Error Handling
Error codes, response format, and troubleshooting guidance.
Error Response Format
All errors return a consistent JSON body alongside the appropriate HTTP status code:
{
"error": {
"code": "rate_limit_exceeded",
"message": "You have exceeded 60 requests per minute. Please wait and retry.",
"status": 429,
"retry_after": 12
}
}The retry_after field (in seconds) is included for 429 and 503 responses.
Error Codes
| Code | Status | Description |
|---|---|---|
| invalid_api_key | 401 | The API key is malformed or does not exist. |
| expired_api_key | 401 | The API key has passed its expiration date. |
| revoked_api_key | 401 | The API key has been manually revoked. |
| insufficient_scope | 403 | The key's scope does not permit this endpoint. |
| ip_not_allowed | 403 | The request IP is not in the key's allowlist. |
| subscription_required | 403 | A paid subscription is required for this feature. |
| rate_limit_exceeded | 429 | Too many requests in the current time window. |
| quota_exceeded | 429 | Daily or weekly usage quota has been reached. |
| file_too_large | 413 | The uploaded file exceeds the maximum allowed size. |
| unsupported_format | 422 | The requested input or output format is not supported. |
| invalid_request | 422 | The request body is missing required fields or contains invalid values. |
| job_not_found | 404 | No job exists with the provided ID. |
| processing_error | 500 | An unexpected error occurred during file processing. |
| service_unavailable | 503 | The service is temporarily unavailable. Retry after a short delay. |
Handling Errors in Code
Always check the HTTP status code and parse the error body for programmatic handling. Here is a JavaScript example:
async function convertFile(file, outputFormat) {
const form = new FormData();
form.append('file', file);
form.append('output_format', outputFormat);
const res = await fetch('https://api.docuhub.live/v1/convert', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.DOCUHUB_API_KEY}` },
body: form,
});
if (!res.ok) {
const { error } = await res.json();
switch (error.code) {
case 'rate_limit_exceeded':
// Wait and retry
await sleep(error.retry_after * 1000);
return convertFile(file, outputFormat);
case 'file_too_large':
throw new Error('File exceeds the maximum size limit.');
case 'invalid_api_key':
case 'expired_api_key':
case 'revoked_api_key':
throw new Error('API key is invalid. Check your credentials.');
default:
throw new Error(`API error: ${error.message}`);
}
}
return res.json();
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}