Rate limits
Routal's request quota, what happens when you exceed it, and recommended client patterns.
The Routal API rate-limits requests per authenticated credential (API key or user session). One credential, one budget — sharing a key across many services means they all draw from the same pool.
Current limit
2,000 requests per minute per credential, applied as a rolling 60-second window. This is the platform-wide default that covers the /v2/* and /v3/* REST surface documented here.
A handful of compute-heavy operations have lower per-route caps on top — geocoding being the most common one. When you cross one of those, you also get 429; the patterns below cover both cases.
What happens when you exceed the limit
You receive a 429 Too Many Requests response. A few things to know:
- There is no
Retry-Afterheader today. - There is no
highway.*message_idon rate-limit errors. The body for a 429 won't match the standard error envelope, so don't try to branch onmessage_idfor this case.
If you need to differentiate a rate-limit 429 from any other 4xx, branch on the status code alone.
Recommended client patterns
Until Retry-After is exposed, back off using exponential delays:
async function callWithBackoff(fn, attempt = 0) {
try {
return await fn();
} catch (err) {
if (err.status !== 429 || attempt >= 5) throw err;
const baseMs = 1000 * 2 ** attempt; // 1s, 2s, 4s, 8s, 16s
const jitterMs = Math.random() * 500;
await new Promise((r) => setTimeout(r, baseMs + jitterMs));
return callWithBackoff(fn, attempt + 1);
}
}Staying under the limit
A few patterns keep you under the quota without trying:
- Use bulk endpoints where they exist.
POST /v2/stopsaccepts an array — one call for 100 stops is much cheaper than 100 calls of one. Same forPOST /v3/vehicles. - Use pagination, not full scans. Most read endpoints accept
?limit=&offset=(see Pagination). Raiselimitto the endpoint's documented max for sync jobs. - Don't poll for state changes. If you're calling
GET /v2/plan/{id}in a loop waiting for status to change, replace it with a webhook subscription. - Cache reference data. Vehicles, projects, custom-field definitions and other rarely-changing entities can live in your cache for the duration of a planning cycle.
Concurrency
The per-minute quota is independent of concurrency. You can fire multiple requests in parallel as long as the total in the rolling window stays under 2,000. Beyond ~10 concurrent connections we typically don't see meaningful throughput gains — the bottleneck shifts to your own infrastructure.
Need more?
If your integration consistently hits the cap on real workloads, email developers@routal.com. Per-credential limits can be raised when the use case warrants it; bulk operations are usually cheaper for both of us than tight polling loops.
