Overview
The RunAgent API uses standard HTTP status codes and returns detailed error information in a consistent format. This guide covers common errors and how to handle them.
All errors follow this structure:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "Additional context"
},
"request_id": "req_abc123",
"documentation_url": "https://docs.run-agent.ai/errors/ERROR_CODE"
}
}
HTTP Status Codes
Status | Meaning | Common Causes |
---|
200 | Success | Request completed successfully |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid parameters or malformed request |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource doesn’t exist |
409 | Conflict | Resource already exists |
422 | Unprocessable | Valid syntax but semantic errors |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Error | Server-side error |
503 | Service Unavailable | Temporary maintenance |
Common Error Codes
Authentication Errors
INVALID_API_KEY
{
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is invalid",
"status": 401
}
}
Solution: Check your API key format and ensure it’s correct.
EXPIRED_API_KEY
{
"error": {
"code": "EXPIRED_API_KEY",
"message": "The API key has expired",
"status": 401
}
}
Solution: Generate a new API key from the dashboard.
Validation Errors
MISSING_REQUIRED_FIELD
{
"error": {
"code": "MISSING_REQUIRED_FIELD",
"message": "Required field 'query' is missing",
"details": {
"field": "query",
"requirement": "string, min length 1"
},
"status": 400
}
}
INVALID_FIELD_TYPE
{
"error": {
"code": "INVALID_FIELD_TYPE",
"message": "Field 'temperature' must be a number",
"details": {
"field": "temperature",
"provided": "string",
"expected": "number"
},
"status": 400
}
}
Resource Errors
AGENT_NOT_FOUND
{
"error": {
"code": "AGENT_NOT_FOUND",
"message": "Agent with ID 'agent-123' not found",
"details": {
"agent_id": "agent-123"
},
"status": 404
}
}
DEPLOYMENT_FAILED
{
"error": {
"code": "DEPLOYMENT_FAILED",
"message": "Failed to deploy agent",
"details": {
"reason": "Invalid configuration",
"validation_errors": ["Missing entrypoint"]
},
"status": 422
}
}
Rate Limiting
RATE_LIMIT_EXCEEDED
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API rate limit exceeded",
"details": {
"limit": 100,
"remaining": 0,
"reset_at": "2024-01-01T00:00:00Z"
},
"status": 429
}
}
Server Errors
INTERNAL_ERROR
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "req_xyz789",
"status": 500
}
}
Error Handling Best Practices
Python Example
import requests
from time import sleep
def call_api_with_retry(url, data, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.post(url, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
# Rate limited - wait and retry
retry_after = int(e.response.headers.get('Retry-After', 60))
sleep(retry_after)
continue
elif e.response.status_code >= 500:
# Server error - retry with backoff
if attempt < max_retries - 1:
sleep(2 ** attempt)
continue
# Don't retry client errors (4xx)
error_data = e.response.json()
raise Exception(f"API Error: {error_data['error']['message']}")
except requests.exceptions.RequestException as e:
# Network error - retry
if attempt < max_retries - 1:
sleep(2 ** attempt)
continue
raise
raise Exception("Max retries exceeded")
JavaScript Example
async function callAPIWithRetry(url, data, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify(data)
});
if (!response.ok) {
const error = await response.json();
if (response.status === 429) {
// Rate limited
const retryAfter = response.headers.get('Retry-After') || 60;
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
if (response.status >= 500 && attempt < maxRetries - 1) {
// Server error - retry with exponential backoff
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
continue;
}
throw new Error(error.error.message);
}
return await response.json();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
// Network error - retry
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
}
}
}
Debugging Errors
Request ID
Every error includes a request_id
for debugging:
# Contact support with request ID
"request_id": "req_abc123xyz"
Detailed Logging
Enable detailed logging in SDKs:
import logging
logging.basicConfig(level=logging.DEBUG)
# Now SDK will log all requests/responses
client = RunAgentClient(agent_id="...", debug=True)
Common Solutions
-
400 Bad Request
- Validate JSON syntax
- Check required fields
- Verify data types
-
401 Unauthorized
- Check API key format
- Verify key hasn’t expired
- Ensure proper header format
-
429 Rate Limited
- Implement exponential backoff
- Check rate limit headers
- Consider upgrading plan
-
500 Internal Error
- Retry with backoff
- Check status page
- Contact support if persistent
Webhook Error Handling
For webhook endpoints, implement proper error handling:
@app.post("/webhook")
async def handle_webhook(request):
try:
# Process webhook
data = await request.json()
process_webhook(data)
return {"status": "success"}
except ValidationError:
# Return 400 for validation errors
return JSONResponse(
status_code=400,
content={"error": "Invalid webhook data"}
)
except Exception as e:
# Return 500 for server errors
# RunAgent will retry 500 errors
return JSONResponse(
status_code=500,
content={"error": "Internal error"}
)
See Also