Error Handling
doczap uses standard HTTP status codes and returns JSON error objects for all API errors.
Error Response Format
All errors follow this structure:
{
"error": {
"message": "Human-readable error description",
"type": "error_category",
"code": "specific_error_code",
"field": "field_name" // Optional, for validation errors
}
}
HTTP Status Codes
Status | Meaning | Common Causes |
---|---|---|
200 | Success | Request completed successfully |
202 | Accepted | Async request queued |
400 | Bad Request | Invalid JSON or missing fields |
401 | Unauthorized | Invalid or missing API key |
404 | Not Found | Template or resource doesn’t exist |
413 | Payload Too Large | Request body exceeds 1MB |
422 | Unprocessable Entity | Validation failed |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected error |
503 | Service Unavailable | Temporary outage |
Common Error Types
Authentication Errors (401)
{
"error": {
"message": "Invalid API key provided",
"type": "authentication_error",
"code": "invalid_api_key"
}
}
Code | Description |
---|---|
missing_api_key | No Authorization header |
invalid_api_key | Malformed API key |
expired_api_key | Key has been revoked |
unauthorized_org | Key doesn’t match organization |
Validation Errors (422)
{
"error": {
"message": "Validation failed: amount must be a number",
"type": "validation_error",
"code": "invalid_type",
"field": "amount"
}
}
Code | Description |
---|---|
missing_required_field | Required field not provided |
invalid_type | Wrong data type |
invalid_format | Format doesn’t match schema |
invalid_value | Value outside allowed range |
Rate Limit Errors (429)
{
"error": {
"message": "Monthly render limit exceeded",
"type": "rate_limit_error",
"code": "monthly_limit_exceeded",
"retry_after": 1234567890
}
}
Code | Description |
---|---|
test_limit_exceeded | Daily test limit (10) reached |
monthly_limit_exceeded | Monthly plan limit reached |
concurrent_limit_exceeded | Too many simultaneous requests |
Resource Errors (404)
{
"error": {
"message": "Template not found: invoice",
"type": "resource_error",
"code": "template_not_found"
}
}
Code | Description |
---|---|
template_not_found | Template doesn’t exist |
org_not_found | Organization doesn’t exist |
document_not_found | Document ID not found |
Error Handling Best Practices
1. Implement Exponential Backoff
For rate limits and server errors:
async function requestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);
if (response.status === 429 || response.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
return response;
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
}
2. Parse Error Details
Always check for error details:
response = requests.post(url, json=data)
if not response.ok:
error = response.json().get('error', {})
error_code = error.get('code')
if error_code == 'monthly_limit_exceeded':
# Upgrade plan or wait
pass
elif error_code == 'validation_failed':
# Fix the data
field = error.get('field')
print(f"Invalid field: {field}")
3. Handle Specific Errors
try {
const response = await generatePDF(data);
} catch (error) {
switch (error.code) {
case 'test_limit_exceeded':
console.log('Test limit reached, switching to production mode');
delete data.isTest;
break;
case 'template_not_found':
console.log('Check template endpoint path');
break;
case 'invalid_api_key':
console.log('Refresh API key from dashboard');
break;
default:
console.error('Unexpected error:', error.message);
}
}
Webhook Errors
For async requests, errors are sent to your webhook:
{
"event": "document.failed",
"data": {
"request_id": "req_abc123",
"error": {
"message": "PDF generation failed",
"type": "generation_error",
"code": "render_timeout"
}
}
}
Always log the request ID (X-Request-ID
header) for debugging with support.
Debug Mode
Add debug headers to get more detailed errors (development only):
curl -X POST https://api.doczap.app/api/v1/... \
-H "X-Debug-Mode: true" \
-H "Authorization: Bearer sk_live_..."
This returns additional debugging information:
{
"error": {
"message": "Validation failed",
"type": "validation_error",
"code": "schema_mismatch",
"debug": {
"schema_errors": [...],
"received_fields": [...],
"expected_fields": [...]
}
}
}