Errors & Rate Limits
Every error is a flat JSON envelope with a stable string code and a numeric code. Branch on the codes, not on message text.
Error envelope
{
"code": "SIGNATURE_MISMATCH",
"numericCode": 1302,
"message": "public key does not match wallet",
"requestId": "b0cb5771cc3ecd35…",
// present on 402 plan-limit errors only:
"current": 25, "limit": 25, "planCode": "sandbox", "upgradeTo": "launch"
}
Numeric code reference
| Range | Area | Notable codes |
|---|---|---|
1000–1099 | Auth | 1000 unauthorized · 1001 forbidden · 1002 key revoked · 1003 invalid signature |
1100–1199 | Validation | 1101 missing field · 1102 bad address · 1103 bad amount · 1104 duplicate externalId · 1105 invalid ownership proof · 1108 bad pagination |
1200–1299 | Policy | 1200 policy denied · 1201 approval required |
1300–1399 | Transactions | 1301 invalid state · 1302 signature mismatch · 1303 broadcast failed · 1304 nonce too low |
1400–1499 | Vaults | not found / archived |
1500–1599 | Node / chain | upstream node errors |
1600–1699 | Platform | 1601 idempotency conflict · 1602 rate limited |
1800–1849 | Billing (HTTP 402) | 1801 wallets · 1802 vaults · 1803 seats · 1804 sub-tenants · 1805 tokens · 1806 feature not in plan · 1807 quota · 1808 trial expired · 1809 billing suspended · 1810 mainnet not in plan |
Billing 402s carry the extra current / limit / planCode / upgradeTo fields — see Plans & Limits.
Rate limits
Limits are per tenant (one shared bucket across all keys and endpoints), sized by plan. Every response includes:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 1786363200 // unix epoch seconds
Exceeding the limit returns 429 with code RATE_LIMITED (1602) and a Retry-After header in seconds. Back off honoring Retry-After; don't hammer.
Request constraints
- Body size — request bodies over 1 MB are rejected.
- Timeouts — requests that exceed the server budget return
503. - Key-material guard — any body containing private keys, seed phrases, or mnemonics is rejected outright, before validation.
- Signup throttle —
/v1/signup*endpoints allow 5 requests per IP per hour.
Handling guidance
| HTTP | What to do |
|---|---|
400/422 | Fix the request; don't retry as-is |
401 | Check key format keyId:secret; rotate if expired/revoked |
402 | Plan limit — surface upgradeTo to your operator |
409 | State conflict (e.g. signing a non-PENDING_SIGNATURE tx) — refetch and reconcile |
429 | Wait Retry-After, then retry |
5xx | Retry with backoff and the same X-Idempotency-Key |

