API Documentation

Onagio API v1.2.0

Base URL https://onagio.com/api. GET only. No authentication. The machine readable version of this page is the OpenAPI 3.1 specification.

Endpoints

GET/api

Service index

Name, version, documentation links, and the list of endpoints.

curl https://onagio.com/api

Response

{
  "name": "Onagio API",
  "version": "1.2.0",
  "openapi": "https://onagio.com/openapi.json",
  "endpoints": ["GET /api/health", "GET /api/cheeses", "..."]
}

GET/api/health

Health check

Whether the API is serving, plus two numbers we care about.

curl https://onagio.com/api/health

Response

{ "status": "ok", "agingRoomsOnline": 3, "typewritersWorking": 4 }

GET/api/cheeses

List all cheeses

Optional query parameter minAgeMonths (integer, 0 to 48) filters to wheels aged at least that long.

curl "https://onagio.com/api/cheeses?minAgeMonths=36"

Response

{
  "count": 2,
  "items": [
    {
      "sku": "ONG-LETTERA-36",
      "name": "La Lettera d'Amore",
      "ageMonths": 36,
      "milk": "raw cow",
      "designation": "Parmigiano-Reggiano DOP",
      "wheelWeightKg": 36.9,
      "priceEurPerKg": 48,
      "tastingNotes": ["dried fruit", "broth", "toasted grain"],
      "crystalline": "pronounced",
      "description": "Three years in. The moisture is gone..."
    }
  ]
}

GET/api/cheeses/{sku}

Get one cheese

SKU is case-insensitive on input. Valid values: ONG-QWERTY-24, ONG-LETTERA-36, ONG-MANIFESTO-48.

curl https://onagio.com/api/cheeses/ONG-QWERTY-24

Response

{
  "sku": "ONG-QWERTY-24",
  "name": "Il Classico QWERTY",
  "ageMonths": 24,
  "priceEurPerKg": 34,
  "crystalline": "light"
}

GET/api/cheeses/{sku}/availability

Stock and lead time

status is one of in_stock, low, or allocated. Cached for 60 seconds.

curl https://onagio.com/api/cheeses/ONG-MANIFESTO-48/availability

Response

{
  "sku": "ONG-MANIFESTO-48",
  "wheelsAvailable": 0,
  "leadTimeDays": 240,
  "status": "allocated"
}

GET/api/cheeses/{sku}/pairings

Pairings for a cheese

kind is one of wine, food, or use.

curl https://onagio.com/api/cheeses/ONG-MANIFESTO-48/pairings

Response

{
  "sku": "ONG-MANIFESTO-48",
  "count": 2,
  "items": [
    { "with": "Vin Santo", "kind": "wine", "note": "Sweetness is the only thing that survives it." },
    { "with": "nothing", "kind": "use", "note": "Eat it on its own, standing up, in the kitchen." }
  ]
}

GET/api/typewriters

The typewriter collection

Optional query parameter working (true or false).

curl "https://onagio.com/api/typewriters?working=true"

Response

{
  "count": 4,
  "items": [
    {
      "id": "oli-valentine-1969",
      "model": "Olivetti Valentine",
      "year": 1969,
      "working": true,
      "location": "museum",
      "note": "Red. Everyone photographs it."
    }
  ]
}

GET/api/tours

Factory tour schedule

Recurring weekly schedule. Tours are booked by email, not through the API.

curl https://onagio.com/api/tours

Response

{
  "timezone": "Europe/Rome",
  "bookingEmail": "o@onagio.com",
  "noticeDays": 3,
  "durationMinutes": 60,
  "schedule": [{ "day": "tuesday", "times": ["11:00", "15:00"], "capacity": 10 }]
}

Errors

Every error is JSON with the same shape. Match on error.code, which is stable. Do not match on error.message, which is prose and may be reworded.

{
  "error": {
    "code": "cheese_not_found",
    "message": "No wheel with SKU \"ONG-GOUDA-12\".",
    "resolution": "We make three. Call GET /api/cheeses to list them.",
    "documentation": "https://onagio.com/docs"
  }
}

Codes

  • invalid_parameter — 400. A query parameter was the wrong type or out of range.
  • cheese_not_found — 404. No wheel with that SKU.
  • sub_resource_not_found — 404. The SKU exists, the sub-resource does not.
  • endpoint_not_found — 404. No such endpoint.
  • method_not_allowed — 405. You used something other than GET.

Caching

Catalogue endpoints send Cache-Control: public, max-age=300. Availability sends max-age=60. There is no rate limit, and honouring those headers is how it stays that way.