Errors

Every error response from the Aeses API has the same shape. Branch on the type and code fields — not the human-readable message, which may change.

Response shape

Error response
{
"error": {
  "type": "invalid_request_error",
  "code": "insufficient_balance",
  "message": "Available USDC balance is 12.50 — requested 50.00.",
  "param": "amount",
  "request_id": "req_01HXYZ7M2P5RT4VG3K8AQWE9FN",
  "doc_url": "https://docs.aeses.io/errors#insufficient_balance"
}
}

| Field | Always present | Description | | ------------ | -------------- | ------------------------------------------------------------- | | type | Yes | High-level category. Use to decide retry behavior. | | code | Yes | Stable, machine-readable code. Use for branching logic. | | message | Yes | Human-readable, English. Not stable — do not parse. | | param | When relevant | The request parameter that caused the error. | | request_id | Yes | Echoed in every response. Include it when contacting support. | | doc_url | When available | Direct link to the documentation for this code. |

Error types

| Type | HTTP | Retry? | Meaning | | ----------------------- | ----- | --------------------------- | ------------------------------------------------- | | authentication_error | 401 | Never — fix the key first. | Missing, invalid, or revoked API key. | | forbidden | 403 | Never. | Key valid but lacks permission for this resource. | | invalid_request_error | 400 | Never — fix the payload. | Validation, schema, or business-rule violation. | | not_found | 404 | Never. | The requested resource does not exist. | | idempotency_error | 409 | Never — generate a new key. | Idempotency key was reused with a different body. | | rate_limit_error | 429 | Yes, with backoff. | Too many requests. Respect Retry-After. | | api_error | 500 | Yes, with backoff. | Internal server error. | | service_unavailable | 503 | Yes, with backoff. | Temporary outage. Retry after a short delay. |

Retry strategy

  • Never retry on 4xx errors except 429.
  • Retry with exponential backoff on 429, 500, and 503. Start at 500ms, double up to 8s, then give up after 5 attempts.
  • Always send the same Idempotency-Key on every retry so the operation runs at most once. See Idempotency.

Common error codes

| Code | Type | Description | | ----------------------------- | ----------------------- | --------------------------------------------------------------------- | | api_key_missing | authentication_error | No x-api-key header present. | | api_key_invalid | authentication_error | The key does not exist or has been revoked. | | key_environment_mismatch | authentication_error | Test key used in live mode (or vice versa). | | parameter_missing | invalid_request_error | A required parameter was omitted. param indicates which. | | parameter_invalid | invalid_request_error | A parameter has the wrong type or format. | | unsupported_asset | invalid_request_error | The requested asset/chain combination is not supported. | | insufficient_balance | invalid_request_error | The account does not have enough balance for the requested operation. | | withdrawal_below_minimum | invalid_request_error | Withdrawal amount is below the network minimum. | | invalid_destination_address | invalid_request_error | The destination address is malformed or invalid for the network. | | idempotency_key_reused | idempotency_error | The Idempotency-Key was used with a different request body. | | rate_limited | rate_limit_error | Too many requests in the window. Honor Retry-After. | | internal_error | api_error | Unexpected server-side failure. Safe to retry. |

Always log request_id

Every response — success or error — includes a Request-Id header and (on errors) a request_id field. Log it on every request. When you contact support, providing the request_id cuts diagnosis time from hours to minutes.