Error Handling
Understand API error codes and how to handle them gracefully.
Error Response Format
CheapAI errors are not fully uniform across every endpoint, but you will usually receive either a simple service error or a structured error payload.
{
"success": false,
"error": "Human-readable error description"
}{
"error": {
"message": "Human-readable error description",
"type": "error_type"
}
}HTTP Status Codes
Invalid request body, missing required fields, or invalid parameter values.
Fix: Check your request body matches the API spec.
Missing, invalid, or expired API key.
Fix: Verify the key and bearer header. Replace expired keys in the dashboard.
Your account balance is too low for this request.
Fix: Top up your balance at /billing.
The key is not allowed to access a specific action or model.
Fix: Check the request and key configuration.
Too many requests or the API key reached its daily spend limit.
Fix: Back off and inspect the key settings in the dashboard.
Something went wrong on our end.
Fix: Retry after a short delay. If persistent, check /status.
The generation service returned an error while handling the request.
Fix: Retry after a short delay or try a different route if the issue persists.
The service is temporarily overloaded or under maintenance.
Fix: Retry with exponential backoff. Check /status for maintenance windows.
Retry Strategy (Python)
import time
import requests
API_KEY = "sk_your_api_key"
def fetch_with_retry(url, method="GET", payload=None, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.request(
method,
url,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
)
if response.status_code < 400:
return response.json()
if response.status_code in (429, 500, 502, 503):
wait = 2 ** attempt
time.sleep(wait)
continue
response.raise_for_status()
except requests.RequestException:
time.sleep(2 ** attempt)
raise RuntimeError("Max retries exceeded")Retry Strategy (Node.js)
const API_KEY = 'sk_your_api_key';
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, {
...options,
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
...(options.headers || {}),
},
});
if (response.ok) {
return await response.json();
}
if ([429, 500, 502, 503].includes(response.status)) {
const wait = 2 ** attempt * 1000;
await new Promise(r => setTimeout(r, wait));
} else {
throw new Error(`Request failed: ${response.status}`);
}
} catch (err) {
const wait = 2 ** attempt * 1000;
await new Promise(r => setTimeout(r, wait));
}
}
throw new Error('Max retries exceeded');
}Common Mistakes
- Sending
Authorization: sk-keyinstead ofAuthorization: Bearer sk-key - Polling the wrong task endpoint after creation
- Assuming all generation routes are synchronous
- Using an expired key or one that already hit its daily spend cap
- Sending route-specific fields to the wrong route family (
/v1,/v1m,/v1e, or/v1i)