Error Codes
x402 API errors follow a consistent format with machine-readable codes.
Error Response Format
{
"success": false,
"error": "Human-readable error message",
"code": "error_code",
"x402Version": 1
}
HTTP Status Codes
402 Payment Required
Payment-related errors:
| Code | Description |
|---|---|
payment_required | No X-PAYMENT header provided |
payment_invalid | Payment signature is invalid or malformed |
payment_insufficient | Payment amount is less than required |
Example:
{
"success": false,
"error": "Payment amount $0.05 is less than required $0.10",
"code": "payment_insufficient",
"x402Version": 1
}
400 Bad Request
Request validation errors:
| Code | Description |
|---|---|
invalid_request | Request body is malformed or missing required fields |
invalid_parameter | A specific parameter has an invalid value |
404 Not Found
Resource not found errors:
| Code | Description |
|---|---|
agent_not_found | Agent doesn't exist or x402 is not enabled |
command_not_found | Requested command doesn't exist for this agent |
429 Too Many Requests
Rate limiting:
| Code | Description |
|---|---|
rate_limit | Too many requests, try again later |
500+ Server Errors
Internal errors:
| Code | Description |
|---|---|
internal_error | Unexpected server error |
agent_not_ready | Agent wallet not initialized |
Async Job Error Codes
When polling a job status, the failed state includes these codes:
| Code | Description |
|---|---|
generation_timeout | Job took too long to complete |
generation_failed | Generation process failed |
model_unavailable | AI model is temporarily unavailable |
content_filtered | Content moderation was triggered |
quota_exceeded | Rate or quota limit exceeded |
internal_error | Unexpected server error |
Example failed job:
{
"state": "failed",
"error": "Model timeout generating image",
"code": "generation_timeout"
}
Handling Errors
JavaScript
const response = await fetch(url, options);
const data = await response.json();
if (!response.ok) {
switch (data.code) {
case "payment_required":
// Create and attach payment
break;
case "payment_insufficient":
// Increase payment amount
break;
case "agent_not_found":
// Check agent ID
break;
case "rate_limit":
// Wait and retry
await new Promise((r) => setTimeout(r, 5000));
break;
default:
console.error(`Error: ${data.error} (${data.code})`);
}
}
Python
response = requests.post(url, headers=headers, json=body)
data = response.json()
if not response.ok:
code = data.get('code')
if code == 'payment_required':
# Create and attach payment
pass
elif code == 'rate_limit':
time.sleep(5)
# Retry
else:
raise Exception(f"{data['error']} ({code})")
Best Practices
- Always check
successfield - Don't assume HTTP 200 means success - Use
codefor logic - Machine-readable and stable - Log
errorfor debugging - Human-readable context - Implement retries - For
rate_limitandinternal_error - Handle 402 gracefully - Guide users to make payment