Error Handling
All Elaypay API responses -- whether successful or not -- follow a consistent envelope format. This page documents the response structure, HTTP status code conventions, and the complete error code catalog organized by domain.
Response Envelope
Every response from the Elaypay API is wrapped in a standard envelope with metadata fields.
Successful Response
Error Response
Envelope Fields
| Field | Type | Description |
|---|---|---|
version | string | API version (e.g., 1.3.0) |
timestamp | long | Response timestamp in epoch milliseconds |
success | boolean | true for successful operations, false for errors |
code | string | Machine-readable result code. 2xxx = success, domain-prefixed codes = error |
message | string | Human-readable result description |
data | object / null | Response payload on success; always null on error |
Always check the success field first. When success is false, use the code field for programmatic handling (e.g., retry logic, user-facing messages). The message field is informational and may change between API versions -- do not parse it programmatically.
HTTP Status Codes
The Elaypay API uses standard HTTP status codes. The table below lists all codes you may encounter:
| Code | Meaning | When Returned |
|---|---|---|
| 200 | OK | Request succeeded, response body contains the result |
| 201 | Created | A new resource was created successfully |
| 204 | No Content | Request succeeded, no response body (e.g., DELETE operations) |
| 400 | Bad Request | Validation error, invalid parameters, or business rule violation |
| 401 | Unauthorized | Missing or invalid authentication (bad API key, signature mismatch, timestamp expired) |
| 403 | Forbidden | Authentication succeeded but the caller lacks permission for this operation |
| 404 | Not Found | The requested resource does not exist |
| 409 | Conflict | Resource already exists or the operation conflicts with current state |
| 429 | Too Many Requests | Rate limit exceeded -- wait and retry |
| 500 | Internal Server Error | Unexpected server error -- contact support if persistent |
Error Code Catalog
Error codes use a domain prefix followed by a numeric identifier. The prefix tells you which module generated the error; the full code uniquely identifies the error condition.
S -- System / Infrastructure
General system-level errors that can occur on any endpoint.
| Code | Name | HTTP | Description |
|---|---|---|---|
S001 | INTERNAL_ERROR | 500 | Unexpected internal error. Contact support if this persists. |
S002 | SERVICE_UNAVAILABLE | 503 | A dependent service is unavailable. Retry after a brief delay. |
S003 | TIMEOUT | 504 | The operation timed out. The request may or may not have been processed. |
S004 | INVALID_REQUEST | 400 | The request is malformed (e.g., invalid JSON syntax). |
S005 | UNAUTHORIZED | 401 | Authentication is required but was not provided. |
S006 | FORBIDDEN | 403 | Access denied. The caller does not have the required role or permission. |
S007 | NOT_FOUND | 404 | The requested resource was not found. |
S011 | VALIDATION_ERROR | 400 | One or more request fields failed validation. |
S012 | INVALID_PARAMETER | 400 | A parameter value is invalid (wrong type, out of range, etc.). |
S013 | MISSING_PARAMETER | 400 | A required parameter is missing from the request. |
S031 | DATA_NOT_FOUND | 404 | The requested data record was not found in the database. |
S032 | DATA_ALREADY_EXISTS | 409 | A record with the same unique key already exists. |
S034 | CONCURRENT_MODIFICATION | 409 | Optimistic lock conflict. Another operation modified this resource concurrently. Retry. |
W -- Wallet
Errors from wallet account and balance operations.
| Code | Name | HTTP | Description |
|---|---|---|---|
W1001 | ACCOUNT_NOT_FOUND | 404 | The wallet account was not found. |
W1002 | ACCOUNT_INACTIVE | 400 | The wallet account is not active. Activate it before performing operations. |
W1003 | ACCOUNT_FROZEN | 400 | The wallet account is frozen. Contact an administrator. |
W1004 | ACCOUNT_ALREADY_EXISTS | 409 | A wallet account with this identity already exists. |
W3001 | INSUFFICIENT_BALANCE | 400 | The wallet does not have sufficient balance for this operation. |
W3003 | INSUFFICIENT_AVAILABLE | 400 | The available balance (excluding holds) is insufficient. |
W3005 | OPTIMISTIC_LOCK_CONFLICT | 409 | A concurrent modification was detected on the wallet balance. Retry the operation. |
W5005 | CURRENCY_NOT_SUPPORTED | 400 | The specified currency is not supported by this wallet. |
W9004 | MISSING_WORKSPACE_CONTEXT | 401 | The workspace context is missing. Ensure the API key is associated with a workspace. |
T -- Transfer
Errors from transfer creation and processing.
| Code | Name | HTTP | Description |
|---|---|---|---|
T1001 | SOURCE_WALLET_NOT_FOUND | 404 | The source wallet was not found. |
T1002 | TARGET_WALLET_NOT_FOUND | 404 | The target wallet was not found. |
T1005 | CURRENCY_MISMATCH | 400 | The source and target wallets use different currencies. |
T1006 | SAME_WALLET_TRANSFER | 400 | Cannot transfer funds to the same wallet. |
T1007 | INVALID_AMOUNT | 400 | The transfer amount must be positive. |
T1008 | INSUFFICIENT_BALANCE | 400 | The source wallet does not have sufficient balance. |
T1020 | ORDER_NOT_FOUND | 404 | The transfer order was not found. |
T1023 | DUPLICATE_REQUEST | 409 | A transfer with this idempotency key has already been processed. |
T1040 | EXECUTION_FAILED | 500 | The transfer execution failed. The funds were not moved. |
T1044 | TARIFF_NOT_CONFIGURED | 400 | The wallet tariff (fee schedule) is not configured. Contact an administrator. |
GA -- Gateway Auth
Errors from the API gateway authentication pipeline. See HMAC Authentication for the full validation pipeline.
| Code | Name | HTTP | Description |
|---|---|---|---|
GA2001 | API_KEY_REQUIRED | 401 | The X-Api-Key header is missing. |
GA2002 | SIGNATURE_REQUIRED | 401 | The X-Signature header is missing. |
GA2011 | API_KEY_INVALID | 401 | The API key is invalid or was not found. |
GA2012 | SIGNATURE_INVALID | 401 | Signature verification failed. |
GA2013 | TIMESTAMP_EXPIRED | 401 | The request timestamp is outside the 60-second window. |
GA2021 | API_KEY_DISABLED | 403 | The API key has been disabled. |
GA2022 | IP_NOT_ALLOWED | 403 | The client IP is not in the whitelist. |
GA2024 | SCOPE_DENIED | 403 | The API key lacks the required scope. |
GA2032 | WORKSPACE_NOT_FOUND | 404 | The workspace was not found. |
GA2034 | WORKSPACE_NOT_MEMBER | 403 | The user is not a member of the workspace. |
Error Handling Best Practices
For 5xx errors and 429 (rate limit), implement exponential backoff with jitter. Start with a 1-second delay, double on each retry, and add random jitter to avoid thundering herd. Set a maximum of 3-5 retries.
For POST operations that create resources, use an idempotency key. If a request fails with a network error and you retry, the idempotency key prevents duplicate creation. A T1023 (DUPLICATE_REQUEST) response means your original request was processed successfully.
Map error codes to user-friendly messages in your application. Do not display raw error codes or the message field to end users -- they are intended for developers. Build a translation layer that converts codes like W3001 into messages like "Insufficient funds to complete this transfer."
Log the full response envelope (including code, message, and timestamp) for every error. The timestamp field helps correlate client-side errors with server-side logs when working with Elaypay support.