Error catalog
Every error, and what unblocks it
All errors are structured JSON with error, message, and context; the message states the fix. Markdown twin: /errors.md.
| code | HTTP | unblock |
|---|---|---|
| PAYMENT_REQUIRED | 402 | Balance too low. Relay human_readable to the user verbatim; retry the SAME call after top-up (or enable auto-refill at the enable_url). |
| UNAUTHORIZED | 401 | Missing/invalid bearer. Get a token via POST /v1/signup; send it as Authorization: Bearer <token>. |
| AGENT_KILLED | 403 | The operator killed this agent token. Only the operator can revive it (/revive in the operator Telegram). |
| AGENT_REVOKED | 403 | Token permanently revoked. Ask the account operator for a new agent token. |
| POLICY_DENIED | 403 | An agent-initiated top-up (POST /v1/topup) was refused: the agent's monthly cap is used up, so the top-up could not be spent. Raise the cap first. |
| ADAPTER_DENIED | 403 | The account operator denylisted this capability. The body names the scope (account or agent); pick another capability, or ask the operator to remove it from the denylist. |
| ADAPTER_NOT_ALLOWED | 403 | This agent may only call allowlisted capabilities. Ask the account operator to add it (PUT /v1/policies or PUT /v1/agents/{id}/policies). |
| PER_CALL_CAP_EXCEEDED | 429 | This call costs more than max_per_call_credits allows. Retrying will not help: use a cheaper call, or ask the operator to raise the cap. |
| DAILY_CAP_REACHED | 429 | A daily spend cap is hit; it resets at 00:00 HKT. With unblock and scope in the body, it is a policy cap the operator can raise (daily_cap_credits, PUT /v1/policies). Without them, it is the fixed account safety cap, which only resets. |
| MONTHLY_CAP_REACHED | 429 | The agent or account monthly spend cap is hit. Wait for the reset, or ask the operator to raise monthly_cap_credits. |
| RATE_LIMITED | 429 | Too many requests (60/min per token; 10/min unauthenticated per IP). Back off and retry in a minute. |
| UNKNOWN_API | 404 | No such slug (400 on /v1/keys and /v1/keys/link). Discover slugs with GET /v1/search?q=. Catalog tools run through their proxy_route, not /v1/call. |
| API_PAUSED | 503 | This capability is temporarily paused (spend alarm or provider issue). Check GET /status; try another slug. |
| API_UNAVAILABLE | 503 | The capability is not configured on this deployment. Check /capabilities for what is live. |
| BYOK_REQUIRED | 403 | This slug needs YOUR provider key. Ask for a one-time vault link (get_vault_link / POST /v1/keys/link) — never paste keys into chat. (403, not 402: 402 always means "top up and retry"; this needs a key, not money.) |
| VAULT_KEY_MISSING | 403 | No vaulted key for this provider on this account. Same fix: one-time vault link. |
| DUPLICATE_CALL | 409 | This x-idempotency-key was already used on this account, so the retry charged nothing. The body names the original call (call_id, slug, status, credits, ts). Response bodies are never stored, so the first response cannot be replayed — check GET /v1/history for what it did, or send a NEW key for a fresh call. |
| KEY_UNREADABLE | 409 | The vaulted key could not be decrypted (e.g. after a vault-secret rotation). Re-vault it via a fresh one-time link; contact support if it repeats. |
| ADAPTER_MISCONFIGURED | 503 | The capability is temporarily unpriced/misconfigured on our side — not your fault; retry later or pick another slug from /v1/search. |
| LINK_INVALID | 400 | Vault link malformed/expired (10-minute TTL). Request a new one. Token-recovery links return it too. |
| LINK_USED | 409 | Vault links are single-use. Request a new one. Token-recovery links return it too. |
| PROVIDER_ERROR | 502 | The upstream provider failed. Your debit is refunded automatically — the body carries machine-readable refunded:true + refund_credits; retry, or check /status for a cluster. |
| RESPONSE_TOO_LARGE | 502 | Upstream response exceeded the proxy cap (default 2MB). Narrow the request. |
| PROXY_RESPONSE_TOO_LARGE | 502 | A proxy response exceeded the size cap (default 2MB). Your credits are refunded; narrow the request. |
| PROXY_UPSTREAM_UNREACHABLE | 502 | The provider could not be reached (network error or timeout). Your credits are refunded; retry, or check /status. |
| PROXY_UNKNOWN_PROVIDER | 404 | No such proxy provider. The 404 body lists the valid names in providers. |
| PROXY_BAD_PATH | 400 | The proxy path failed safety checks (no .., no absolute URLs). |
| REQUEST_CAP_REACHED | 429 | Daily request cap for an unpriced route. Resets 00:00 HKT. |
| CONSENT_REQUIRED | 400 | Auto-refill needs the saved-card consent flow first: open the enable_url (/mandate?ref=...). |
| BALANCE_CAP | 409 | The top-up would exceed the account balance cap ($100 default). Spend down first; over-cap Stripe payments park for review. |
| EMAIL_EXISTS | 409 | Account exists. Use the existing token — or if it was LOST, POST /v1/token/recover {"email":...}: a one-time re-key link is emailed to the account address (rotate requires the old token and cannot recover a lost one). |
| SIGNUPS_PAUSED | 503 | Trial-abuse alarm paused signups. Try again later. |
| MGMT_ACTION_DENIED | 403 | The credential broker blocks destructive, billing and member routes on the owner's vendor management APIs. Use a read or routine call instead. |
| UNKNOWN_VENDOR | 404 | No such management vendor for the credential broker. The message lists the supported vendors. |
| EMAIL_MISMATCH | 403 | Token recovery needs the account email typed exactly as registered. Nothing changed and the link is still valid; try again. |
| NOT_CONFIGURED | 503 | This deployment lacks a required secret for the feature. The operator has been signaled. |
| CONFLICT | 409 | The resource is already in the requested state (e.g. proposal already decided, refill already this period). |
| FORBIDDEN | 403 | Founder/operator-only surface. |
| BAD_REQUEST | 400 | The body/params are malformed; the message names the exact field shape expected. |
| NOT_FOUND | 404 | No such resource, or not yours (tickets and mandates are account-private). |