Error Format
| Field | Description |
|---|---|
type | A URI identifying the error type |
title | A short, human-readable summary |
status | The HTTP status code |
detail | A human-readable explanation specific to this occurrence |
instance | The request path that generated the error |
error_code | Machine-readable code in {DOMAIN}-{STATUS}-{SEQUENCE} format |
trace_id | Unique identifier for this request — share with support for debugging |
Domain Prefixes
Each error code starts with a domain prefix that identifies the resource or subsystem the error originated from. Branch onerror_code to render domain-specific UI without parsing detail strings.
| Prefix | Domain |
|---|---|
USR | Users and accounts |
ONB | Onboarding state machine |
WAL | Wallets (EOA and Safe) |
KYC | KYC verification |
SAF | Safe smart contract creation |
SGN | Agent signer setup |
STS | User status transitions |
PHONE | Phone verification |
TXN | Transactions |
RCT | Receipts |
BUD | Budgets |
INS | Insights |
CRD | Cards |
CHT | Chat sessions and messages |
IPA | Errand (Intelligent Purchase Authorisation) operations |
PINT | Stamped Mandate (Purchase Intent) signing and validation |
PAY | Payment Links and x402 settlement |
SIS | Sumvin Identity Service (org/env/member/keys) |
BNK | Bank linking and open banking |
RMP | On/off-ramp sessions |
ACC | Accounts |
AST | Assets |
GEN | General validation |
SYS | Internal system errors |
Common HTTP Status Codes
| Status | Meaning | Action |
|---|---|---|
| 200 | Success | — |
| 201 | Created | Resource created successfully |
| 202 | Accepted | Async operation started — poll _links for completion |
| 208 | Already Reported | Idempotent replay — resource already exists, returned as-is |
| 400 | Bad Request | Fix the request body or parameters |
| 401 | Unauthorized | Check your JWT or API key |
| 403 | Forbidden | Valid credentials but insufficient permissions |
| 404 | Not Found | Resource doesn’t exist — check the ID |
| 409 | Conflict | Resource state conflict (e.g., duplicate wallet) |
| 422 | Unprocessable | Missing or invalid required fields |
| 424 | Failed Dependency | Upstream dependency not ready (e.g., agent signer not provisioned) |
| 429 | Too Many Requests | Rate limited — wait for Retry-After header duration |
| 500 | Internal Error | Retry with exponential backoff |
Authentication Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
USR-401-001 | 401 | Missing or invalid JWT | Check x-juno-jwt header contains a valid, unexpired token |
USR-404-001 | 404 | No user exists for this JWT | Create the user first with POST /v0/user/ |
User & Onboarding Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
USR-409-001 | 409 | User already exists | Use the existing user — POST /v0/user/ returns 208 Already Reported |
USR-422-001 | 422 | Missing required fields on user creation | Include primary_eoa_address and chain_id |
Wallet Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
WAL-400-001 | 400 | Invalid Ethereum address format | Provide a valid 0x-prefixed, checksummed address |
WAL-400-002 | 400 | Chain ID does not match primary chain | Use the same chain as the primary wallet |
WAL-400-004 | 400 | Primary chain is locked because a Safe wallet is already persisted on a different chain | Don’t try to switch primary chain after a Safe has been deployed. See Wallets Guide |
WAL-403-001 | 403 | Cannot delete primary wallet | Set another wallet as primary first |
WAL-403-002 | 403 | Wallet belongs to another user | Verify the wallet ID |
WAL-403-003 | 403 | Wallet address not in verified credentials | Verify wallet ownership — see Wallets Guide |
WAL-404-001 | 404 | Wallet not found | Check the wallet ID; list wallets via GET /v0/wallets |
WAL-409-001 | 409 | Wallet already exists for this address and chain | Use the existing wallet |
USR-424-001 | 424 | No active agent signer | Wait for onboarding to complete before setting a primary wallet |
Onboarding Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
ONB-409-001 | 409 | Submitted step does not match the user’s current step | Read GET /v0/user/me/onboarding/steps and submit current_step |
ONB-409-002 | 409 | The targeted onboarding step is already completed (BYO Safe / user-signed deploy submission for a closed step) | The user is already past this step — fetch their current state and route accordingly |
Safe Operation Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
SAF-400-012 | 400 | User-signed Safe deploy verification failed (not a Safe, wrong owners, wrong contract version) | Permanent — do not retry. The deployed contract does not match expectations. |
SAF-409-001 | 409 | Idempotency-Key reused with a different request body | Use a fresh key for a different request, or replay the original |
SAF-503-001 | 503 | User-signed Safe deploy finalisation hit a transient error after the UserOperation was included | Pause polling for the Retry-After interval (default 5s) then retry the status poll |
SIS Configuration Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
SIS-409-008 | 409 | Mutually-exclusive features both requested enabled (ai_agent + user_signed_deploy) | Disable one before enabling the other. See Environment features |
KYC Errors
| Error Code | Status | Description | Resolution |
|---|---|---|---|
KYC-403-001 | 403 | KYC already submitted | Check status with GET /v0/kyc/status instead of re-submitting |
KYC-409-001 | 409 | KYC session already in progress | Wait for the existing session to complete |
Retry Strategy
Retryable Errors
These errors are transient and should be retried with exponential backoff:| Status | Strategy |
|---|---|
| 429 | Wait for the Retry-After header value, then retry |
| 500 | Retry up to 3 times with exponential backoff (1s, 2s, 4s) |
| 424 | Retry after a delay — the upstream dependency may become available |
| 202 | Not an error — poll the linked resource for completion |
Non-Retryable Errors
These indicate a problem with the request itself:| Status | Action |
|---|---|
| 400 | Fix the request body or parameters |
| 401 | Refresh or replace the authentication token |
| 403 | Check permissions — the action may not be allowed in the current state |
| 404 | Verify the resource ID exists |
| 409 | Resolve the conflict — typically by using the existing resource |