Before you start slinging API calls, it helps to understand how the Cheese Store models the world. Spoiler: everything revolves around cheese.
Every cheese in our catalog is represented as a rich object with everything you'd want to know (and some things you didn't know you wanted to know).
{
"id": "epoisses-de-bourgogne",
"name": "Époisses de Bourgogne",
"origin": {
"country": "France",
"region": "Burgundy",
"producer": "Fromagerie Berthaut"
},
"milk": "cow",
"pasteurized": false,
"texture": "soft",
"rind": "washed",
"aged_weeks": 6,
"tasting_notes": "Pungent, complex, barnyard funk. Banned from public transport in France. Genuinely.",
"stinkiness_rating": 9,
"serving_temp_celsius": { "min": 16, "max": 18 },
"pairings": ["Gewürztraminer", "crusty bread", "an open window"],
"seasonal": false,
"price_per_kg": 38.00,
"in_stock": true,
"stock_quantity_kg": 12.5
}We classify textures as soft, semi-soft, semi-hard, hard, or blue. Yes, "blue" is a texture. We had a long argument about this with the fromagers. They won. A cheese like Stilton has a crumbly texture but the blue mould classification takes precedence. We don't make the rules (the fromagers do).
Rated 1-10 by our panel of trained noses. A 1 is a mild fresh mozzarella. A 10 is a Vieux-Boulogne that will set off smoke alarms. This field was the single most debated design decision in our API. We considered making it a float but decided that arguing about whether Limburger is a 7.3 or 7.4 was not a productive use of engineering time.
Some cheeses are only available during certain months. Vacherin Mont d'Or, for instance, is only made between September and March. The seasonal boolean tells you if a cheese has restricted availability, and available_months gives you the specific window. Set up webhooks to get notified when seasonal favourites come back.
Every cheese includes an array of suggested pairings, covering wines, accompaniments, and occasionally, warnings. These are curated by our sommeliers and fromagers, not generated by AI. We tried AI-generated pairings once. It suggested pairing Roquefort with Mountain Dew. We shut that project down immediately.
An order represents a customer's cheese purchase, from placement through delivery.
Placed
Customer submits an order via POST /v2/orders. Payment is authorized but not captured. The cheese is reserved in inventory. The warehouse team is alerted. Excitement builds.
Confirmed
Payment is captured and the order is confirmed. A webhook fires (order.confirmed). The cheese is pulled from temperature-controlled storage and inspected for quality. Any cheese that doesn't meet standards is eaten by the quality team (a coveted role).
Shipped
The order is packed in insulated packaging with gel ice packs and handed to the courier. Tracking information becomes available via GET /v2/orders/{id}/tracking. Temperature sensors in the packaging feed real-time data back to the API.
Delivered
The courier confirms delivery. A webhook fires (order.delivered). The customer now has cheese. Everything that follows is between them and the cheese.
| Method | Speed | Temperature | Use case |
|---|---|---|---|
standard | 3-5 days | Ambient | Hard cheeses in cool weather |
temperature_controlled | 1-2 days | 4-8°C | Soft cheeses, warm climates |
express_chilled | Next day | 2-4°C | When you need Brie and you need it now |
Customer objects represent end users of your application. Each customer can have:
All list endpoints use cursor-based pagination. We chose cursors over page numbers because cheese catalogs change frequently (seasonal items, sold-out items, new arrivals) and offset-based pagination falls apart when the underlying data shifts.
# First page
GET /v2/cheeses?limit=20
# Next page (use nextCursor from the previous response)
GET /v2/cheeses?limit=20&cursor=eyJpZCI6MjB9The nextCursor is an opaque string. Don't try to decode it. We know it's Base64. We know you can decode it. Please don't build logic around the internal structure; we reserve the right to change it to ROT13 out of spite.