Rate Limits
Postpone enforces rate limits on API requests to ensure fair usage and maintain system stability for all users. This guide explains the rate limits, how they work, and best practices for handling them.
Rate Limit Tiers
Rate limits are applied per user and vary based on your account type:
Free Accounts
25 requests per 10 minutes
Paid Accounts
300 requests per 10 minutes
The rate limit window is a sliding 10-minute period, meaning the limit resets continuously rather than at fixed intervals.
Rate Limit Headers
Every API response includes headers that provide information about your current rate limit status:
Header | Description |
---|---|
X-RateLimit-Limit | Maximum number of requests allowed in the time window |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets |
Example Response Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1697472000
Content-Type: application/json
Rate Limit Exceeded
When you exceed your rate limit, the API will return a 429 Too Many Requests
status code with an error response:
{
"errors": [
{
"message": "Rate limit exceeded. Please try again later.",
"code": "rate_limit_exceeded"
}
]
}
When you receive a 429 response, you should wait until the time specified in the X-RateLimit-Reset
header before making additional requests.
Best Practices
1. Monitor Rate Limit Headers
Always check the rate limit headers in your API responses to track your usage:
const response = await fetch('https://api.postpone.app/gql', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR-TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({ query: '...' })
});
const remaining = response.headers.get('X-RateLimit-Remaining');
const resetTime = response.headers.get('X-RateLimit-Reset');
console.log(`Requests remaining: ${remaining}`);
console.log(`Resets at: ${new Date(resetTime * 1000)}`);
2. Implement Exponential Backoff
When you receive a rate limit error, implement exponential backoff to avoid repeated failed requests:
async function makeRequestWithRetry(query, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch('https://api.postpone.app/gql', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR-TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({ query })
});
if (response.status === 429) {
const resetTime = response.headers.get('X-RateLimit-Reset');
const waitTime = (resetTime * 1000) - Date.now();
if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
}
return response;
}
}
3. Cache Responses
Cache API responses when appropriate to reduce unnecessary requests:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedData(query) {
const cacheKey = JSON.stringify(query);
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await makeAPIRequest(query);
cache.set(cacheKey, {
data: response,
timestamp: Date.now()
});
return response;
}
Upgrading for Higher Limits
If you're on a free account and need higher rate limits, consider upgrading to a paid plan. Paid accounts receive 12x more requests (300 vs 25 per 10 minutes)
Visit postpone.app/plans to view our pricing and upgrade options.