Rate Limits
Understand the request limits that apply to your API key and how to stay within them.
Every API key has a monthly request quota and a per-second rate limit. Staying within these limits keeps your integration running smoothly and avoids 429 Too Many Requests errors.
Limits at a glance
| Limit | Value |
|---|---|
| Monthly quota | 250,000 requests |
| Sustained rate | 25 requests / second |
| Burst capacity | 50 requests |
The monthly quota is the total number of requests you can make in a calendar month. The sustained rate is the steady-state throughput your key supports. The burst capacity allows short spikes above the sustained rate — useful when your application starts up or processes a batch — but you cannot sustain burst-level traffic continuously.
What counts as a request
Each HTTP call to any API endpoint counts as one request, regardless of how many records are returned. Fetching 1,000 headlines in a single paginated call counts the same as fetching 10.
Handling 429 errors
When you exceed the rate limit, the API returns:
HTTP 429 Too Many Requests
The correct response is to back off and retry. A simple fixed delay of 1–2 seconds is sufficient for most usage patterns. If you are running a batch process that makes many sequential calls, add a small sleep between requests to stay comfortably within the 25 req/s limit.
import time
import os
import requests
API_KEY = os.environ["PERMUTABLE_API_KEY"]
HEADERS = {"x-api-key": API_KEY}
TICKERS = ["BZ_COM", "CL_COM", "NG_COM", "QO_COM"]
results = []
for ticker in TICKERS:
resp = requests.get(
f"https://copilot-api.permutable.ai/v1/signals",
headers=HEADERS,
params={"tickers": [ticker]},
)
if resp.status_code == 429:
time.sleep(2)
resp = requests.get(
f"https://copilot-api.permutable.ai/v1/signals",
headers=HEADERS,
params={"tickers": [ticker]},
)
resp.raise_for_status()
results.extend(resp.json()["signals"])
time.sleep(0.1) # stay well within 25 req/sAvoid parallelised requests. Firing many concurrent requests simultaneously is the most common cause of hitting the burst limit. Sequential requests with a small delay between them are more predictable and easier to debug. If you need data for multiple tickers, use endpoints that accept a list of tickers in a single call (e.g.
GET /v1/signals?tickers=BZ_COM&tickers=CL_COM) rather than making one request per ticker in parallel.
Quota usage
Your monthly quota resets at the start of each calendar month. If you need a higher quota or a higher rate limit for a specific use case, contact the Permutable team.
Next steps
- Pagination — fetch large historical datasets efficiently without burning through your quota
- Error responses — full list of error codes and what they mean
Updated 3 days ago
