All API errors follow a consistent JSON format:
{
"code": 400,
"message": "Invalid request: missing required field 'input'",
"error_type": "validation_error",
"details": {
"field": "input",
"reason": "required"
},
"request_id": "req_abc123xyz"
}| Error Type | Description | Action |
|---|---|---|
authentication_error | Invalid or missing API token | Check your token is correct and not expired |
authorization_error | Token lacks required permissions | Ensure you have purchased the skill |
validation_error | Request data failed validation | Check required fields and data types |
not_found_error | Requested resource not found | Verify the skill slug or ID exists |
rate_limit_error | Too many requests | Implement exponential backoff |
execution_error | Skill execution failed | Check skill input format and try again |
internal_error | Server-side error | Retry with exponential backoff |
{
"code": 401,
"message": "Invalid or expired API token",
"error_type": "authentication_error"
}{
"code": 403,
"message": "You have not purchased this skill",
"error_type": "authorization_error",
"details": {
"skill_slug": "premium-analyzer"
}
}{
"code": 422,
"message": "Validation failed",
"error_type": "validation_error",
"details": {
"errors": [
{"field": "input.text", "message": "Required field missing"}
]
}
}{
"code": 429,
"message": "Rate limit exceeded",
"error_type": "rate_limit_error",
"details": {
"limit": 100,
"window": "1m",
"retry_after": 45
}
}Don't assume success. Check HTTP status codes and handle errors appropriately.
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${error.message}`);
}
const data = await response.json();For transient errors (5xx, 429), implement exponential backoff.
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.ok) return response.json();
if (response.status === 429 || response.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, delay));
continue;
}
throw new Error(`API Error: ${response.status}`);
}
throw new Error('Max retries exceeded');
}Always log the request_id from error responses for debugging.
try {
const result = await executeSkill(input);
} catch {
console.error('Skill execution failed', {
message: error.message,
request_id: error.request_id, // Include in support tickets
timestamp: new Date().toISOString()
});
}100
requests / minute
1,000
requests / minute
Custom
Contact sales
Rate Limit Headers
Check X-RateLimit-Remaining and X-RateLimit-Reset headers to monitor your usage.