Rate Limits
How Woosmap APIs report rate limit usage in response headers, and how to back off when a request returns 429 Too Many Requests.
Each endpoint has its own rate limit, shared by all the API keys of a project. The endpoint’s reference page shows it: Ratelimit: 50/1s means 50 requests per second.
Read your remaining quota
Every response tells you where you stand:
RateLimit-Policy: "requests";q=40;w=1
RateLimit: "requests";r=39;t=1
| Field | Meaning | Here |
|---|---|---|
q |
Requests allowed per window | 40 |
w |
Window length, in seconds | 1 second |
r |
Requests left in this window | 39 |
t |
Seconds until the window resets | 1 second |
Handle a 429
Once r reaches 0, the API answers 429 Too Many Requests until the window resets. Wait t seconds, then retry. Retrying right away fails again.
- Retry at most three times.
- If the 429 has no
RateLimitheader, wait 1, 2, then 4 seconds. - In a batch job, pause as soon as
rreaches 0, without waiting for the 429.
Retry on 429
import re
import time
import requests
def retry_delay(response: requests.Response, attempt: int) -> int:
header = response.headers.get("RateLimit", "")
waits = [
int(reset)
for remaining, reset in re.findall(r"r=(\d+);t=(\d+)", header)
if remaining == "0"
]
return max(waits, default=2**attempt)
def get(url: str, params: dict, retries: int = 3) -> requests.Response:
for attempt in range(retries + 1):
response = requests.get(url, params=params, timeout=10)
if response.status_code != 429 or attempt == retries:
return response
time.sleep(retry_delay(response, attempt))
function retryDelay(response, attempt) {
const header = response.headers.get("RateLimit") ?? "";
const waits = [...header.matchAll(/r=(\d+);t=(\d+)/g)]
.filter(([, remaining]) => remaining === "0")
.map(([, , reset]) => Number(reset));
return waits.length ? Math.max(...waits) : 2 ** attempt;
}
async function get(url, retries = 3) {
for (let attempt = 0; ; attempt++) {
const response = await fetch(url);
if (response.status !== 429 || attempt === retries) return response;
await new Promise((resolve) => setTimeout(resolve, retryDelay(response, attempt) * 1000));
}
}
Complete scripts, with tests, are in woosmap-samples.
Special cases
- The Distance Matrix limits requests and matrix elements separately, and lists both policies:
RateLimit: "elements";r=999;t=1, "requests";r=19;t=2. Wait for the one atr=0. The code above handles it. RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset(X-RateLimit-*on the Distance API) are legacy headers that describe only the last policy. UseRateLimit.- Browsers can’t read these headers, because the API does not expose them to cross-origin JavaScript. Read them on your server.
- If your normal traffic keeps reaching the limit, contact [email protected].