Skip to navigation

API error reference

This page lists the error response formats, status codes, and error codes that the Runtype API returns. For steps that fix each error, see Common errors and solutions and Rate limits and usage.

Error response body

An error response is a JSON object with an error string. Most responses add more fields. The following table lists the fields that can appear:

FieldTypeDescription
errorstringA short description of the error. Present on every error response.
messagestringA longer, human-readable explanation.
codestringA stable, machine-readable error code. Branch on code, not on the error or message text.
detailsarrayField-level problems in a request that failed validation.
limitTypestringThe kind of limit that refused the request. Present on burst-rate, spend-cap, and Test key limit errors.
resetsAtstringAn ISO 8601 timestamp. Present on RATE_LIMIT_EXCEEDED and SPEND_LIMIT_EXCEEDED responses.
upgradeUrlstringThe dashboard path where you can change the setting that caused the error, such as /settings/billing.
statsobjectUsage figures for the limit that refused the request.

The following example shows a 404 response for a path that doesn’t exist:

404 response
{
"error": "Not Found",
"message": "The requested resource was not found",
"timestamp": "2026-09-27T14:03:11.482Z"
}

A request for a specific resource that doesn’t exist, such as an unknown Flow ID, also returns 404. Its error string names the resource.

Every API response includes an X-Runtype-Request-ID header. Include its value when you contact support about an error.

Validation errors

When a request body, query parameter, or path parameter fails schema validation, the API returns 400 before it runs the request. The details array has one entry for each problem:

400 response
{
"error": "Validation error",
"details": [
{
"code": "MISSING_REQUIRED_FIELD",
"message": "Invalid input: expected string, received undefined",
"path": "name"
}
]
}

Each entry has these fields:

  • code: the detail code.
  • message: a description of the problem.
  • path: the dotted path to the field, such as steps.0.config. The path is an empty string for the request root.
  • suggestion: optional. A hint such as the allowed values, the accepted range, or the fields to remove.

The details array lists at most 100 problems. When a request has more, the last entry has the code VALIDATION_ERROR and reports how many problems it omitted.

The following table lists the detail codes:

Detail codeMeaning
MISSING_REQUIRED_FIELDA required field is missing.
INVALID_TYPEA field has the wrong type.
INVALID_ENUMA field has a value outside its allowed set.
OUT_OF_RANGEA number, string, or array is too large or too small.
INVALID_FORMATA string doesn’t match its format, such as an email or URL.
UNRECOGNIZED_KEYSThe object contains fields that the endpoint doesn’t accept.
INVALID_UNIONThe value matches none of the accepted shapes.
CUSTOM_VALIDATIONThe value fails an endpoint-specific rule.
VALIDATION_ERRORAny other validation problem.

Status codes

The following table lists the status codes that the API returns for errors and the codes that each one can carry:

StatusMeaningCodes
400The request is malformed or fails validation.Validation detail codes in details, or an endpoint-specific code
401The credential is missing, invalid, expired, or revoked.None
402A spending control blocked the request.SPEND_LIMIT_EXCEEDED, PLATFORM_KEY_SPEND_EXCEEDED, DAILY_EVAL_LIMIT
403The credential lacks a permission or can’t do the operation.TEST_KEY_PERMISSION_DENIED, or none with an error that names the missing permission
404The path or resource doesn’t exist.None
429The request exceeded a rate or Test key limit.RATE_LIMIT_EXCEEDED, RATE_LIMITED, TEST_KEY_DAILY_LIMIT_EXCEEDED, TEST_KEY_LIFETIME_LIMIT_EXCEEDED
500An unexpected server error occurred.None. The body is {"error": "Internal Server Error", "message": "Something went wrong"}.
503A limit blocked an end-user request, or Runtype couldn’t verify a credential for a short time.SERVICE_UNAVAILABLE, or none for credential verification

A 429 from a rate limit and a 503 from credential verification include a Retry-After header with the number of seconds to wait.

Limit error codes

The following table lists the codes that the API returns when a limit refuses a request:

