Errors
API Error Codes
Every error code, its HTTP status, and what to do about it.
All errors use the envelope {"error": {"code", "message", "request_id"}}.
Branch on code: message is for humans.
Authentication and authorization
| Code | HTTP | Meaning | Your action |
|---|---|---|---|
UNAUTHENTICATED | 401 | Missing/invalid/revoked key | Fix the key |
FORBIDDEN | 403 | Valid key, disallowed scope or IP | Check scope/IP allowlist |
ACCOUNT_SUSPENDED | 403 | Account suspended by operations | Contact support |
PIN_REQUIRED | 403 | Transaction PIN step-up needed | Prompt for PIN |
Validation and state
| Code | HTTP | Meaning | Your action |
|---|---|---|---|
VALIDATION | 400 | Field validation failed | Fix the request |
NOT_FOUND | 404 | Resource does not exist | Check the id |
DUPLICATE | 409 | Unique constraint conflict | Reuse existing resource |
CONFLICT | 409 | Invalid state transition | Check current status |
IDEMPOTENCY_REPLAY | 409 | Key reused with different payload | Do not mutate on retry |
Business rules (422)
| Code | Meaning | Your action |
|---|---|---|
INSUFFICIENT_FUNDS | Wallet cannot cover amount + fee | Prompt for funding/lower amount |
LIMIT_EXCEEDED | Above the customer's tier limit | Prompt for KYC upgrade |
COMPLIANCE_DENIED | Screening blocked the operation | Unrecoverable: do not retry |
METHOD_NOT_SELECTABLE | Method not enabled for customer | Re-resolve /payments/methods |
FEATURE_DISABLED | Operation under maintenance | Surface maintenance, retry later |
Rate limits and infrastructure
| Code | HTTP | Meaning | Your action |
|---|---|---|---|
RATE_LIMITED | 429 | Quota exceeded | Back off, retry later |
PROVIDER_ERROR | 502 | Upstream provider failed | Retry-safe via idempotency |
INTERNAL | 500 | OuiPay internal error | Retry; quote request_id |
failure.code vs error.code
Both are machine-readable, but on different surfaces:
error.code: the HTTP response's reason (this page)failure.code: the transaction's recorded failure reason, visible onGET /v1/transactions/{id}and failed webhook events
A rejected request produces both: an HTTP error now and a failed
transaction entry carrying failure.code + failure.stage.