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: "52.41", not 52.41. Binary floating point cannot represent most decimal fractions exactly, and arithmetic on them drifts. Parse the strings into the 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 failing on them.

#Errors

Errors return a JSON body with a human-readable error and a machine-readable 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
500An unexpected error on Restro's 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 have already fetched rather than splitting it across several keys.

#Idempotency

Read endpoints are 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.
  • 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 retry it on a timeout without checking; fetch the item and confirm 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