Rate Limits
Understand API rate limits, monitoring, best practices, and how to handle rate limit errors effectively
Rate limits
The GetPaidHQ API implements rate limiting to ensure fair usage and maintain service quality for all customers. Rate limits are applied per API key and reset every minute.
Current limits
Rate limits vary by plan tier:
Plan | Requests per minute | Burst allowance |
---|---|---|
Starter | 500 | 100 |
Standard | 1,000 | 200 |
Pro | 5,000 | 1,000 |
Enterprise | Custom | Custom |
Rate limit headers
Every API response includes rate limit information in the headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1642681260
X-RateLimit-Burst-Limit: 200
X-RateLimit-Burst-Remaining: 150
Header descriptions
X-RateLimit-Limit
: Maximum requests per minute for your planX-RateLimit-Remaining
: Requests remaining in current windowX-RateLimit-Reset
: Unix timestamp when the limit resetsX-RateLimit-Burst-Limit
: Maximum burst requests allowedX-RateLimit-Burst-Remaining
: Burst requests remaining
Rate limit exceeded
When you exceed your rate limit, the API returns an HTTP 429 status code:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642681320
Retry-After: 60
{
"error": {
"type": "rate_limit_error",
"message": "Rate limit exceeded. Retry after 60 seconds."
}
}
Best practices
Implement exponential backoff
When you receive a 429 response, implement exponential backoff:
async function makeRequestWithBackoff(apiCall, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await apiCall();
} catch (error) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Monitor rate limit headers
Track your usage to avoid hitting limits:
function checkRateLimit(response) {
const remaining = parseInt(response.headers['x-ratelimit-remaining']);
const reset = parseInt(response.headers['x-ratelimit-reset']);
if (remaining < 10) {
const resetTime = new Date(reset * 1000);
console.warn(`Rate limit low: ${remaining} requests remaining until ${resetTime}`);
}
}
Batch operations efficiently
Group related operations to reduce API calls:
// ❌ Inefficient: Multiple API calls
for (const customer of customers) {
await getpaidhq.customers.retrieve(customer.id);
}
// ✅ Efficient: Single batch call
const customerIds = customers.map(c => c.id);
const customers = await getpaidhq.customers.list({
ids: customerIds,
limit: 100
});
Use webhooks instead of polling
Instead of frequently polling for updates, use webhooks:
// ❌ Inefficient: Polling every minute
setInterval(async () => {
const invoices = await getpaidhq.invoices.list({
status: 'unpaid',
limit: 100
});
processUnpaidInvoices(invoices);
}, 60000);
// ✅ Efficient: Use webhooks
app.post('/webhooks/getpaidhq', (req, res) => {
const event = req.body;
if (event.type === 'invoice.payment_failed') {
processFailedPayment(event.data);
}
res.status(200).send('OK');
});
Cache frequently accessed data
Cache data that doesn't change often:
const cache = new Map();
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
async function getCustomer(customerId) {
const cacheKey = `customer_${customerId}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
return cached.data;
}
const customer = await getpaidhq.customers.retrieve(customerId);
cache.set(cacheKey, {
data: customer,
timestamp: Date.now()
});
return customer;
}
Enterprise rate limits
Enterprise customers can request custom rate limits based on their usage patterns:
- Higher base limits: Up to 50,000 requests per minute
- Burst capacity: Custom burst allowances for traffic spikes
- Dedicated endpoints: Optional dedicated API endpoints
- Priority support: Faster response times for rate limit issues
Contact your account manager to discuss custom rate limits.
Rate limiting by endpoint
Some endpoints have additional limits:
Webhook endpoints
- Creation: 10 webhooks per minute
- Updates: 20 webhook updates per minute
- Deletion: 5 webhook deletions per minute
File uploads
- Invoice uploads: 50 files per minute
- Document uploads: 100 files per minute
- Size limits: 10MB per file
Bulk operations
- Batch imports: 5 operations per minute
- Bulk updates: 10 operations per minute
- Export requests: 3 requests per minute
Monitoring and alerts
Dashboard monitoring
Monitor your API usage in the GetPaidHQ dashboard:
- Real-time usage: Current rate limit consumption
- Historical data: Usage patterns over time
- Alert thresholds: Configure alerts at 80% and 90% usage
- Usage analytics: Identify optimization opportunities
API monitoring
Implement monitoring in your application:
// Track rate limit metrics
const rateLimitMetrics = {
requestsPerMinute: 0,
burstUsage: 0,
throttledRequests: 0
};
function trackRateLimit(response) {
rateLimitMetrics.requestsPerMinute++;
const remaining = parseInt(response.headers['x-ratelimit-remaining']);
const burstRemaining = parseInt(response.headers['x-ratelimit-burst-remaining']);
if (remaining < 50) {
// Alert: Approaching rate limit
sendAlert('Rate limit warning', { remaining });
}
if (response.status === 429) {
rateLimitMetrics.throttledRequests++;
sendAlert('Rate limit exceeded', { timestamp: Date.now() });
}
}
Error handling
Handle rate limit errors gracefully:
import { GetPaidHQError } from '@getpaidhq/node';
try {
const customer = await getpaidhq.customers.create(customerData);
} catch (error) {
if (error instanceof GetPaidHQError && error.type === 'rate_limit_error') {
// Rate limit exceeded
const retryAfter = error.headers['retry-after'];
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
// Implement retry logic or queue the request
await scheduleRetry(customerData, retryAfter);
} else {
throw error;
}
}
Getting help
If you're experiencing rate limiting issues:
- Review your usage patterns in the dashboard
- Implement the best practices outlined above
- Consider upgrading your plan for higher limits
- Contact support for custom limit discussions
For Enterprise customers, contact your dedicated support team for immediate assistance with rate limiting concerns.