Error codes
Every non-2xx response from Photon uses the standard error envelope. The code values below are stable — branch your error handling on code, never on message, since messages may carry request-specific detail.
Error envelope
{
"success": false,
"error": {
"code": "TRANSACTION_002",
"message": "Insufficient balance to process transaction",
"category": "TRANSACTION",
"details": { "required": 1.25, "available": 0.5 },
"traceId": "a4f2c9e1d7b83a50"
},
"timestamp": "2026-07-29T09:14:03.512Z"
}
| Field |
Type |
Description |
error.code |
string |
Stable machine-readable code from the tables below. |
error.message |
string |
Human-readable description. May be more specific than the default message listed here. |
error.category |
string |
One of AUTH, VALIDATION, TRANSACTION, USER, SYSTEM, CHAIN, RESOURCE, PAYMENT. |
error.details |
object |
Optional. Extra context for the failure; omitted when there is none. |
error.traceId |
string |
Opaque identifier for this request. |
timestamp |
string |
ISO-8601 UTC timestamp with millisecond precision. |
Info
Include the traceId when you contact support about a failed request — it lets us find the exact request in our logs.
AUTH — authentication and authorization
| Code |
HTTP status |
Default message |
AUTH_001 |
401 |
Unauthorized access |
AUTH_002 |
401 |
Invalid API key provided |
AUTH_003 |
401 |
Admin key required for this operation |
AUTH_004 |
401 |
Invalid or malformed JWT token |
AUTH_005 |
401 |
JWT token has expired |
AUTH_006 |
401 |
Invalid nonce provided |
AUTH_007 |
401 |
Nonce has expired |
AUTH_008 |
401 |
Invalid wallet signature |
Seeing AUTH_001 or AUTH_002? Check that you are sending the api-key header — see Get API access.
| Code |
HTTP status |
Default message |
VALIDATION_001 |
400 |
Invalid input data |
VALIDATION_002 |
400 |
Invalid address format |
VALIDATION_003 |
400 |
Invalid or unsupported chain ID |
VALIDATION_004 |
400 |
Request validation failed |
TRANSACTION — transaction processing
| Code |
HTTP status |
Default message |
TRANSACTION_001 |
400 |
Transaction cost exceeds maximum allowed limit |
TRANSACTION_002 |
400 |
Insufficient balance to process transaction |
TRANSACTION_003 |
404 |
Transaction not found |
TRANSACTION_004 |
500 |
Error processing transaction |
TRANSACTION_005 |
400 |
Invalid gas parameters provided |
TRANSACTION_006 |
400 |
Daily limit exceeded, can not process transaction |
USER — user management
| Code |
HTTP status |
Default message |
USER_001 |
404 |
User not found |
USER_002 |
400 |
User already exists |
USER_003 |
400 |
Invalid user address |
USER_004 |
403 |
User account has been disabled |
SYSTEM — system-level
| Code |
HTTP status |
Default message |
SYSTEM_001 |
500 |
Database operation failed |
SYSTEM_002 |
500 |
Internal server error |
SYSTEM_003 |
503 |
Service temporarily unavailable |
CHAIN — blockchain
| Code |
HTTP status |
Default message |
CHAIN_001 |
400 |
Unsupported blockchain network |
CHAIN_002 |
500 |
Chain adapter operation failed |
CHAIN_003 |
500 |
Blockchain RPC error |
CHAIN_004 |
503 |
Network connectivity error |
RESOURCE — resource management
| Code |
HTTP status |
Default message |
RESOURCE_001 |
404 |
Requested resource not found |
RESOURCE_002 |
409 |
Resource conflict detected |
RESOURCE_003 |
429 |
Resource limit exceeded |
RESOURCE_003 is the rate-limit response — see rate limiting for the limits and how to back off.
PAYMENT_REQUIRED
One code sits outside the numbered table:
| Code |
Category |
HTTP status |
Default message |
PAYMENT_REQUIRED |
PAYMENT |
402 |
x402 payment required |
It is returned during x402 payment negotiation, when a request must be paid for before Photon will process it.
Retry guidance
SYSTEM_003 and CHAIN_004 (both 503) are transient — retry with backoff.
RESOURCE_003 (429) means you are over your rate limit — slow down, then retry.
- 4xx codes other than 429 indicate a problem with the request itself; retrying unchanged will fail again.