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 TypeLimitDescription
API Key Authentication200 requests/minuteDefault for authenticated API requests using an API key
User Authentication200 requests/minuteFor authenticated requests from app.paperinvest.io users
Public Endpoints100 requests/minuteFor authentication endpoints and health checks
Unauthenticated Requests50 requests/minuteFor protected endpoints accessed without authentication (IP-based)

Rate Limit Headers

All API responses include headers that provide information about your current rate limit status:

HeaderDescription
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

JSON
429 Too Many Requests
{
  "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:

  1. Monitor headers: Check X-RateLimit-Remaining to track your usage
  2. Implement backoff: When you receive a 429 response, wait for the resetTime before retrying
  3. Use batch endpoints: For example, use /v1/market-data/quotes instead of multiple single quote requests
  4. 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;
}