Skip to main content

Pagination

List endpoints use zero-indexed pagination.
ParameterDefaultNotes
page0First page is 0.
page_size50Keep values reasonable.
Most list responses include a pagination wrapper:
{
  "pagination": {
    "total_count": 562,
    "total_pages": 12,
    "current_page": 0,
    "next_page": 1,
    "page_size": 50
  }
}
GET /locations/{id}/open_hours is not paginated.

Error response shapes

Three error envelope shapes occur on the API. Branch on the HTTP status code first, then read the matching shape below.

Envelope A - modern

Returned by /check_ins, /users/me/*, /memberships, and /payment_intents/* on 400 validation and 404 resource_not_found errors. Note this envelope is status-agnostic: the same shape appears on both 400 and 404, so branch on the HTTP status, not the envelope.
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_not_found",
    "message": "No active status found for user.",
    "param": null
  }
}

Envelope B - Discovery 401

Returned by /restaurants* and /locations* when the X-API-Key header is missing or invalid.
{
  "status": 401,
  "message": "API key is required. Include your key in the X-API-Key header.",
  "error_code": "MISSING_API_KEY"
}

Envelope C - routing layer 404

Returned when the path does not match a known route, such as typos, deprecated routes, or version-prefix mistakes.
{
  "status": 404,
  "display_message": "Something went wrong. Please try again in a moment.",
  "message": "Endpoint not found.",
  "error": "EndpointNotFoundException",
  "error_code": "internal0007",
  "timestamp": "2026-05-12T00:41:22.919648516Z"
}

401 with empty body

Routes protected by OAuth bearer (/users/me/*, /check_ins*, /memberships, /payment_intents/*) return HTTP 401 with an empty body and a WWW-Authenticate: Bearer header if the bearer is missing or invalid. Do not try to parse JSON on these 401s.

403 insufficient scope

A valid bearer that lacks the scope a member route requires returns HTTP 403 with an empty body and a WWW-Authenticate: Bearer error="insufficient_scope" header. The route exists; the token simply isn’t authorized for it, distinct from the empty-body 401 (missing/invalid token) and from a 404 (route doesn’t exist). See Authentication → OAuth scopes.

Filtering GET /check_ins

GET /check_ins accepts optional filters ([restaurant, location, created_after, created_before]), but a bare GET /check_ins with no filter is valid and returns the full paginated set. (Earlier launch builds required at least one filter and accepted a user filter; both are gone — the feed is anonymized and cannot be filtered by user.)

Timestamp format

created_after and created_before take ISO 8601 strings: 2026-04-01T00:00:00Z. Epoch seconds are rejected with 400: "Parse attempt failed for value [1715468700]".

Unknown query parameters

Unknown query parameters are silently ignored. A wrong filter name, such as ?restaurant_id=... instead of ?restaurant=..., is treated as if the filter was not supplied, so /check_ins returns the unfiltered set rather than an error, and you get more rows than you expected rather than a 400.

Error code reference

CodeMeaning
invalid_request_errorRequest body or parameters are malformed.
invalid_parameterA specific parameter is invalid or missing.
resource_not_foundThe resource does not exist.
payment0030Member has insufficient FLY for Payment Intent confirm.
paymentIntent0003The Payment Intent is not in a state that allows this operation.
MISSING_API_KEYThe X-API-Key header is missing on a Discovery route.
insufficient_scopeThe bearer token lacks the OAuth scope the member route requires (HTTP 403, in the WWW-Authenticate header).
EndpointNotFoundExceptionThe route does not exist. Check the path and version prefix.