Skip to main content
Every error response carries both an HTTP status code and a stable numeric code you can switch on programmatically. The shape is:
{
  "error": {
    "code": 1300,
    "type": "NOT_FOUND",
    "message": "Wallet not found",
    "request_id": "req_01HXYZ..."
  }
}
Always log request_id — it lets Qustody operators trace the full request path.

Code ranges

RangeFamily
1000–1099Authentication and authorization
1100–1199Validation
1200–1299Policy and approval
1300–1399Transaction lifecycle
1400–1499Vault and resource ownership
1500–1599Upstream node and chain
1600–1699Server / infrastructure

Authentication and authorization (1000–1099)

CodeTypeHTTPMeaning
1000UNAUTHORIZED401Missing or invalid bearer token
1001FORBIDDEN403Authenticated but RBAC permission missing for the resource+action
1002API_KEY_REVOKED401The API key has been revoked or rotated
1003INVALID_SIGNATURE401Webhook or request signature did not verify
Recovery: verify the bearer token, check the user’s role assignments via GET /v1/users/{id}/roles, or rotate the API key with POST /v1/credentials/rotate.

Validation (1100–1199)

CodeTypeHTTPMeaning
1100VALIDATION400Generic validation failure (see message)
1101MISSING_FIELD400A required field is absent
1102INVALID_ADDRESS400Address is not a valid Quantum Chain address
1103INVALID_AMOUNT400Amount is non-numeric, negative, or zero where not allowed
1104DUPLICATE_EXTERNAL_ID409An object with this external_id already exists for the tenant
1105OWNERSHIP_PROOF400The ownership-proof signature did not verify against the registered public key
1106INVALID_EMAIL400Email address is malformed
1107INVALID_URL400URL is malformed or non-HTTPS in production
1108INVALID_PAGINATION400limit is out of range or cursor is malformed
1109AMOUNT_OVERFLOW400Amount exceeds 256-bit unsigned bounds
1110STRING_TOO_LONG400A string field exceeds its allowed length
Recovery: fix the input. Validation errors are not retryable.

Policy and approval (1200–1299)

CodeTypeHTTPMeaning
1200POLICY_DENIED422A policy rule rejected the transaction outright (e.g. amount > MAX_AMOUNT, address on BLACKLIST_ADDRESS)
1201APPROVAL_REQUIRED422The transaction requires approvers; this is informational. The transaction is created in PENDING_AUTHORIZATION
1202APPROVAL_NOT_FOUND404The approval record does not exist or has expired
Recovery: for 1200, modify the request or update the policy. For 1201, route the transaction to the appropriate approvers.

Transaction lifecycle (1300–1399)

CodeTypeHTTPMeaning
1300TX_NOT_FOUND404The transaction ID does not exist for this tenant
1301TX_INVALID_STATE409Operation not allowed in the transaction’s current state (e.g. signing a BROADCASTING transaction)
1302TX_SIGNATURE_MISMATCH422The submitted post-quantum signature did not verify against the wallet’s registered public key
1303TX_BROADCAST_FAILED502The Quantum Chain node rejected the raw transaction
1304TX_NONCE_TOO_LOW422The nonce was already used on chain
Recovery: for 1301, fetch the latest state with GET /v1/transactions/{id}. For 1302, confirm the signer is using the correct key. For 1303 and 1304, cancel the transaction and resubmit.

Vault and resource (1400–1499)

CodeTypeHTTPMeaning
1400VAULT_NOT_FOUND404Vault does not exist for this tenant
1401VAULT_DUPLICATE409A vault with this name already exists

Upstream node and chain (1500–1599)

CodeTypeHTTPMeaning
1500NODE_UNAVAILABLE503The Quantum Chain RPC node is unreachable; circuit breaker may be open
1501CHAIN_ERROR502The node returned an error (gas estimation, QVM revert, etc.)
Recovery: retry with exponential backoff. If CUSTODY_NODE_BACKUP_RPC_URLS is configured, Qustody fails over automatically.

Server / infrastructure (1600–1699)

CodeTypeHTTPMeaning
1600INTERNAL_ERROR500Unexpected server error; see request_id
1601IDEMPOTENCY_CONFLICT422Same Idempotency-Key reused with a different method or path
1602RATE_LIMITED429Tenant or API key exceeded the rate limit; honor Retry-After
Recovery: for 1600, retry once after a short delay; if it persists, contact support with the request_id. For 1601, generate a fresh idempotency key. For 1602, respect the Retry-After header and consider a Redis-backed limiter for cluster deployments.

Retry policy

HTTP classRetry?Strategy
4xx (validation, auth, conflict)NoFix input; do not retry
409 TX_INVALID_STATENoRefresh state, then act
429YesBack off Retry-After seconds
502 / 503YesExponential backoff with jitter, max 5 retries
500YesOnce after 1–2s; if persistent, escalate
Always include an Idempotency-Key on retried mutating requests so the server collapses duplicates.

Webhook delivery errors

Webhook delivery failures don’t surface to the API caller. They appear in:
  • GET /v1/webhooks/{id}/deliveries — per-delivery status, last response code, retry count.
  • webhook.delivery.failed events — when an endpoint exhausts its retry budget.
If your endpoint returns 410 Gone, Qustody marks it DISABLED permanently. Recreate it to resume deliveries.