Skip to content
Help

Conventions

Pagination, errors, rate limits, money, and dates — the rules every endpoint follows.

Public API2 min read

#Pagination

Every list endpoint takes page and limit, and returns a pagination object.

bash
curl "https://api.tryrestro.com/v1/orders?page=2&limit=50" \
  -H "Authorization: Bearer $RESTRO_API_KEY"
json
{
  "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.

json
{ "error": "Order not found", "code": "not_found" }
StatusCodeMeaning
400invalid_requestMalformed request or a value the endpoint will not accept
401unauthorizedMissing or invalid key
401key_inactiveThe key is revoked or expired
403forbiddenThe key lacks the scope, or the branch is outside its scope
404not_foundNo such resource, or not visible to this key
409conflictThe resource is in a state that forbids this change
429rate_limitedToo many requests
500Something 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:

http
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1785312000

X-RateLimit-Reset is a Unix timestamp in seconds. Exceeding the limit returns 429 with a Retry-After header in seconds:

json
{ "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/status is idempotent — setting an order to the status it already has returns the order unchanged rather than erroring.
  • PATCH /menu/items/:itemId is idempotent — the same body applied twice leaves the same state.
  • POST /inventory/items/:itemId/transactions is 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