Reference
Tiered by what an operation costs us, not by how often callers want it.
| Tier | Budget | Operations |
|---|---|---|
| auth_failure | 10 / 300s | not charged by a REST operation |
| checkout | 5 / 60s | createCheckoutHandoff |
| discovery | 120 / 60s | listTransferServices, listVehicleClasses, getPolicy, getQuoteRequirements |
| quote_authoritative | 10 / 60s | createQuote |
| quote_estimate | 20 / 60s | createQuoteEstimate |
| quote_read | 60 / 60s | getOwnQuote, resolveCheckoutHandoff |
| routing | 60 / 60s | getRouteByPair, getRoute |
The same table is on the document as x-ratelimit-tiers, and each operation names its tier as x-rate-limit-tier. Read those rather than parsing this page — they are generated from the limiter itself, so they cannot drift from what is actually charged.
auth_failure is not like the othersIt counts failed authentications, not requests to any one endpoint, and it is keyed on the calling address rather than a verified subject — because a caller that cannot authenticate has no subject yet. A credential-guessing loop is therefore throttled by its own failures rather than by whichever endpoint it happens to target. If you are debugging a token, a burst of retries will hit this before it hits anything else.
A rejection is RATE_LIMITED with HTTP 429, a Retry-After header in seconds, and the same value in the body as retry_after_seconds. It is one of only four retryable codes: wait the stated interval and send the identical request again.
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/problem+json
{
"code": "RATE_LIMITED",
"retryable": true,
"retry_after_seconds": 30,
"next_action": "Wait for the interval in retry_after_seconds, then retry."
}One thing we do not send yet
There are no RateLimit-* headers on a successful response, so you cannot read your remaining budget before you exhaust it. Pace against the table above. We would rather leave this documented as absent than describe a header we do not send.
REST and MCP consume the same tiers with the same numbers. Calling create_transfer_quote over MCP and POST /quotes over REST draws down one budget, not two — they are the same operation reached by two protocols.