Errors
Error shape and the codes you will handle most often.
Errors share one JSON shape:
{
"error": {
"code": "INVALID_AMOUNT",
"message": "Human-readable message"
}
}Branch on error.code. Use message for logs and support.
HTTP status
| Status | Typical meaning |
|---|---|
400 | Invalid input |
401 | Missing or invalid credentials / signature |
403 | Not allowed (for example live not approved) |
404 | Not found |
409 | Conflict (for example idempotency mismatch) |
410 | Endpoint retired — use the Payments API |
429 | Rate limited |
500 | Unexpected server error |
Common codes
Auth & signing
| Code | Status | When |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid credentials |
INVALID_API_KEY | 401 | Unknown or revoked key |
SIGNATURE_REQUIRED | 401 | Missing X-Request-Signature |
INVALID_SIGNATURE | 401 | Signature does not match the request |
SIGNATURE_EXPIRED | 401 | Timestamp outside the allowed window |
SIGNING_MISCONFIGURED | 401/500 | Signing secret missing — re-issue in the dashboard |
RATE_LIMITED | 429 | Over 100 requests/minute |
Payments
| Code | Status | When |
|---|---|---|
INVALID_AMOUNT | 400 | Amount must be a positive decimal string |
EMAIL_REQUIRED | 400 | Missing or invalid email |
INVALID_TOKEN | 400 | Token must be USDC or USDT |
INVALID_NETWORK_ID | 400 | Bad or unknown networkId |
INVALID_ADDRESS_MODE | 400 | addressMode must be invoice or customer |
INVALID_SETTLEMENT_ADDRESSES | 400 | Settlement address list missing or malformed |
TOKEN_NOT_AVAILABLE | 400 | Token not available on the selected network(s) |
NETWORK_NOT_AVAILABLE | 400 | Network not enabled for this account |
AMOUNT_TOO_SMALL | 400 | Below the minimum payment amount |
OPEN_INVOICE_EXISTS | 409 | Payer already has an open customer-mode payment |
PAYMENT_NOT_FOUND | 404 | Unknown payment id |
IDEMPOTENCY_KEY_REQUIRED | 400 | Missing Idempotency-Key |
IDEMPOTENCY_CONFLICT | 409 | Same key, different body |
ENDPOINT_GONE | 410 | Old money endpoint — use /v1/payments |
LIVE_NOT_APPROVED | 403 | Live key before go-live approval |
MERCHANT_SUSPENDED | 403 | Account suspended |
Webhooks (dashboard)
| Code | Status | When |
|---|---|---|
INVALID_WEBHOOK_URL | 400 | Bad URL, or live URL is not public HTTPS |
INVALID_WEBHOOK_SECRET | 400 | Secret length out of range |
WEBHOOK_SECRET_REQUIRED | 400 | First setup without a secret |
WEBHOOK_NOT_CONFIGURED | 404 | No endpoint for that environment |
Idempotency
On create calls, send a fresh Idempotency-Key per distinct attempt (a UUID is fine).
- Same key + same body → original result
- Same key + different body →
IDEMPOTENCY_CONFLICT(409)
Rate limits
Default: 100 requests/minute per API key. On 429, retry with backoff.