Error catalogue
Every error the API returns is an RFC 9457 problem document with
the media type application/problem+json. Its type member is the address of the page that describes it,
so an agent can follow the error straight to its own documentation.
{
"type": "https://docs.co-relayer.com/errors/quota-exhausted",
"title": "The plan’s included Relay Units are used up.",
"status": 429,
"detail": "Cap of 1000 RU reached for the period ending 2026-10-19T00:00:00Z.",
"instance": "req_01JB…",
"code": "QUOTA_EXHAUSTED",
"retryable": false,
"resign": "NONE",
"details": {
"reason": "CAP_REACHED_PAYG_OFF"
},
"hint": "Turn on pay-as-you-go or upgrade the tier."
}
The members you should branch on
| Member | Always present | What it is for |
|---|---|---|
code | yes | The stable machine name. Branch on this, not on title or detail. |
status | yes | The HTTP status. Use it when code is one your client does not know. |
retryable | yes | Whether sending the same request again can succeed. |
resign | relay path | NONE, SAME_BYTES or NEW_SIGNATURE_SAME_NONCE. Never ask for a signature unless it says so. |
hint | usually | One sentence naming the next action, written for an agent. |
instance | yes | The request id. Quote it to support. |
details | some codes | Machine-readable specifics, listed on each code’s page. |
intent | relay path | sender, nonce, state and, once it exists, txHash. |
The enum is open
New codes are added without a breaking change, so treat an unknown code by its status and
retryable members rather than failing. Additions are announced in the changelog.
The names some other documents use
A few names that appear in our own specs are not codes of this API: NO_SUBSCRIPTION is
NO_ENTITLEMENT, SERVICE_HALTED is QUOTA_EXHAUSTED (or ACCOUNT_SUSPENDED), and
GAS_PRICE_TOO_HIGH / GAS_PRICE_TOO_LOW are both GAS_PRICE_OUT_OF_RANGE with
details.bound set to max or min.
Every code
The machine-readable version of this table is /errors.json.
Relay path
| Code | HTTP | Retryable | Meaning |
|---|---|---|---|
MALFORMED_REQUEST | 400 | no | The request body did not match the schema of the endpoint. |
VARIANTS_NOT_SUPPORTED | 400 | no | The request carried several signed variants of the same transaction. |
RELAYER_SIGNATURE_PRESENT | 400 | no | The transaction already had a relayerSignature. |
CHAIN_ID_MISMATCH | 400 | no | The transaction was signed for a different network than this host serves. |
TX_VERSION_UNSUPPORTED | 400 | no | The transaction version is not one CoRelayer relays. |
TX_OPTIONS_UNSUPPORTED | 400 | no | The transaction options field has a bit CoRelayer does not relay. |
LEASE_MISSING | 400 | no | The relay request arrived without the lease returned by the assign call. |
LEASE_INVALID | 403 | no | The lease did not verify. |
LEASE_MISMATCH | 409 | no | The lease does not belong to this transaction. |
LEASE_EXPIRED | 409 | yes | The lease was older than its validity window when the transaction arrived. |
NONCE_PIN_MISMATCH | 409 | no | The transaction nonce is not the nonce the assignment pinned. |
RESIGN_REQUIRED | 409 | no | The assigned relayer can no longer be used, so the transaction must be signed once more. |
RESIGN_SAME_NONCE | 409 | no | A replacement for the same nonce is needed, at a higher gas price. |
REPLACEMENT_UNDERPRICED | 422 | no | The replacement transaction does not pay enough to displace the one in the pool. |
INTENT_ALREADY_EXECUTED | 409 | no | That nonce has already executed on chain. |
NOTHING_TO_CANCEL | 409 | no | There is no in-flight intent to cancel. |
NONCE_TOO_LOW | 409 | no | The transaction nonce is below the account nonce on chain. |
NONCE_IN_FLIGHT | 409 | yes | Another intent already holds this nonce. |
NONCE_GAP | 409 | no | The nonce skips ahead of the account nonce and the pool. |
TOO_MANY_IN_FLIGHT | 429 | yes | This sender has as many unsettled intents as it may have at once. |
RELAYER_UNKNOWN | 422 | no | The relayer address in the transaction is not one of ours. |
RELAYER_SHARD_MISMATCH | 422 | no | The relayer is not in the sender’s shard. |
RELAYER_RETIRED | 410 | no | The relayer in the transaction has been retired. |
GAS_PRICE_OUT_OF_RANGE | 422 | no | The gas price is below the network minimum or above the cap CoRelayer relays. |
GAS_LIMIT_TOO_LOW | 422 | no | The gas limit is below the movement gas of the transaction. |
GAS_LIMIT_TOO_HIGH | 422 | no | The gas limit is above the ceiling of your rate class. |
GAS_OVERPROVISIONED | 422 | no | The gas limit is far above what simulation says the transaction needs. |
DATA_TOO_LARGE | 422 | no | The transaction data field is larger than self-serve accounts may send. |
RECEIVER_NOT_ALLOWED | 403 | no | The receiver of the transaction is not allowed on this path. |
SENDER_SIGNATURE_INVALID | 422 | no | The sender signature does not verify against the transaction bytes. |
GUARDIAN_SIGNATURE_INVALID | 422 | no | The guardian signature does not verify. |
GUARDIAN_REQUIRED | 422 | no | The sender is guarded but the transaction is not. |
GUARDIAN_MISMATCH | 422 | no | The guardian in the transaction is not the sender’s active guardian. |
GUARDIAN_IS_RELAYER | 422 | no | The guardian and the relayer are the same address. |
INSUFFICIENT_SENDER_BALANCE | 422 | no | The sender cannot cover the value it is trying to move. |
SIMULATION_FAILED | 422 | no | Pre-flight simulation says the transaction would fail on chain. |
SWAP_VENUE_PAUSED | 503 | yes | The exchange venue used to convert USDC is paused. |
CONTRACT_PAUSED | 503 | yes | The CoRelayer contract is paused for this kind of call. |
ASSIGN_PROOF_REQUIRED | 401 | no | The assign call needs a proof that the sender is present. |
ASSIGN_PROOF_INVALID | 401 | no | The presence proof did not verify. |
FREE_FLOW_BUSY | 409 | yes | This sender already has a free transaction in flight. |
FREE_FLOW_BARRED | 403 | no | This sender is temporarily barred from the free flow. |
FREE_FLOW_UNAVAILABLE | 503 | yes | The free-transaction budget for this period is spent. |
INTENT_ALREADY_SUBMITTED | 409 | no | This idempotency key was already used. |
HOURLY_BURN_EXCEEDED | 429 | yes | The account passed the Relay Units per hour of its rate class. |
SIGNER_TIMEOUT | 503 | yes | The signer did not commit before the deadline. |
NO_ENTITLEMENT | 402 | no | The account has no plan that can pay for this transaction. |
SENDER_NOT_AUTHORIZED | 403 | no | This sender is not authorised to spend the paying account’s plan. |
QUOTA_EXHAUSTED | 429 | no | The plan’s included Relay Units are used up. |
RATE_LIMITED | 429 | yes | You are sending faster than your rate class allows. |
GAS_BUDGET_EXCEEDED | 429 | yes | The gas-per-second budget of your rate class in this shard is spent. |
NO_RELAYER_AVAILABLE | 503 | yes | No healthy relayer can be assigned in that shard right now. |
UPSTREAM_UNAVAILABLE | 503 | yes | A dependency (chain gateway, node) was unavailable before anything was committed. |
SIGNER_UNAVAILABLE | 503 | yes | The signer process could not be reached. |
SIGNER_FENCED | 503 | yes | The signer fenced itself and refuses to sign. |
INTERNAL | 500 | yes | An unexpected failure before the commit point. |
Pricing and purchase
| Code | HTTP | Retryable | Meaning |
|---|---|---|---|
PRICE_ABOVE_MAX | 409 | no | The price at execution time is above the maximum you signed for. |
TIER_NOT_PURCHASABLE | 422 | no | That tier cannot be bought right now. |
QUEUED_BLOCK_EXISTS | 409 | no | A plan is already queued to start after the current one. |
DOWNGRADE_NOT_IMMEDIATE | 409 | no | A plan without a period cannot start while a period plan is running. |
INSUFFICIENT_CREDITS | 402 | no | The account does not hold enough credits for this purchase. |
DEPOSIT_BELOW_MIN | 422 | no | The deposit is below the minimum the contract accepts. |
DEPOSIT_ABOVE_MAX | 422 | no | The deposit is above the configured maximum. |
SWAP_BUDGET_EXHAUSTED | 503 | yes | The rolling swap budget for deposits is used up. |
PAYG_PRICE_ABOVE_MAX | 409 | no | The pay-as-you-go price is above the maximum this account accepts. |
DEPLOY_NOT_ALLOWED | 403 | no | Contract deployments and upgrades are not relayed for this account. |
UNSUPPORTED_TX_FIELD | 422 | no | The transaction carries a fee-relevant field this Relay-Unit schedule does not price. |
QUOTE_EXPIRED | 409 | no | The quote presented with the payment has expired. |
RENEW_NOT_APPLICABLE | 409 | no | “Renew now” would do nothing. |
Platform
| Code | HTTP | Retryable | Meaning |
|---|---|---|---|
UNAUTHENTICATED | 401 | no | The endpoint needs credentials and none were presented. |
TOKEN_INVALID | 401 | no | The token did not verify. |
TOKEN_EXPIRED | 401 | no | The token is past its validity. |
ORIGIN_NOT_ALLOWED | 403 | no | The browser origin is not allowed for this route. |
CHALLENGE_INVALID | 401 | no | The signed challenge did not verify. |
API_KEY_INVALID | 401 | no | The API key is unknown, revoked, or from another environment. |
API_KEY_SCOPE | 403 | no | The API key is valid but not allowed to do this. |
STREAM_TICKET_INVALID | 401 | no | The ticket presented to the event stream did not verify. |
FORBIDDEN | 403 | no | Authenticated, but not permitted to do this. |
ACCOUNT_SUSPENDED | 403 | no | The account is suspended. |
NOT_FOUND | 404 | no | No such resource. |
PAYLOAD_TOO_LARGE | 413 | no | The request body is larger than the endpoint accepts. |
CURSOR_INVALID | 400 | no | The pagination cursor is malformed or no longer valid. |
IDEMPOTENCY_KEY_REUSED | 422 | no | That idempotency key was used for a different request body. |
IDEMPOTENCY_IN_PROGRESS | 409 | yes | The first request with this key is still running. |
LIMIT_REACHED | 409 | no | A per-account limit is full. |
WEBHOOK_URL_NOT_ALLOWED | 422 | no | That webhook URL cannot be registered. |
x402
| Code | HTTP | Retryable | Meaning |
|---|---|---|---|
PAYMENT_REQUIRED | 402 | no | The resource needs payment; the response describes how. |
PAYMENT_INVALID | 402 | no | The payment presented did not verify. |
PAYMENT_FAILED | 402 | no | The payment verified but could not be settled. |