Error Handling
Understand API errors and how to handle them gracefully
Error Response Format
All API errors follow a consistent JSON structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "Additional context about the error"
}
}
}
HTTP Status Codes
400
Bad Request
The request was malformed or missing required parameters.
Example
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"title": ["The title field is required."],
"payment_per_submission": ["Must be at least 0.01"]
}
}
}
How to Fix
Check all required parameters are included and properly formatted. Review the endpoint documentation for parameter requirements.
401
Unauthorized
Invalid or missing API credentials.
Example
{
"success": false,
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Invalid API key or secret"
}
}
How to Fix
Verify your X-API-Key and X-API-Secret headers are correct. Check for typos and ensure you're using active (not expired) credentials.
403
Forbidden
You don't have permission to access this resource or your quota is exceeded.
Example
{
"success": false,
"error": {
"code": "QUOTA_EXCEEDED",
"message": "Monthly budget limit exceeded",
"details": {
"limit": 5000.00,
"used": 5150.00
}
}
}
How to Fix
Check your account limits and upgrade your tier if needed. For permission errors, ensure your account type allows this operation.
404
Not Found
The requested resource doesn't exist.
Example
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Content request with ID 999 not found"
}
}
How to Fix
Verify the resource ID exists and belongs to your account. Check for typos in the endpoint URL.
429
Too Many Requests
You've exceeded your rate limit. Wait and retry after the specified time.
Example
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 45 seconds.",
"retry_after": 45
}
}
How to Fix
Wait for the retry_after seconds before making another request. Implement exponential backoff. Consider upgrading your tier.
500
Internal Server Error
An unexpected error occurred on our servers.
Example
{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred. Please try again."
}
}
How to Fix
Retry the request after a short delay. If the error persists, contact support@opttab.com with the request details.
Common Error Codes
| Code | Description | HTTP Status |
|---|---|---|
INVALID_CREDENTIALS |
Invalid API key or secret | 401 |
VALIDATION_ERROR |
Request validation failed | 400 |
RESOURCE_NOT_FOUND |
Requested resource doesn't exist | 404 |
RATE_LIMIT_EXCEEDED |
Too many requests | 429 |
INSUFFICIENT_BUDGET |
Not enough budget for operation | 403 |
QUOTA_EXCEEDED |
Monthly quota limit exceeded | 403 |
PERMISSION_DENIED |
Account type doesn't allow this action | 403 |
INTERNAL_ERROR |
Unexpected server error | 500 |
Handling Errors in Code
Python Example
import requests
def handle_opttab_request(url, headers, data=None):
try:
if data:
response = requests.post(url, json=data, headers=headers)
else:
response = requests.get(url, headers=headers)
# Check for errors
if not response.ok:
error_data = response.json()
error_code = error_data.get('error', {}).get('code')
error_message = error_data.get('error', {}).get('message')
if response.status_code == 429:
retry_after = error_data.get('error', {}).get('retry_after', 60)
print(f"Rate limited. Retry after {retry_after}s")
time.sleep(retry_after)
return handle_opttab_request(url, headers, data) # Retry
elif response.status_code == 401:
raise Exception(f"Authentication failed: {error_message}")
elif response.status_code == 400:
details = error_data.get('error', {}).get('details', {})
raise Exception(f"Validation error: {details}")
else:
raise Exception(f"API error ({error_code}): {error_message}")
return response.json()
except requests.exceptions.RequestException as e:
print(f"Network error: {e}")
raise
# Usage
try:
result = handle_opttab_request(
"https://opttab.com/api/v1/ai/budget-status",
{"X-API-Key": "...", "X-API-Secret": "..."}
)
print(result)
except Exception as e:
print(f"Error: {e}")
JavaScript Example
async function makeOpttabRequest(url, options = {}) {
try {
const response = await fetch(url, {
...options,
headers: {
'X-API-Key': process.env.OPTTAB_API_KEY,
'X-API-Secret': process.env.OPTTAB_API_SECRET,
'Content-Type': 'application/json',
...options.headers
}
});
const data = await response.json();
if (!response.ok) {
const error = data.error || {};
switch (response.status) {
case 429:
const retryAfter = error.retry_after || 60;
console.log(`Rate limited. Retry after ${retryAfter}s`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return makeOpttabRequest(url, options); // Retry
case 401:
throw new Error(`Authentication failed: ${error.message}`);
case 400:
throw new Error(`Validation error: ${JSON.stringify(error.details)}`);
default:
throw new Error(`API error (${error.code}): ${error.message}`);
}
}
return data;
} catch (error) {
console.error('API request failed:', error);
throw error;
}
}
// Usage
try {
const result = await makeOpttabRequest('https://opttab.com/api/v1/ai/budget-status');
console.log(result);
} catch (error) {
console.error(error.message);
}
Best Practices
Always Check Response Status
Don't assume requests succeed. Always check the success field and handle errors appropriately.
Log Error Details
Log error codes and details for debugging. Include request IDs if provided in error responses.
Implement Retry Logic
For 429 and 500 errors, implement exponential backoff retry logic with maximum retry limits.
Handle Network Errors
Catch network timeouts and connection errors separately from API errors.