Docs · Concepts
Rate limits
Two budgets on the merchant API, separate budgets for wallets, and one status code when you exceed any of them.
Merchant budgets
Every /v1/* route carries two budgets at once. The defaults:
| Budget | Default | Keyed on |
|---|---|---|
| Per API key | 120 requests / 60 s | The key's id, once the bearer token has been validated — the presented secret is never a bucket name. |
| Per source IP | 600 requests / 60 s | The client address, checked before authentication, so it also covers unauthenticated requests and rejected credentials. |
Wallet budgets
The wallet-facing routes have their own budgets, so a merchant's polling loop and a wallet's two requests never share a bucket:
| Budget | Default |
|---|---|
Per client IP across both /wallet/* routes | 120 requests / 60 s |
Posts to /wallet/response/:sessionId, per session id | 10, over the session's lifetime |
Behind a proxy
X-Forwarded-For is not trusted unless the deployment is
configured with the real number of proxy hops in front of it. Where it is unset,
every client shares the proxy's bucket for the IP-keyed budgets; the per-key budget
is unaffected. This only concerns you if you run Valitel yourself.
Handling 429
Exceeding any budget returns 429 rate_limit_exceeded in the
standard error shape. Back off and retry — retry the read freely, and retry
the create safely by sending an Idempotency-Key header, so a
retry after a timeout replays the original session instead of creating a second one
(see Create a verification).