Errors
Every API response includes a status code and a JSON payload. Successful requests return success: true; failures return success: false with a descriptive message, error_code, and HTTP status.
Most failures are caused by missing headers, invalid payloads, or exhausted credits. Double-check your request before contacting support.
HTTP Status Codes
PDF-Loom uses standard HTTP status codes combined with specific error codes for precise error identification.
- Name
200- Description
Success. Request processed successfully. The
responsefield contains the signed S3 URL.
- Name
401- Description
Authentication failed. Invalid or missing API credentials.
- Name
402- Description
Payment required. Insufficient credits to complete the request.
- Name
403- Description
Forbidden. Token lacks required scope for this endpoint.
- Name
409- Description
Conflict. Duplicate idempotency key currently in flight or recently completed.
- Name
422- Description
Unprocessable entity. Validation error or processing failure.
- Name
429- Description
Too many requests. Rate limit exceeded (60 requests/minute per token).
- Name
500- Description
Internal server error. Unexpected system failure.
- Name
503- Description
Service unavailable. Generator temporarily unavailable (circuit breaker open).
Generator Error Codes
When PDF or screenshot generation fails, the API returns specific error codes to help diagnose issues.
Authentication Errors (401)
AUTH-001: Missing API Key
Cause: The generator service did not receive the required X-API-Key header (internal configuration error).
Resolution: This indicates a server configuration issue. Contact support at support@pdfloom.com with your request ID.
Example:
{
"success": false,
"error_code": "AUTH-001",
"message": "Missing X-API-Key header",
"details": "Authentication required"
}
AUTH-002: Invalid API Key
Cause: The provided API key does not match the generator's expected key (internal configuration error).
Resolution: This indicates a server configuration issue. Contact support at support@pdfloom.com with your request ID.
Example:
{
"success": false,
"error_code": "AUTH-002",
"message": "Invalid X-API-Key",
"details": "Authentication failed"
}
Processing Errors (422)
PDF-001: PDF Generation Failed
Cause: The PDF generation process failed due to:
- Timeout waiting for page load
- Invalid HTML structure
- Chromium crash during rendering
- Memory exhaustion
- Complex CSS transforms/animations
Resolution:
- Reduce HTML complexity and file size
- Increase timeout value in
engine_options.timeoutparameter - Validate HTML structure
- Simplify CSS (avoid complex transforms, animations, or large images)
- Test the HTML in a browser first
Example:
{
"success": false,
"error_code": "PDF-001",
"message": "PDF generation timed out after 30s",
"details": "Page did not finish loading within timeout period"
}
SCREENSHOT-001: Screenshot Failed
Cause: Screenshot capture failed due to:
- Invalid image format requested
- Page rendering issues
- Chromium crash
- Viewport configuration errors
- Resource loading timeout
Resolution:
- Use supported formats: png, jpeg, webp
- Verify viewport dimensions are reasonable
- Check that the page renders correctly in a browser
- Simplify page content
Example:
{
"success": false,
"error_code": "SCREENSHOT-001",
"message": "Screenshot capture failed",
"details": "Invalid viewport configuration"
}
DOC-001: Unsupported File Type
Cause: The document file type cannot be converted by LibreOffice.
Supported formats:
- Word: .doc, .docx, .rtf
- Excel: .xls, .xlsx, .csv
- PowerPoint: .ppt, .pptx
- OpenDocument: .odt, .ods, .odp
Resolution: Convert your file to a supported format before uploading.
Example:
{
"success": false,
"error_code": "DOC-001",
"message": "Unsupported file type: .pages",
"details": "Only Office and OpenDocument formats are supported"
}
DOC-002: Document Conversion Failed
Cause: LibreOffice conversion failed due to:
- Corrupted file
- File too large (> 50 MB)
- Incompatible document features (macros, embedded objects)
- LibreOffice crash
- Font rendering issues
Resolution:
- Verify the file is not corrupted (open it locally first)
- Reduce file size (compress images, remove unused content)
- Simplify document (remove macros, embedded objects, complex formatting)
- Ensure fonts used are standard/common
Example:
{
"success": false,
"error_code": "DOC-002",
"message": "Document conversion failed",
"details": "LibreOffice crashed during conversion"
}
Service Errors (503)
RETRY_EXHAUSTED: All Retries Failed
Cause: The generator service failed multiple times and exhausted all retry attempts (3 retries).
Resolution:
- Check generator service health status
- Verify network connectivity
- Wait a few moments and try again
- Contact support if the issue persists
Example:
{
"success": false,
"error_code": "RETRY_EXHAUSTED",
"message": "Generator service unavailable after 3 attempts",
"details": "Connection timeout"
}
SERVICE_UNAVAILABLE: Circuit Breaker Open
Cause: The generator service has experienced too many failures and the circuit breaker is open to prevent cascading failures.
Resolution:
- Wait for the circuit breaker to reset (typically 30-60 seconds)
- Check the service status page
- Monitor for systematic issues
- Implement exponential backoff in your retry logic
Example:
{
"success": false,
"error_code": "SERVICE_UNAVAILABLE",
"message": "Generator service is temporarily unavailable",
"retry_after": 30
}
Application Error Codes
In addition to generator errors, the API may return these application-level error codes:
- Name
PAYMENT_REQUIRED- Description
HTTP 402 - Insufficient credits to complete the request. Purchase more credits or reduce file size.
- Name
INSUFFICIENT_SCOPE- Description
HTTP 403 - Token lacks required scope for this endpoint. Create a new token with the correct permissions.
- Name
FILE_TOO_SMALL- Description
HTTP 500 - Generated file is corrupt or empty (< 100 bytes). This usually indicates a generator error.
- Name
S3_UPLOAD_MISSING- Description
HTTP 500 - S3 file upload not found after multiple retries. The generator may have failed to upload.
- Name
CONVERSION_FAILED- Description
HTTP 500 - Generic conversion failure. Check the
categoryfield for details.
Error Response Format
All error responses follow this structure:
{
"success": false,
"error_code": "ERROR_CODE",
"message": "Human-readable error message",
"details": "Additional technical details (optional)"
}
Response Fields
success(boolean): Alwaysfalsefor errorserror_code(string): Specific error code (see sections above)message(string): User-friendly error descriptiondetails(string, optional): Technical details for debugging
Some errors include additional context fields:
{
"success": false,
"error_code": "PAYMENT_REQUIRED",
"message": "Insufficient credits",
"available_credits": 0,
"required_credits": 2
}
Retry Behavior
The API automatically retries certain errors to improve reliability:
Retried Errors (up to 3 attempts with exponential backoff):
- Network timeouts
- Temporary service unavailability (5xx errors)
- Transient connection failures
Not Retried (returned immediately):
- Authentication errors (AUTH-001, AUTH-002)
- Unsupported file types (DOC-001)
- Processing failures (PDF-001, SCREENSHOT-001, DOC-002)
- Validation errors (422)
- Insufficient credits (402)
Retry Configuration:
- Maximum attempts: 3
- Backoff strategy: Exponential (250ms, 500ms, 750ms)
Common Scenarios
402 – Insufficient Credits
Triggered when CreditService cannot lock enough credits to complete the job. The response includes your current balance and credits required:
{
"success": false,
"error_code": "PAYMENT_REQUIRED",
"message": "Insufficient credits.",
"available_credits": 0,
"required_credits": 2
}
Fix: Purchase more credits or reduce file size (smaller HTML/assets, lower DPI). Check your balance using the GET /v1/account/credits endpoint.
403 – Insufficient Scope
Returned when your API token lacks the required scope for the endpoint you're trying to access.
{
"success": false,
"error_code": "INSUFFICIENT_SCOPE",
"message": "This token does not have the required scope: convert:pdf",
"required_scope": "convert:pdf",
"token_scopes": ["read:credits", "read:requests"]
}
Fix: Create a new token with the required scope or use an existing token with the necessary permissions. See Token Scopes for details.
409 – Idempotency Key in Use
Raised when you reuse an Idempotency-Key while the original request is still processing.
{
"success": false,
"message": "This idempotency key is already being processed.",
"status": 409
}
Fix: Wait for the original request to finish or send a new UUID.
422 – Validation Error
Example: missing content or invalid callback_url.
{
"success": false,
"message": "The content field is required.",
"status": 422,
"details": {
"content": ["The content field is required."]
}
}
Fix: Inspect the details object and conform to the field requirements listed in the Convert and Screenshot documentation.
Debugging Tips
1. Check Error Code First
The error_code field tells you exactly what went wrong. Use it to narrow down the issue quickly.
2. Read the Details Field
The details field often contains technical information useful for debugging:
- Stack traces
- Specific validation failures
- Generator logs
- Resource paths
3. Common Issues by Error Code
AUTH-001 or AUTH-002 → Internal configuration issue. Contact support - this is not a problem with your request.
PDF-001 with timeout message
→ Increase timeout in engine_options.timeout parameter or simplify HTML/CSS.
DOC-001 → Wrong file type. Check the supported formats list above.
SERVICE_UNAVAILABLE → Temporary issue. Wait 30-60 seconds and retry with exponential backoff.
PAYMENT_REQUIRED → Purchase credits or reduce file size to consume fewer credits.
4. Enable Debug Logging
Log all API responses (including error details) to help diagnose issues:
console.log('Error:', {
code: response.error_code,
message: response.message,
details: response.details
});
Example Error Handling
async function convertToPdf(html) {
try {
const response = await fetch('https://api.pdfloom.com/v1/convert/html', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: html,
options: { format: 'A4' }
})
});
const data = await response.json();
if (!data.success) {
// Handle specific error codes
switch (data.error_code) {
case 'PDF-001':
console.error('PDF generation failed:', data.message);
console.error('Details:', data.details);
// Maybe retry with simpler HTML or increased timeout
break;
case 'DOC-001':
console.error('Unsupported file type:', data.message);
// Show user error about file format
break;
case 'PAYMENT_REQUIRED':
console.error('Insufficient credits:', data.message);
// Redirect user to purchase credits
break;
case 'SERVICE_UNAVAILABLE':
console.error('Service unavailable:', data.message);
// Implement exponential backoff retry
const retryAfter = data.retry_after || 30;
setTimeout(() => convertToPdf(html), retryAfter * 1000);
break;
case 'AUTH-001':
case 'AUTH-002':
console.error('Server configuration error:', data.message);
// Contact support - this is not a client issue
break;
default:
console.error('Unknown error:', data.error_code, data.message);
}
return null;
}
return data.response; // S3 presigned URL
} catch (error) {
console.error('Network error:', error);
// Handle network failures
return null;
}
}
Need Help?
If you encounter an error not covered here, email support@pdfloom.com with:
- Your request ID (from dashboard logs)
- The error code and message
- The request payload (sanitized)
- Timestamp of the error
We typically respond within 24 hours.