Error Codes
Complete reference of API error codes and their meanings.
Error Codes
PDF API uses standard HTTP status codes along with detailed error objects to help you identify and resolve issues.
Error Response Format
All errors follow this structure:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
// Additional context (optional)
}
}
}
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 400 | Bad Request | Invalid request body or parameters |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Feature not available on your plan |
| 404 | Not Found | Resource does not exist |
| 429 | Too Many Requests | Rate limit or quota exceeded |
| 500 | Internal Server Error | Server-side error |
400 Bad Request
INVALID_REQUEST
The request body is malformed or missing required fields.
{
"error": {
"code": "INVALID_REQUEST",
"message": "Request body must be valid JSON"
}
}
VALIDATION_ERROR
Request parameters failed validation.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Markdown content is required",
"details": {
"field": "markdown",
"reason": "required"
}
}
}
Common validation errors:
| Field | Error | Solution |
|---|---|---|
markdown | required | Provide markdown content |
html | required | Provide HTML content |
url | invalid | Use a valid URL starting with http:// or https:// |
options.format | invalid | Use a supported format (A4, Letter, etc.) |
options.margin | invalid | Use valid CSS units (mm, cm, in, px) |
401 Unauthorized
UNAUTHORIZED
Authentication failed. The API key is missing, invalid, or revoked.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}
Common causes:
- Missing
Authorizationheader - Incorrect
Bearerprefix - API key typo
- Revoked or deleted key
Solution: Verify your API key in the dashboard.
403 Forbidden
THEME_NOT_AVAILABLE
Attempted to use a premium theme on a plan that doesn't support it.
{
"error": {
"code": "THEME_NOT_AVAILABLE",
"message": "Theme 'invoice' requires a Pro plan or higher",
"details": {
"theme": "invoice",
"required_plan": "pro"
}
}
}
TEMPLATE_NOT_AVAILABLE
Attempted to use a premium template on a plan that doesn't support it.
{
"error": {
"code": "TEMPLATE_NOT_AVAILABLE",
"message": "Template 'contract' requires a Business plan or higher",
"details": {
"template": "contract",
"required_plan": "business"
}
}
}
Solution: Upgrade your plan or use a theme/template available on your current plan.
404 Not Found
NOT_FOUND
The requested resource does not exist.
{
"error": {
"code": "NOT_FOUND",
"message": "API key not found"
}
}
429 Too Many Requests
RATE_LIMIT_EXCEEDED
You've exceeded the per-minute rate limit.
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"details": {
"limit": 3,
"window": "1 minute",
"retry_after": 45
}
}
}
Solution: Wait for the retry_after seconds before retrying. See Rate Limits for details.
MONTHLY_LIMIT_EXCEEDED
You've exceeded your monthly PDF generation quota.
{
"error": {
"code": "MONTHLY_LIMIT_EXCEEDED",
"message": "Monthly PDF limit exceeded",
"details": {
"limit": 10,
"used": 10,
"resets_at": "2025-02-01T00:00:00Z"
}
}
}
Solution: Wait for the monthly reset or upgrade your plan.
500 Internal Server Error
CONVERSION_ERROR
Markdown conversion to HTML failed.
{
"error": {
"code": "CONVERSION_ERROR",
"message": "Failed to convert markdown to HTML"
}
}
PDF_GENERATION_ERROR
PDF generation failed, typically due to rendering issues.
{
"error": {
"code": "PDF_GENERATION_ERROR",
"message": "Failed to generate PDF",
"details": {
"reason": "Page load timeout"
}
}
}
Common causes:
- External resources (images, fonts) failed to load
- JavaScript errors on the page
- Page load timeout for URL conversions
TEMPLATE_ERROR
Template rendering failed.
{
"error": {
"code": "TEMPLATE_ERROR",
"message": "Failed to render template",
"details": {
"reason": "Missing required variable: customerName"
}
}
}
INTERNAL_ERROR
An unexpected server error occurred.
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}
Solution: Retry the request. If the error persists, contact support.
Error Handling Best Practices
- Always check the status code before processing the response
- Parse error details to provide helpful feedback to users
- Implement retry logic for transient errors (429, 500)
- Log errors for debugging and monitoring
- Don't expose raw errors to end users
async function generatePDF(content) {
const response = await fetch('https://api.pdfapi.dev/v1/pdf/markdown', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDFAPI_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ markdown: content }),
});
if (!response.ok) {
const { error } = await response.json();
switch (error.code) {
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
break;
case 'VALIDATION_ERROR':
// Fix input and retry
throw new Error(`Invalid input: ${error.message}`);
case 'UNAUTHORIZED':
// Check API key
throw new Error('API key is invalid');
default:
throw new Error('PDF generation failed');
}
}
return response.arrayBuffer();
}