Skip to main content

Rate limits

The MyTrafficData API throttles abusive request patterns to keep the platform fast for everyone. Most well-behaved integrations never hit a limit; this page explains what happens if you do.

Current status

note

There are no DRF-level throttles configured on /api/v1/ endpoints today. Throttling may still be applied at the infrastructure layer (reverse proxy, WAF) — partners should treat this page as the contract for when you hit a 429, not as a guarantee you never will.

Whenever a throttle is enforced:

  • It is applied per authenticated user (per token).
  • Limits track on a sliding window.
  • Numeric rates may change without breaking compatibility — never hard-code them. Read the response headers and react.

How you know you've been throttled

Throttled requests return HTTP 429 Too Many Requests with a Retry-After response header and a JSON body carrying a detail field (DRF's default throttling response):

429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
"detail": "Request was throttled. Expected available in 12 seconds."
}

Retry-After is the integer number of seconds to wait before retrying. Honour it.


Python — minimal retry loop
import time
import requests

def request_with_backoff(method, url, *, headers, max_attempts=5, **kwargs):
if max_attempts < 1:
raise ValueError("max_attempts must be at least 1")
# Never let a stalled connection hang the caller forever; override per call.
kwargs.setdefault("timeout", 30)
for attempt in range(max_attempts):
r = requests.request(method, url, headers=headers, **kwargs)
# Don't sleep after the last attempt — there is nothing left to retry.
if r.status_code != 429 or attempt == max_attempts - 1:
return r
# Retry-After may be an HTTP-date rather than seconds (RFC 9110),
# so fall back to the exponential delay instead of raising.
try:
wait = max(0, int(r.headers["Retry-After"]))
except (KeyError, ValueError):
wait = 2 ** attempt
time.sleep(wait)
return r # unreachable; the loop returns on its final attempt

Add jitter (a small random delay) for parallel workers so they don't all retry at the same instant.


Tips to avoid hitting limits

  • Page with bigger limit values on search endpoints — one request of 1,000 items is much cheaper than ten requests of 100.
  • Filter aggressively — narrow the date range, site list, or record type to only what you need.
  • Cache stable lookups — site lists, account metadata, and configuration rarely change. Cache them client-side and re-fetch on a slow cadence.
  • Avoid hot polling — don't poll an export status endpoint every second. Start at 2s, double each time, cap at 30s.
  • One token per integration — sharing one token across many services makes you compete with yourself for the same budget.

What's NOT throttled

  • Reading the OpenAPI schema at /api/v1/docs/schema/.
  • Health/status probes (if you've been pointed at them).

Summary checklist

  • ✅ 429 means slow down — honour the Retry-After header.
  • ✅ Exponential backoff + jitter for parallel workers.
  • ✅ Limits are per-token; one token per integration is recommended.
  • ✅ Cache stable data client-side; don't refetch what doesn't change.
  • ✅ Read the headers, don't hard-code rate numbers.