Errors
The API uses conventional HTTP status codes and returns a structured error envelope on every failure, so you can branch on machine-readable fields rather than parsing prose.
Error envelope
Section titled “Error envelope”{ "error": { "type": "invalid_request_error", "code": "bad_request", "message": "limit must be a positive integer.", "param": "limit", "doc_url": "https://docs.useservice.app/api/errors#bad_request" }}| Field | Description |
|---|---|
type | Broad category of the error (see below). Always present. |
code | A specific, stable machine code for the failure. Always present. |
message | A human-readable explanation. For logging/debugging — do not show it directly to end users, and do not match on it. |
param | The offending request parameter — present only when a specific parameter caused the error (for example a bad limit, status, or expand value). Omitted otherwise (it is not sent as null). |
doc_url | A deep link to the reference entry for this code (https://docs.useservice.app/api/errors#<code>). Always present. |
Every response — successes and errors alike — also echoes the
Service-Version header that served it.
Error types
Section titled “Error types”type | Meaning |
|---|---|
invalid_request_error | The request was malformed — a bad parameter, value, or filter. |
authentication_error | The API key is missing, malformed, or not valid. |
rate_limit_error | You have exceeded the rate limit. |
api_error | An unexpected error on our side. Safe to retry with backoff. |
Error code catalog
Section titled “Error code catalog”Every code the API can return, with its type, HTTP status, and when it
occurs. Branch on code for precise handling; fall back to type for broad
categories. The doc_url on every error links straight to its entry below
(https://docs.useservice.app/api/errors#<code>).
code | type | HTTP | When it occurs |
|---|---|---|---|
auth_header_missing | authentication_error | 401 | No Authorization: Bearer … header was sent. |
invalid_token | authentication_error | 401 | The API key is invalid, revoked, expired, or unknown. |
bad_request | invalid_request_error | 400 | A query parameter, filter, cursor, expand, or Service-Version value is malformed. The offending input is named in param. |
not_found | invalid_request_error | 404 | The resource does not exist for this key’s restaurant (see below). |
rate_limited | rate_limit_error | 429 | You exceeded the rate limit. Honour Retry-After. |
internal_error | api_error | 500 | An unexpected error on our side. Safe to retry with backoff. |
auth_header_missing
Section titled “auth_header_missing”authentication_error · 401 Unauthorized. No Authorization: Bearer … header
was sent. Add the header — see Authentication.
invalid_token
Section titled “invalid_token”authentication_error · 401 Unauthorized. A key was supplied but is invalid,
revoked, expired, or unknown.
Provision a new key if yours no
longer works.
bad_request
Section titled “bad_request”invalid_request_error · 400 Bad Request. A query parameter, filter,
pagination cursor, expand, or Service-Version value is malformed. The
offending input is named in param. Fix the request — retrying it unchanged
will fail the same way.
not_found
Section titled “not_found”invalid_request_error · 404 Not Found. The resource does not exist for this
key’s restaurant. See
404, not 403, across restaurants.
rate_limited
Section titled “rate_limited”rate_limit_error · 429 Too Many Requests. You exceeded the rate limit. Wait
for the Retry-After interval, then retry — see
Rate limits.
internal_error
Section titled “internal_error”api_error · 500. An unexpected error on our side. Safe to retry with
exponential backoff; contact support if it persists.
HTTP status codes
Section titled “HTTP status codes”| Status | Meaning |
|---|---|
200 OK | The request succeeded. |
304 Not Modified | Returned on a conditional GET when your If-None-Match matches. See Expanding objects for caching. |
400 Bad Request | A malformed request — a bad parameter or value. Check param. |
401 Unauthorized | Missing or invalid API key. See Authentication. |
404 Not Found | The resource does not exist for this key’s restaurant. |
429 Too Many Requests | Rate limited. See Rate limits. |
500 / 503 | Something went wrong on our side. Retry with exponential backoff. |
404, not 403, across restaurants
Section titled “404, not 403, across restaurants”If you request a resource that exists but belongs to another restaurant, the
API returns 404 Not Found, not 403 Forbidden. From your key’s point of
view the resource simply does not exist. This avoids leaking the existence of
other restaurants’ data. A valid id you “expect” to work but that returns 404
almost always means it belongs to a different restaurant (or a different key).
Handling errors
Section titled “Handling errors”- Branch on
typeandcode, never onmessage. - Retry only
429(afterRetry-After) and5xx(with exponential backoff). - Never retry
400/401/404— they will fail again until you change the request or the key.