pending to brewing, then ready, and finally picked-up. Orders can also be cancelled from pending or brewing states.
Order status lifecycle
| From | To |
|---|---|
pending | brewing, cancelled |
brewing | ready, cancelled |
ready | picked-up |
picked-up | — (terminal) |
cancelled | — (terminal) |
CoffeeOrder schema
All order endpoints return aCoffeeOrder object. Its fields are:
Unique order identifier. Format:
order-N (e.g., order-1, order-42).Name provided by the customer when the order was placed.
The drink ordered. One of:
espresso, americano, latte, cappuccino, cold-brew, tea.Human-readable name of the drink (e.g.,
"Latte").Size of the drink. One of:
small, medium, large.Milk choice. One of:
whole, oat, almond, none.Temperature preference. One of:
hot, iced, extra-hot.Number of espresso shots.
Optional free-text notes from the customer (e.g., allergy information).
Current order status. One of:
pending, brewing, ready, picked-up, cancelled.Final calculated price in US cents, including size multiplier and any extra shot surcharges.
ISO 8601 UTC timestamp of when the order was placed (e.g.,
"2026-04-10T14:30:00Z").POST /orders
Place a new coffee order. The server validates the drink ID, size, milk, and temperature against the menu and returns aCoffeeOrder with status pending.
Request body
Name of the customer placing the order.
ID of the drink to order. Must be one of the IDs returned by
GET /menu: espresso, americano, latte, cappuccino, cold-brew, tea.Desired size. One of:
small, medium, large.Milk preference. One of:
whole, oat, almond, none. Defaults to the drink’s default milk when omitted.Temperature preference. One of:
hot, iced, extra-hot. Defaults to the drink’s first available temperature when omitted.Number of espresso shots. Must not exceed the drink’s
maxShots. Defaults to 1 for espresso-based drinks and 0 for tea.Free-text notes to attach to the order (e.g.,
"extra foam please").Response
Returns aCoffeeOrder object with status: "pending".
Errors
_tag | HTTP status | Description |
|---|---|---|
DrinkNotFoundError | 404 | The drinkId does not match any menu item |
InvalidOrderInputError | 400 | The request body failed validation (e.g., invalid size or milk for that drink) |
InternalAppError | 500 | An unexpected server error occurred |
Example
GET /orders
Returns a list of all orders, optionally filtered by status.Query parameters
Filter results to orders with this status. One of:
pending, brewing, ready, picked-up, cancelled. Omit to return all orders.Response
An array ofCoffeeOrder objects.
Errors
_tag | HTTP status | Description |
|---|---|---|
InvalidOrderInputError | 400 | The status query parameter has an unrecognised value |
InternalAppError | 500 | An unexpected server error occurred |
Examples
List all orders:GET /orders/:orderId
Retrieve a single order by its ID.Path parameters
The order ID to retrieve. Must match the pattern
order-N (e.g., order-1).Response
A singleCoffeeOrder object.
Errors
_tag | HTTP status | Description |
|---|---|---|
OrderNotFoundError | 404 | No order with the given orderId exists |
InternalAppError | 500 | An unexpected server error occurred |
Example
POST /orders/:orderId/start-brewing
Transitions the order frompending to brewing. Call this when a barista picks up the order and begins preparing it.
Path parameters
The ID of the order to start brewing. Must match the pattern
order-N.Response
The updatedCoffeeOrder object with status: "brewing".
Errors
_tag | HTTP status | Description |
|---|---|---|
OrderNotFoundError | 404 | No order with the given orderId exists |
InvalidOrderStatusTransitionError | 409 | The order is not in pending status and cannot be moved to brewing |
InternalAppError | 500 | An unexpected server error occurred |
Example
POST /orders/:orderId/mark-ready
Transitions the order frombrewing to ready. Call this when the drink is prepared and waiting for the customer.
Path parameters
The ID of the order to mark as ready. Must match the pattern
order-N.Response
The updatedCoffeeOrder object with status: "ready".
Errors
_tag | HTTP status | Description |
|---|---|---|
OrderNotFoundError | 404 | No order with the given orderId exists |
InvalidOrderStatusTransitionError | 409 | The order is not in brewing status and cannot be moved to ready |
InternalAppError | 500 | An unexpected server error occurred |
Example
POST /orders/:orderId/pick-up
Transitions the order fromready to picked-up. Call this when the customer collects their drink. This is a terminal state — no further transitions are possible.
Path parameters
The ID of the order being picked up. Must match the pattern
order-N.Response
The updatedCoffeeOrder object with status: "picked-up".
Errors
_tag | HTTP status | Description |
|---|---|---|
OrderNotFoundError | 404 | No order with the given orderId exists |
InvalidOrderStatusTransitionError | 409 | The order is not in ready status and cannot be moved to picked-up |
InternalAppError | 500 | An unexpected server error occurred |
Example
POST /orders/:orderId/cancel
Cancels an order. This is allowed frompending or brewing states. Once an order reaches ready or picked-up, it can no longer be cancelled.
Path parameters
The ID of the order to cancel. Must match the pattern
order-N.Response
The updatedCoffeeOrder object with status: "cancelled".
Errors
_tag | HTTP status | Description |
|---|---|---|
OrderNotFoundError | 404 | No order with the given orderId exists |
InvalidOrderStatusTransitionError | 409 | The order is in a state that does not allow cancellation (e.g., ready or picked-up) |
InternalAppError | 500 | An unexpected server error occurred |