CodeStatuslimitTypeCause
RATE_LIMIT_EXCEEDED429rateYou started more executions in a 10-second window than your plan’s burst rate allows.
SPEND_LIMIT_EXCEEDED402spendYour month-to-date spend reached your monthly spend cap.
TEST_KEY_DAILY_LIMIT_EXCEEDED429dailyA Test API key or a test surface key reached its daily execution limit.
TEST_KEY_LIFETIME_LIMIT_EXCEEDED429lifetimeA Test API key reached its lifetime execution limit. This limit doesn’t reset.
RATE_LIMITED429NoneA surface key exceeded its per-minute or per-day request limit.
PLATFORM_KEY_SPEND_EXCEEDED402NonePlatform-key credit is unavailable, so model calls and tools that use platform keys stop.
DAILY_EVAL_LIMIT402NoneYou reached your plan’s daily limit on eval submissions. The count resets at midnight UTC.
SERVICE_UNAVAILABLE503NoneAn end user of your chat widget, client token, or surface reached one of the preceding limits.

Runtype doesn’t cap the number of executions that you run. The API doesn’t return DAILY_EXECUTION_LIMIT_EXCEEDED or MONTHLY_EXECUTION_LIMIT_EXCEEDED.

Limit response fields

A RATE_LIMIT_EXCEEDED or SPEND_LIMIT_EXCEEDED response has this shape:

402 response (abridged)
{
"error": "Limit Exceeded",
"message": "You've reached your monthly spend cap. Raise or clear it in billing settings to continue, or wait for the cap to reset at the start of next month.",
"code": "SPEND_LIMIT_EXCEEDED",
"limitType": "spend",
"upgradeUrl": "/settings/billing",
"resetsAt": "2026-10-01T00:00:00.000Z",
"stats": {
"tier": "startup",
"periodType": "monthly",
"spendLimitEnabled": true,
"spendLimitCents": 5000,
"atSpendLimit": true
}
}

The value of resetsAt depends on the code:

  • For SPEND_LIMIT_EXCEEDED, resetsAt is the start of the next month (UTC), when the spend cap resets.
  • For RATE_LIMIT_EXCEEDED, resetsAt is the next midnight UTC. It isn’t the time to retry. Wait for the number of seconds in the Retry-After header instead.

The Test key codes use a different body. It has limitType set to daily or lifetime, a resetTime for the daily limit, an upgradeMessage, and stats with the remaining and limits counts.

A PLATFORM_KEY_SPEND_EXCEEDED response includes a blockReason field with one of these values:

  • credit_exhausted: your credit ran out and no automatic top-up replenished it.
  • trial_expired: your free trial ended with no payment method on file.
  • auto_topup_failed: an automatic top-up payment failed.

A RATE_LIMITED response includes a retryAfter field and a Retry-After header.

Errors in streaming responses

When you request a stream, some errors arrive as events instead of an HTTP error status.

When a rate or spend limit refuses a streaming request before the run starts, the response has status 200. The stream contains one execution_error event:

Refused streaming request (abridged)
event: execution_error
data: {"type":"execution_error","kind":"flow","error":{"code":"SPEND_LIMIT_EXCEEDED","message":"You've reached your monthly spend cap. Raise or clear it in billing settings to continue, or wait for the cap to reset at the start of next month."},"code":"SPEND_LIMIT_EXCEEDED","upgradeUrl":"/settings/billing"}

The execution_error event has these fields:

  • kind: flow or agent.
  • error: an object with code and message, or a string.
  • code: the error code, when the error has one.
  • upgradeUrl: the dashboard path for billing errors.
  • blockReason: present for PLATFORM_KEY_SPEND_EXCEEDED.

A Test key limit returns a JSON 429 response, not an event, even when you request a stream.

After a run starts, errors arrive in these events:

  • When a step fails, a step_complete event has success set to false and the message in error.
  • When the run stops because of an error, the stream ends with an execution_error event. If platform-key credit runs out during the run, the event has the code PLATFORM_KEY_SPEND_EXCEEDED.
  • When an Agent error is recoverable, the stream sends an error event with recoverable set to true, and the run continues.

For a non-streaming request, a failed run returns success set to false, with error and code fields that describe the failure. For all event types and fields, see the API reference.

Errors for end users

Requests from a chat widget, a client token, a surface key, or a public surface don’t show billing details. When one of these requests reaches a rate limit, spend cap, or platform-key credit limit, the API returns 503 with this body:

503 response for end users
{
"error": "Service Unavailable",
"message": "This assistant is temporarily unavailable. Please try again later.",
"code": "SERVICE_UNAVAILABLE"
}

A streaming request from an end user gets an execution_error event with the same code and message.

Next steps