Skip to content
Endless Documentation

API errors and rate limits

The JSON shape every Endless REST API failure returns, the data.code field to branch on, and the RateLimit headers for 1,000 requests a minute.

Every failure from the Endless REST API at https://api.endless.app returns JSON in one shape, and every response reports your remaining request budget. Versioning has its own page.

The error shape

{
  "code": "FORBIDDEN",
  "status": 403,
  "message": "Your role does not have permission to do this",
  "data": { "code": "permission_denied" }
}
FieldWhat it is
codeThe HTTP status as a word: BAD_REQUEST, UNAUTHORIZED, NOT_FOUND, …
statusThe HTTP status as a number
messageA sentence for a person. It may be reworded, so don't match on it
data.codeThe machine-readable reason, in snake_case. This is the field to branch on
data.hintWhen present, the step that resolves it
data.documentationWhen present, a link to the API reference

The Error schema in the OpenAPI document lists every data.code, and each operation in the API reference lists its statuses.

Common codes

Statusdata.codeWhat to do
400(validation)message names the field and the rule it broke
400unsupported_api_versionSee API versioning
401missing_tokenSend Authorization: Bearer <token>
401invalid_tokenThe token didn't verify or expired. Get a new one
402insufficient_credits, exceeds_spending_limitThe workspace or the caller can't pay for this call
403permission_denied, forbiddenThe caller's role or access doesn't allow it
404not_found, organization_not_found, …The resource doesn't exist, or the caller can't open it
404route_not_foundNo operation matches the path (never an HTML page)
404invalid_path_parameterAn id in the path can't name a resource
429rate_limitedWait the seconds in retry_after, then retry

Rate limits

  • Limit: 1,000 requests per 60 seconds per caller, in a policy named default. One counter per caller across all servers.
  • Fixed window: it resets all at once, so pace by RateLimit-Remaining, not by an assumed even rate.
  • Credits are separate: running out of balance or spending limit returns 402, not 429.

Every API response, success or failure, carries the counter in two spellings (browsers can read them too):

RateLimit-Policy: "default";q=1000;w=60
RateLimit: "default";r=997;t=42
RateLimit-Limit: 1000
RateLimit-Remaining: 997
RateLimit-Reset: 42

r / RateLimit-Remaining are requests left; t / RateLimit-Reset are seconds until reset. Over the limit, the API returns 429 with a Retry-After header and the same seconds in the body:

{
  "code": "TOO_MANY_REQUESTS",
  "status": 429,
  "message": "Too many requests.",
  "data": {
    "code": "rate_limited",
    "hint": "Wait 42s, then retry. Every response carries RateLimit headers — read them to pace yourself before you are refused.",
    "documentation": "https://endless.app/docs/api"
  },
  "retry_after": 42
}

Machine-readable sources

  • API index: its rate_limit and errors objects state this policy.
  • OpenAPI document: the Error schema on every failure response.
  • The MCP server has its own limit: 60 tool calls per minute per account.

On this page