Rate Limits
RenderScreenshot uses rate limiting to ensure fair usage and system stability. Limits vary by plan.
Rate Limits by Plan
| Plan | Requests/min | Concurrent | Batch Size |
|---|---|---|---|
| Free | 10 | 2 | 5 |
| Starter | 60 | 5 | 20 |
| Pro | 300 | 20 | 100 |
| Enterprise | Custom | Custom | Custom |
Requests per Minute
Maximum number of API requests allowed per minute. Resets every 60 seconds.
Concurrent Requests
Maximum number of requests that can be processing simultaneously. This affects how many screenshots can be rendered at the same time.
Batch Size
Maximum number of URLs allowed in a single batch request.
Rate Limit Headers
Every response includes rate limit information:
HTTP/1.1 200 OK X-RateLimit-Limit: 300 X-RateLimit-Remaining: 295 X-RateLimit-Reset: 1705600060
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests per window |
X-RateLimit-Remaining |
Requests remaining in current window |
X-RateLimit-Reset |
Unix timestamp when the window resets |
429 Too Many Requests
When you exceed rate limits, you'll receive a 429 response:
HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1705600060 Retry-After: 45 Content-Type: application/json { "error": { "type": "rate_limit_error", "code": "too_many_requests", "message": "Rate limit exceeded. Please retry after 45 seconds.", "retryable": true, "docs": "https://docs.renderscreenshot.com/errors/rate-limits" }, "request_id": "req_abc123" }
Retry-After Header
The Retry-After header indicates how many seconds to wait before retrying:
Retry-After: 45
Handling Rate Limits
Exponential Backoff
Implement exponential backoff for rate limit errors:
async function screenshotWithRetry(url, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch('https://api.renderscreenshot.com/v1/screenshot', { method: 'POST', headers: { 'Authorization': 'Bearer rs_live_xxxxx', 'Content-Type': 'application/json' }, body: JSON.stringify({ url }) }); if (response.status === 429) { const retryAfter = parseInt(response.headers.get('Retry-After') || '60'); const delay = retryAfter * 1000 * Math.pow(2, attempt); console.log(`Rate limited. Waiting ${delay}ms before retry.`); await new Promise(resolve => setTimeout(resolve, delay)); continue; } return response; } throw new Error('Max retries exceeded'); }
Ruby Example
def screenshot_with_retry(url, max_retries: 3) attempt = 0 loop do response = HTTParty.post( 'https://api.renderscreenshot.com/v1/screenshot', headers: { 'Authorization' => 'Bearer rs_live_xxxxx', 'Content-Type' => 'application/json' }, body: { url: url }.to_json ) return response unless response.code == 429 attempt += 1 raise 'Max retries exceeded' if attempt >= max_retries retry_after = response.headers['Retry-After'].to_i delay = retry_after * (2 ** attempt) sleep(delay) end end
Python Example
import time import requests def screenshot_with_retry(url, max_retries=3): for attempt in range(max_retries): response = requests.post( 'https://api.renderscreenshot.com/v1/screenshot', headers={ 'Authorization': 'Bearer rs_live_xxxxx', 'Content-Type': 'application/json' }, json={'url': url} ) if response.status_code == 429: retry_after = int(response.headers.get('Retry-After', 60)) delay = retry_after * (2 ** attempt) print(f'Rate limited. Waiting {delay}s before retry.') time.sleep(delay) continue return response raise Exception('Max retries exceeded')
Concurrent Request Limits
If you exceed concurrent request limits:
{ "error": { "type": "rate_limit_error", "code": "concurrent_limit", "message": "Too many concurrent requests. Maximum is 5.", "retryable": true } }
Handle by queuing requests or implementing a semaphore.
Best Practices
1. Use Caching
Leverage caching to avoid redundant requests:
{ "url": "https://example.com", "cache": { "enabled": true, "ttl": 86400 } }
2. Batch Multiple URLs
Use batch endpoint instead of multiple single requests:
{ "urls": ["https://a.com", "https://b.com", "https://c.com"], "options": { "preset": "og_card" } }
3. Use Webhooks for Large Jobs
For many screenshots, use async processing with webhooks:
{ "url": "https://example.com", "webhook": { "url": "https://your-server.com/webhook" } }
4. Monitor Usage
Check your remaining limits before large operations:
curl https://api.renderscreenshot.com/v1/usage \ -H "Authorization: Bearer rs_live_xxxxx"
5. Implement Request Queuing
For high-volume applications, implement a request queue that respects rate limits.
Requesting Higher Limits
Enterprise customers can request custom rate limits. Contact [email protected] with:
- Your current plan and account ID
- Expected request volume
- Use case description
See Also
- Error Codes - All error types
- Usage Statistics - Monitor your usage
- Batch Screenshots - Efficient batch processing