Rate Limits
The PostCapture API enforces rate limits to ensure fair usage and service stability.
Current Limits
10
per minute
Requests
60
seconds
Window
Per
user
Scope
Rate limits are shared across all API keys belonging to the same user account. Creating multiple keys does not increase your rate limit budget.
How It Works
PostCapture uses a fixed-window rate limiter. A 60-second window starts with your first request. After 10 requests within that window, subsequent requests receive a 429 response until the window resets.
Window start: Timestamp of your first request in the current window.
Counter: Incremented with each request. Resets to 1 when the window expires.
Expiry: 60 seconds after window start. Your next request after expiry starts a new window.
429 Response Format
When rate limited, the API returns a JSON body and a Retry-After header (in seconds):
HTTP 429
1{2 "error": "Rate limit exceeded",3 "message": "Too many requests. Limit is 10 per minute. Try again in 42s.",4 "retryAfterMs": 420005}
| Header / Field | Description |
|---|---|
| Retry-After | Seconds until the rate limit window resets (HTTP header). |
| retryAfterMs | Milliseconds until the window resets (JSON body, more precise). |
Best Practices
- •Respect
Retry-After. Wait the specified duration before retrying instead of polling aggressively. - •Implement exponential backoff. If you hit the limit, wait progressively longer between retries (e.g., 1s, 2s, 4s).
- •Batch your work. If you need many screenshots, space requests evenly within the rate limit window.
- •Cache results. Screenshots are cached for 60 seconds on the CDN. Avoid re-requesting the same URL within that window.
Retry Example
1async function screenshotWithRetry(postUrl, apiKey, maxRetries = 3) {2 const url = new URL("https://postcapture.com/api/screenshot");3 url.searchParams.set("postUrl", postUrl);4 url.searchParams.set("apiKey", apiKey);56 for (let attempt = 0; attempt <= maxRetries; attempt++) {7 const res = await fetch(url);89 if (res.ok) return res;1011 if (res.status === 429) {12 const retryAfter = parseInt(res.headers.get("Retry-After") || "10");13 console.log(`Rate limited. Retrying in ${retryAfter}s…`);14 await new Promise((r) => setTimeout(r, retryAfter * 1000));15 continue;16 }1718 throw new Error(`API error: ${res.status}`);19 }2021 throw new Error("Max retries exceeded");22}
Next:Code Examples →