API overview
ExaRoutes exposes a REST API at https://api.exaroutes.com. All endpoints accept and return
JSON. Authentication uses workspace-level API keys.
Base URL
https://api.exaroutes.comFor staging:
https://api.staging.exaroutes.comAuthentication
Pass your API key in the Authorization header:
curl https://api.exaroutes.com/api/qr/codes \
-H "Authorization: Bearer er_live_..."See Authentication for full details on key scopes and rotation.
Rate limits
ExaRoutes applies two distinct kinds of throttle:
Per-IP request limits (express-rate-limit)
Hard caps to keep a single IP from blowing up the service. Apply to every caller (anonymous, cookie-authed, or API-key-authed). Limit + window vary per route. The most-asked-about ones:
| Route | Limit | Window |
|---|---|---|
POST /api/auth/login | 5 | 15 min |
POST /api/auth/register | 3 | 1 hour |
POST /api/auth/step-up | 5 | 15 min |
POST /api/mfa/verify | 10 | 15 min |
GET /r/:shortId (QR scan) | 600 | 1 min |
POST /api/forms/.../submissions | 30 | 1 min |
POST /api/verify/serial | 60 | 1 min |
GET /v/:itemId/:signature | 60 | 1 min |
POST /api/webhook/dodo | 60 | 1 min |
POST /api/ai/... | 30 | 1 hour |
| Public free QR generator | 10 | 1 day |
Headers on rate-limited responses follow the
draft-7 standard:
RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, plus
Retry-After on 429s.
Per-plan quotas (usage middleware)
Daily / monthly / lifetime caps tied to your subscription’s plan tier
(apiCalls, dynamicQr, bulkOrders, etc.). Hitting one returns a
429 with X-ExaRoutes-Error-Code: PLAN_LIMIT_REACHED and a body
indicating which capability tripped:
{
"error": "Daily QR generation limit reached for the qr.starter plan.",
"code": 429,
"exaroutesErrorCode": "PLAN_LIMIT_REACHED"
}Plan limits are documented per tier on the pricing page.
What’s NOT yet implemented
- Per-API-key rate limits (today, throttling is per-IP). Tracked for V11.
- Per-workspace bulk-job throttling (today, bulk jobs share the per-IP limit). Tracked for V11.
Versioning
The API is currently unversioned. Breaking changes will be announced via the changelog with a six-month deprecation window once we go GA.