Conventions
Pagination, errors, rate limits, money, and dates — the rules every endpoint follows.
#Pagination
Every list endpoint takes page and limit, and returns a pagination object.
curl "https://api.tryrestro.com/v1/orders?page=2&limit=50" \
-H "Authorization: Bearer $RESTRO_API_KEY"{
"data": [],
"pagination": {
"page": 2,
"limit": 50,
"total": 132,
"totalPages": 3,
"hasMore": true
}
}limit defaults to 25 and is capped at 100. Values outside the range are clamped rather than rejected, so a request never fails over a paging parameter.
#Money
All monetary values are decimal strings, not numbers: "184.00", not 184. This is deliberate — binary floats cannot represent 0.1 exactly and money arithmetic on them drifts. Parse them into whatever decimal type your language offers.
Currency is per branch. Orders carry a currency field taken from their branch; a restaurant with branches in two countries returns two currencies from the same endpoint.
#Dates
All timestamps are ISO 8601 in UTC: 2026-07-28T10:30:00.000Z. Date filters accept anything Date.parse understands, and an unparseable date is ignored rather than rejected.
#Enums
Enum values are lowercase with underscores: dine_in, sold_out, mobile_app. New values may be added to any enum without a major version change, so treat unknown values as opaque strings rather than crashing on them.
#Errors
Errors return a JSON body with a human error and a machine code.
{ "error": "Order not found", "code": "not_found" }| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed request or a value the endpoint will not accept |
| 401 | unauthorized | Missing or invalid key |
| 401 | key_inactive | The key is revoked or expired |
| 403 | forbidden | The key lacks the scope, or the branch is outside its scope |
| 404 | not_found | No such resource, or not visible to this key |
| 409 | conflict | The resource is in a state that forbids this change |
| 429 | rate_limited | Too many requests |
| 500 | — | Something broke on our side |
Request bodies are schema-validated. A body that fails validation returns 400 with the offending fields named.
#Rate limits
Every key is limited to 120 requests per minute. Each response carries the current state:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1785312000X-RateLimit-Reset is a Unix timestamp in seconds. Exceeding the limit returns 429 with a Retry-After header in seconds:
{ "error": "Rate limit exceeded", "code": "rate_limited" }Back off and retry after the interval. If you are consistently at the ceiling, spread the work over time or cache what you already fetched rather than splitting it across several keys.
#Idempotency
Read endpoints are naturally safe to repeat. Of the write endpoints:
POST /orders/:reference/statusis idempotent — setting an order to the status it already has returns the order unchanged rather than erroring.PATCH /menu/items/:itemIdis idempotent — the same body applied twice leaves the same state.POST /inventory/items/:itemId/transactionsis not idempotent. Each call records a movement. Do not blindly retry it on a timeout; fetch the item and check the balance first.
#Versioning
The path carries the version: /v1. Additive changes — new fields, new endpoints, new enum values — happen within v1. Anything that would break a well-behaved client gets a new version, and v1 keeps working.
Did this page miss something? Tell us.
Back to top