ReferenceHTTP API
Error codes
Every error the API returns, its status, meaning, and the fix.
Errors always use the same envelope:
{
"error": {
"code": "validation_error",
"message": "The request contains invalid fields.",
"details": {}
},
"requestId": "01J..."
}details is present only when the error carries structured information — most
often a flattened validation result naming the offending fields.
Authentication and authorization
| Status | Code | Meaning and fix |
|---|---|---|
401 | unauthorized | No credential, an unrecognised one, or a revoked key. Send Authorization: Bearer wor_…. |
403 | insufficient_scope | Valid key, missing scope. Scopes are fixed at creation — issue a new key. |
403 | session_required | The endpoint is session-only: API keys, organizations, projects. |
403 | organization_forbidden | You are not owner or admin in that organization, so you cannot create a project in it. |
403 | billing_owner_required | Only the workspace's organization owner can change billing. |
403 | untrusted_origin | A browser mutation did not come from the configured UI_ORIGIN. |
Validation
| Status | Code | Meaning and fix |
|---|---|---|
400 | validation_error | A field failed schema validation. details names the fields. |
400 | invalid_model | The model identifier is not in the current directory. Pick a listed model. |
400 | invalid_schedule | The cron expression is not five fields, or cannot produce a future occurrence. |
400 | invalid_name | The name contains no letters or digits, so no slug can be derived. |
400 | tool_policy_requires_connection | Tool policies must reference a saved connection; they cannot be created inline with a routine. |
400 | missing_variables | The instructions reference a {{key}} with no value. details.variables names the keys. |
400 | invalid_workflow | A stage breaks a workflow rule or names a tool the routine may not use, including when a connections change would take that tool away. details.errors names the stage. |
413 | body_too_large | /v1 bodies are capped at 1 MB. |
Not found
| Status | Code | Meaning |
|---|---|---|
404 | routine_not_found | No routine with that id in this project. |
404 | run_not_found | No run with that id in this project. |
404 | connection_not_found | No connection with that id in this project. |
404 | tool_policy_not_found | No such policy, or it belongs to a different routine. |
404 | api_key_not_found | No such key in this project, or it is already revoked. |
404 | not_found | No route matched. |
404 rather than 403 across projects
A resource that exists in another project returns 404. The API does not
confirm the existence of something the credential cannot see.
Conflicts
| Status | Code | Meaning and fix |
|---|---|---|
409 | successful_run_required | Run this routine successfully once before activating its schedule. |
409 | routine_archived | Archived routines cannot run. Unarchive or recreate. |
409 | automatic_tool_confirmation_required | Send confirmAutomaticExecution: true alongside automaticExecution: true. |
409 | billing_contact_required | A Business or exceptional account must be handled through support. |
409 | billing_customer_required | Stripe customer/subscription provisioning is not ready; retry or contact support. |
409 | provider_not_configured | The deployment has no OAuth client for that provider. An operator must set it. |
409 | oauth_client_unavailable | The provider offers no dynamic client registration and no client is configured. |
Billing and plan access
| Status | Code | Meaning and fix |
|---|---|---|
402 | plan_limit_reached | A specific allowance is exhausted. Read details.limit/current/maximum/plan; preserve work and upgrade. |
402 | billing_action_required | A post-grace payment state blocks new paid work. The owner should update billing through Stripe. |
Neither error means saved configuration was deleted. See Billing for reset periods, failed-payment grace, and downgrade behavior.
Rate limiting
| Status | Code | Meaning and fix |
|---|---|---|
429 | rate_limit_exceeded | Per-credential window exceeded. Honour Retry-After; details.retryAfterSeconds repeats it. |
Upstream and service
| Status | Code | Meaning and fix |
|---|---|---|
502 | model_directory_unavailable | LLMGateway's directory could not be read. Retry. |
502 | mcp_discovery_failed | The MCP server was unreachable or returned invalid tools. Check the URL and headers. |
503 | scheduler_unavailable | /internal/scheduler/tick was called on a deployment with no scheduler configured. |
503 | billing_unavailable | Stripe billing is disabled or not completely wired in this environment. |
503 | billing_checkout_unavailable | New Checkout is disabled; existing status, portal, and webhooks remain available. |
503 | lead_intake_unavailable | The runtime cannot derive a trusted rate-limit identity for the public Business form. |
500 | internal_error | Unexpected failure. Quote the requestId. |
Run error categories are different
The codes above describe API requests. A run that fails carries an
error.category instead — tool_denied, idle_timeout, gateway_timeout,
and so on. See Run states and error categories.