L O R I C A / docs
API REFERENCE

Rate Limiting

Default production limits scale to your contracted volume. Both global and per-action-class caps apply; whichever you hit first triggers a 429. Sandbox has separate, lower limits for integration testing.

Default limits

ScopeLimitBurst
Global (production, per tenant)200 req/sec400
Per action class (production, per tenant)50 req/sec100
Per user (production)10 verify/min per user_id
Sandbox (per tenant)20 req/sec40

Higher production limits are negotiated as part of your contract and apply automatically to your production keys.

Response headers

HeaderValue
X-RateLimit-LimitYour current limit
X-RateLimit-RemainingCalls left in the current window
X-RateLimit-ResetUnix seconds until window resets
Retry-AfterPresent only on 429 responses, seconds to wait

Recommended retry behavior

On 429, sleep for Retry-After seconds, then retry the request with the same X-Lorica-Idempotency-Key. Don't invent your own backoff — Retry-After is computed from your tenant's actual cap and current usage and is always the correct minimum wait. Add jitter on top if you have many concurrent retries.

# Python
import time
import requests

def verify_with_retry(payload, max_attempts=3):
    for attempt in range(max_attempts):
        r = requests.post(URL, headers=HEADERS, json=payload)
        if r.status_code == 200:
            return r.json()
        if r.status_code == 429:
            wait = int(r.headers.get("Retry-After", "1"))
            time.sleep(wait + 0.5)  # small jitter
            continue
        r.raise_for_status()
    raise RuntimeError("exceeded retries")
Operational note
Hitting the per-user 10/min cap usually indicates a UI bug — a real user won't intentionally trigger ten verify calls in a minute. If you see sustained per-user 429s, check your retry logic and the user-facing error handling.