Errors and rate limits
Handle request IDs, blocked reasons, idempotency conflicts, quotas, and safe retries.
Every failed Developer API response is JSON and includes a request ID. Preserve that ID in your support and audit records; never include a secret key, wallet-session token, signature, or signer credential in an error report.
{
"ok": false,
"code": "wrong_network",
"message": "The wallet session is bound to a different network.",
"requestId": "req_...",
"retryable": false,
"blockedReason": "wallet_session_chain_mismatch",
"docsUrl": "https://docs.torq.finance/developers/errors/wrong_network"
}Retry rules
| Response | What to do |
|---|---|
400 or 403 | Correct the request, origin, scope, wallet, role, or network. Do not retry unchanged input. |
409 idempotency_conflict | Reuse the original request body for that key, or choose a new key for a distinct operation. |
429 | Wait until the supplied Retry-After or x-ratelimit-reset, then retry with backoff. |
5xx with retryable: true | Retry the same idempotency key with bounded exponential backoff. |
capability_not_ready | Do not substitute arbitrary calldata. Use a supported workflow or wait for the capability to become available. |
Rate-limit headers
Every API response carries:
x-ratelimit-limit
x-ratelimit-remaining
x-ratelimit-reset
x-request-idAnonymous discovery is limited per source IP and operation. Authenticated preview applications
receive a higher per-application operation budget, currently 120 requests per minute by default.
An application can also have scoped quotas, including sandbox and faucet quotas. Treat the headers
as authoritative rather than hard-coding a client-side limit.
Idempotency
Send Idempotency-Key for every state-changing request. Reuse it only when retrying the exact same
operation. Torq records the request fingerprint and response in the same transaction as the
mutation: a matching retry returns the safe stored result, while changed input fails with
idempotency_conflict before another write occurs.
Pagination
List endpoints that declare pagination accept the cursor and limit parameters in their OpenAPI
operation. Treat the returned pageInfo.nextCursor as opaque and preserve the API ordering while
following it. Stop when pageInfo.hasMore is false; do not synthesize an offset or sort order
from a cursor. A stale, malformed, or expired cursor fails with the returned error code and request
ID, so restart from the resource’s canonical first page when the integration cannot resume safely.
Canonical-state blocks
A workflow can be blocked because the current projected state is stale, a prior intent has not
reached final_success, a role changed, an authority was lost, or a prepared snapshot expired.
Re-fetch and re-prepare from canonical state. Do not retry a stale prepared intent or alter its
calldata locally.
Observed error-code registry
This registry is generated from the developer surface inventory. The response’smessage, blockedReason, retryable, andrequestId remain the authoritative remediation context.
| Code | Meaning |
|---|---|
capability_not_ready | The requested capability is not available for the current governed deployment or preview boundary. |
idempotency_conflict | The idempotency key was already used with a different request fingerprint. |
invalid_chain_id | The chain identifier is invalid for the request. |
invalid_credentials | The supplied developer key, wallet session, or other credential could not be accepted. |
invalid_cursor | The pagination cursor is invalid or cannot be resumed. |
invalid_graphql_request | The GraphQL request did not satisfy the parser or query budget. |
invalid_pagination | The supplied pagination input is invalid. |
invalid_transaction_hash | The registered transaction hash is invalid. |
invalid_transaction_order | The registered transaction order does not match the prepared workflow. |
invalid_workflow_input | The workflow input fails the registered workflow validation. |
wrong_network | The signer or wallet session is bound to a different network. |