Error Handling
Understanding and handling API errors.
Error Response Format
All errors follow this structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
}
}
Error Codes
Authentication Errors
| Code | Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key |
INVALID_TOKEN | 401 | Expired or malformed JWT token |
FORBIDDEN | 403 | Insufficient permissions |
Example:
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key provided"
}
}
Validation Errors
| Code | Status | Description |
|---|---|---|
VALIDATION_ERROR | 400 | Invalid request parameters |
INVALID_TEMPLATE | 400 | Template doesn't exist |
MISSING_FIELD | 400 | Required field is missing |
INVALID_FORMAT | 400 | Invalid data format |
Example:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Field 'title' is required for blog template"
}
}
Rate Limit Errors
| Code | Status | Description |
|---|---|---|
RATE_LIMIT_EXCEEDED | 429 | Too many requests |
Example:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 60 seconds."
}
}
Headers included:
Retry-After: 60
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704067260
Resource Errors
| Code | Status | Description |
|---|---|---|
NOT_FOUND | 404 | Resource not found |
QUOTA_EXCEEDED | 402 | Monthly quota exceeded |
Server Errors
| Code | Status | Description |
|---|---|---|
INTERNAL_ERROR | 500 | Unexpected server error |
SERVICE_UNAVAILABLE | 503 | Temporary maintenance |
Handling Errors
JavaScript Example
async function generateOgImage(data) {
const response = await fetch('https://ssiat.dev/api/v1/og/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
const result = await response.json();
if (!result.success) {
switch (result.error.code) {
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
const retryAfter = response.headers.get('Retry-After');
await sleep(parseInt(retryAfter) * 1000);
return generateOgImage(data);
case 'VALIDATION_ERROR':
// Log and use fallback
console.error('Invalid data:', result.error.message);
return FALLBACK_IMAGE;
case 'UNAUTHORIZED':
// Check API key
throw new Error('Invalid API key');
default:
// Generic error handling
console.error('API error:', result.error);
return FALLBACK_IMAGE;
}
}
return result.data.url;
}
Python Example
import requests
import time
def generate_og_image(data, retries=3):
response = requests.post(
'https://ssiat.dev/api/v1/og/generate',
headers={'Authorization': f'Bearer {api_key}'},
json=data
)
result = response.json()
if not result['success']:
error = result['error']
if error['code'] == 'RATE_LIMIT_EXCEEDED' and retries > 0:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
return generate_og_image(data, retries - 1)
raise Exception(f"API Error: {error['message']}")
return result['data']['url']
Best Practices
- Always check
successfield before using response data - Implement retry logic for rate limits and temporary errors
- Log errors with full context for debugging
- Use fallback images when generation fails
- Handle timeouts (recommend 30 second timeout)