Error Codes
Learn the LayerX API's standardized JSON error structure, complete list of error codes, HTTP statuses, and guidance for retryable versus non-retryable
Error codes
All LayerX API errors follow a consistent JSON structure:
{
"error": {
"code": "insufficient_funds",
"message": "Transfer amount exceeds available balance.",
"details": {
"available": "10.00",
"requested": "25.00"
}
}
}
The code field is a stable machine-readable string. The message field is a human-readable explanation. The details field is optional and contains context-specific information.
Error codes
invalid_request
The request body or parameters are malformed. This includes missing required fields, invalid DID formats, non-numeric amounts, or malformed JSON.
HTTP status: 400
{
"error": {
"code": "invalid_request",
"message": "Field 'amount' must be a positive decimal string.",
"details": { "field": "amount", "value": "-5" }
}
}
unauthorized
The request lacks a valid principal token, the token has expired, or the DID signature verification failed.
HTTP status: 401
{
"error": {
"code": "unauthorized",
"message": "Principal token has expired."
}
}
Re-run the DID challenge/verify flow to obtain a new token.
not_found
The requested resource does not exist. This applies to receipt lookups, transfer queries, and DID lookups.
HTTP status: 404
{
"error": {
"code": "not_found",
"message": "No receipt found for sequence number 99999."
}
}
insufficient_funds
The sender's USDX balance is less than the requested transfer amount.
HTTP status: 402
{
"error": {
"code": "insufficient_funds",
"message": "Transfer amount exceeds available balance.",
"details": { "available": "10.00", "requested": "25.00" }
}
}
When returned in the context of a 402LXP flow, this indicates the agent cannot afford the service's price.
conflict
The request conflicts with current state. Common causes:
- Duplicate transfer - a transfer with the same nonce has already been processed.
- Already settled - the requested transfer has already been force-settled.
- Concurrent modification - the account was modified by another request.
HTTP status: 409
{
"error": {
"code": "conflict",
"message": "Transfer with nonce 42 already exists."
}
}
internal
An unexpected server error occurred. These are logged and investigated automatically. Retry with exponential backoff.
HTTP status: 500
{
"error": {
"code": "internal",
"message": "An unexpected error occurred. Please retry."
}
}
rate_limited
The client has exceeded the rate limit. The details object includes the retry-after window.
HTTP status: 429
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded.",
"details": { "retry_after_seconds": 5 }
}
}
Handling errors
Retryable errors
internal- retry with exponential backoff (1s, 2s, 4s, max 30s).rate_limited- wait forretry_after_secondsbefore retrying.conflict(duplicate nonce) - check if the transfer already succeeded before retrying.
Non-retryable errors
invalid_request- fix the request body before retrying.unauthorized- re-authenticate before retrying.not_found- the resource does not exist.insufficient_funds- deposit more USDX before retrying.