Rate Limiting
To ensure fair usage and system stability, the Paper API implements rate limiting. This page explains how rate limiting works, what limits apply to different types of requests, and how to handle rate limit responses.
How Rate Limiting Works
Paper uses a sliding window approach to rate limiting. Each client is allowed a certain number of requests within a 60-second window. When the limit is reached, subsequent requests will receive a 429 Too Many Requests
response until the window expires.
Rate Limits
Different rate limits apply depending on the authentication method and endpoint:
Client Type | Limit | Description |
---|---|---|
API Key Authentication | 200 requests/minute | Default for authenticated API requests using an API key |
User Authentication | 200 requests/minute | For authenticated requests from app.paperinvest.io users |
Public Endpoints | 100 requests/minute | For authentication endpoints and health checks |
Unauthenticated Requests | 50 requests/minute | For protected endpoints accessed without authentication (IP-based) |
Rate Limit Headers
All API responses include headers that provide information about your current rate limit status:
Header | Description |
---|---|
X-RateLimit-Limit | The maximum number of requests allowed in the current window |
X-RateLimit-Remaining | The number of requests remaining in the current window |
X-RateLimit-Reset | The time in seconds until the rate limit window resets |
Handling Rate Limit Responses
When you exceed the rate limit, the API will respond with a 429 Too Many Requests
status code:
Rate Limit Exceeded Response
{
"statusCode": 429,
"message": "Rate limit exceeded",
"limit": 200,
"remaining": 0,
"resetTime": 45
}
The resetTime
field indicates the number of seconds until the rate limit window resets and you can resume making requests.
Best Practices
To avoid hitting rate limits:
- Monitor headers: Check
X-RateLimit-Remaining
to track your usage - Implement backoff: When you receive a 429 response, wait for the
resetTime
before retrying - Use batch endpoints: For example, use
/v1/market-data/quotes
instead of multiple single quote requests - Cache responses: Cache API responses when appropriate to reduce requests
Example: Handling Rate Limits
JavaScript Example
async function makeApiRequest(url, options = {}) {
const response = await fetch(url, {
...options,
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json',
...options.headers
}
});
// Check rate limit headers
const remaining = response.headers.get('X-RateLimit-Remaining');
const resetTime = response.headers.get('X-RateLimit-Reset');
if (response.status === 429) {
const data = await response.json();
console.log(`Rate limit exceeded. Retry after ${data.resetTime} seconds`);
// Wait and retry
await new Promise(resolve => setTimeout(resolve, data.resetTime * 1000));
return makeApiRequest(url, options);
}
return response;
}