Skip to main content

Error Handling

Error codes, response format, and troubleshooting guidance.

Back to Docs

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

CodeStatusDescription
invalid_api_key401The API key is malformed or does not exist.
expired_api_key401The API key has passed its expiration date.
revoked_api_key401The API key has been manually revoked.
insufficient_scope403The key's scope does not permit this endpoint.
ip_not_allowed403The request IP is not in the key's allowlist.
subscription_required403A paid subscription is required for this feature.
rate_limit_exceeded429Too many requests in the current time window.
quota_exceeded429Daily or weekly usage quota has been reached.
file_too_large413The uploaded file exceeds the maximum allowed size.
unsupported_format422The requested input or output format is not supported.
invalid_request422The request body is missing required fields or contains invalid values.
job_not_found404No job exists with the provided ID.
processing_error500An unexpected error occurred during file processing.
service_unavailable503The 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));
}