Skip to main content

Error Reference

Every error code the CodeSpar API can return, with HTTP status, the response shape, when it fires, and the fix. Aggregated across sessions, projects, connections, triggers, wallets, and auth surfaces.

5 min read
View MarkdownEdit on GitHub

Error Reference

The error envelope

Most /v1 endpoints return errors in a nested envelope:

{
  "error": {
    "code": "invalid_body",
    "message": "request body did not match the expected schema",
    "details": { "issues": [] }
  },
  "request_id": "req_a1b2c3d4"
}
  • error.code is a stable machine-readable string. Safe to branch on in your code.
  • error.message is a human-readable explanation. Surface to users with caution.
  • error.details is optional and per-error. Validation errors put the schema issues here.
  • request_id matches the X-Request-Id response header. Include it in support tickets.

The HTTP status is on the response itself, not in the body. Branch on error.code, not on the message text.

Exceptions to the envelope

A few surfaces return a different shape. Detect them by checking whether error is a string or an object:

SurfaceStatusShape
Missing, malformed, or revoked API key401Bare: {"error": "unauthorized"}. No message, no request_id.
Key lacks a required scope403Flat: {"error": "forbidden", "message": "...", "status": 403}
Policy denial (including budget rules)403Flat: {"reason": "budget_exceeded", "ruleType": "...", "ruleId": "..."}, plus approval_id and expires_at when an approval was created
Project resolution failure500Bare: {"error": "project_resolution_failed"}
Session quota and rate limits403 / 429Flat: {"error": "quota_exceeded", ...} or {"error": "rate_limited", ...} with limit fields at the top level
Test-mode mock errors403 / 422Flat: {"code": "mocks_not_permitted", "message": "..."} style, with code at the top level
Some legacy routes404Bare: {"error": "not_found"}

When the body has no request_id, take it from the X-Request-Id response header.

Error codes

Grouped by area. Each API reference page (/docs/api/*) also lists the errors specific to its surface. Wallet-specific codes (ledger conflicts, funding-source bindings, balance invariants) are also listed on the Wallets API page.

Validation

CodeStatusWhen it fires
invalid_body400The request body did not match the endpoint's schema. details.issues lists the exact field problems. Covers missing fields, wrong types, out-of-range values, and disallowed or reserved project slugs.
invalid_query400Query parameters did not match the endpoint's schema. details.issues lists the problems.

Fix: read details.issues and correct the named fields. The SDK's schemas catch most of these before the request is sent.

Auth and scopes

CodeStatusWhen it fires
unauthorized401No Authorization: Bearer header, the key is malformed, or it was revoked. Bare-string shape (see exceptions above).
forbidden403The key is valid but does not have the scope this route requires. The message names the missing scope. Flat shape.
budget_exceeded403A policy budget rule denied the call. Appears as reason in the flat policy-denial body, not as error.code.
project_resolution_failed500The key authenticated but no default project could be resolved for the account. Bare-string shape. Open a support ticket.

Fix for 401: verify the key in the dashboard under Settings, API Keys and confirm it is active and sent as Authorization: Bearer csk_....

Fix for 403 forbidden: create a key with the required scope, or widen the existing key's scopes.

Projects

CodeStatusWhen it fires
slug_conflict400Project create or update with a slug another project in the account already uses. Note this is a 400, not a 409.
cannot_delete_default409Delete on the default project. Promote another project to default first.
cannot_delete_last_project409Delete on the only project in the account. Create another project before deleting this one.
not_found404The project id does not exist or belongs to a different account.

Connections and providers

CodeStatusWhen it fires
not_connected424Connection verification found no active connection for this project and server. Connect the server first, then retry.
vault_unavailable503The credential store could not persist or read a secret. Nothing was written; retry with backoff.
provider_error502The upstream provider returned an error or an unexpected response. Retriable; retry with backoff.

Triggers

CodeStatusWhen it fires
unknown_server400Trigger create referenced a server_id that is not in the catalog.
trigger_not_active409Test-fire or event delivery on a trigger that is not active. Activate the trigger first.
invalid_delivery_id400A delivery id that is not a positive integer was passed to a delivery endpoint.

Consumer wallet and mandates

CodeStatusWhen it fires
mandate_not_found404The mandate id does not exist or is not visible to this account.
same_slot_transfer422Wallet transfer where from_currency and to_currency are the same slot. Nothing to move.
currency_not_authorized422Wallet transfer names a currency the wallet has no slot for. Also fires with status 403 on a mandate spend whose payee resolves to a currency the mandate has no slot for.
unsupported_transfer_route422No wired route between the two currencies. No FX is ever guessed.
not_wired501The transfer route exists in the plan but the execution rail is not wired yet, for example certain cross-currency pairs.

Test mode

CodeStatusWhen it fires
tool_not_mocked422A session declared mocks but the executed tool has no mock registered. Flat shape with code at the top level.
mocks_not_permitted403Mocks declared with a live-environment key. Use a csk_test_ key on a test-environment project. Flat shape.

Limits

CodeStatusWhen it fires
quota_exceeded403The monthly tool-call allowance for the plan is used up. The flat body includes plan, limit, and used.
rate_limited429Per-server rate limit hit on session execution. The response includes a Retry-After header (seconds) and retry_after_ms in the body.

Fix for 429: respect Retry-After. Exponential backoff with jitter is the canonical pattern.

Debugging

Errors in the standard envelope carry a request_id in the body; every response also carries it in the X-Request-Id header. In the dashboard, search the Logs page for that id to see the full trace: every upstream call, its response body, and timings.

For production support: open an issue at github.com/codespar/codespar with the request_id, timestamp, and expected behavior. See Debugging for the full bug-report template.

Next steps

Error Reference | CodeSpar