Rate Limits
API usage is limited based on your subscription plan to ensure fair usage and service stability.
Monthly Limits by Plan
| Plan | Monthly PDF Limit | Price |
|---|---|---|
| Starter | 300 PDFs | €9/month |
| Pro | 3,000 PDFs | €29/month |
| Scale | 15,000 PDFs | €59/month |
| Enterprise | Unlimited | €99/month |
Understanding Rate Limits
Monthly Quota
The monthly quota is the total number of PDFs you can generate per billing period.
- Resets on the 1st of each month at 00:00 UTC
- Unused quota does not roll over
- Counted per successful PDF generation
Rate Limiting
Rate limits prevent abuse and ensure service availability for all users.
- Measured per minute
- Based on API key
- Returns 429 Too Many Requests when exceeded
Checking Your Usage
Dashboard
View your current usage in the Dashboard:
- Current month's usage
- Remaining quota
- Usage history
Response Headers
Each API response includes usage information:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1704067200
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Remaining requests in the current minute |
X-RateLimit-Reset | Unix timestamp when the rate limit resets |
Rate Limit Errors
403 Forbidden (Quota Exceeded)
Returned when you've used all your monthly quota.
{
"error": "Monthly quota exceeded. Upgrade your plan to continue.",
"code": "QUOTA_EXCEEDED",
"status": 403
}
Solution: Upgrade your plan or wait for the monthly reset.
429 Too Many Requests
Returned when you exceed the per-minute rate limit.
{
"error": "Rate limit exceeded. Try again in 60 seconds.",
"code": "RATE_LIMITED",
"status": 429,
"retryAfter": 60
}
Solution: Implement backoff and retry logic.
Handling Rate Limits
Implement Exponential Backoff
async function generateWithBackoff(templateId, variables, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await generatePDF(templateId, variables);
} catch (error) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await sleep(delay);
continue;
}
throw error;
}
}
}
Queue Requests
For high-volume applications, implement a request queue:
class PDFQueue {
constructor(rateLimit = 60) {
this.queue = [];
this.processing = false;
this.interval = (60 / rateLimit) * 1000; // ms between requests
}
async add(templateId, variables) {
return new Promise((resolve, reject) => {
this.queue.push({ templateId, variables, resolve, reject });
this.process();
});
}
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
const { templateId, variables, resolve, reject } = this.queue.shift();
try {
const result = await generatePDF(templateId, variables);
resolve(result);
} catch (error) {
reject(error);
}
await sleep(this.interval);
}
this.processing = false;
}
}
Monitor Usage
async function generateWithMonitoring(templateId, variables) {
const response = await fetch(url, options);
// Log usage information
const remaining = response.headers.get('X-RateLimit-Remaining');
const limit = response.headers.get('X-RateLimit-Limit');
console.log(`Rate limit: ${remaining}/${limit} remaining`);
if (parseInt(remaining) < 10) {
console.warn('Approaching rate limit!');
}
return response.json();
}
Upgrading Your Plan
If you regularly hit your limits:
- Go to Billing in the dashboard
- Select a higher tier plan
- Your new limits apply immediately
Enterprise Plans
Need higher limits or custom solutions? Contact us to discuss enterprise options.
Best Practices
1. Cache When Possible
Don't regenerate PDFs if the content hasn't changed. Cache generated PDF URLs.
2. Batch Processing
If you need to generate many PDFs, spread them over time rather than all at once.
3. Monitor Proactively
Set up alerts when you approach your monthly quota (e.g., at 80% usage).
4. Use Webhooks
For high-volume use cases, consider implementing webhooks instead of polling.
5. Optimize Templates
Simpler templates generate faster, allowing you to make more requests within rate limits.