Rate Limits
Understand API rate limits and how to handle them.
Rate Limits
PDF API implements rate limiting to ensure fair usage and maintain service quality for all users. Rate limits vary by plan.
Rate Limit Tiers
| Plan | Requests/Min | Monthly PDFs | Concurrent Requests |
|---|---|---|---|
| Free | 3 | 10 | 1 |
| Pro | 30 | 3,000 | 5 |
| Business | 60 | 15,000 | 10 |
| Enterprise | 120 | Unlimited | 25 |
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1705591200
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the rate limit resets |
Monthly Quota
Your monthly PDF generation quota resets on the 1st of each month at 00:00 UTC. You can check your current usage via the Usage endpoint or in your dashboard.
Handling Rate Limits
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"details": {
"limit": 3,
"window": "1 minute",
"retry_after": 45
}
}
}
Best Practices
- Check headers: Monitor
X-RateLimit-Remainingto avoid hitting limits - Implement backoff: Use exponential backoff when you receive a 429 response
- Queue requests: For batch operations, queue requests and process them gradually
- Use webhooks: For high-volume use cases, consider our webhook support (Enterprise)
Example: Retry with Backoff
async function generatePDFWithRetry(markdown, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
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 }),
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Retrying in ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return await response.arrayBuffer();
}
throw new Error('Max retries exceeded');
}
Monthly Limit Exceeded
When you exceed your monthly quota, the API returns:
{
"error": {
"code": "MONTHLY_LIMIT_EXCEEDED",
"message": "Monthly PDF limit exceeded",
"details": {
"limit": 10,
"used": 10,
"resets_at": "2025-02-01T00:00:00Z"
}
}
}
To continue generating PDFs, you can:
- Wait for the monthly reset
- Upgrade your plan
Need Higher Limits?
If you need higher rate limits or custom quotas, contact us about our Enterprise plan.