One budget, weighted by what you ask for
A quote is a read against in-memory pool state. A swap runs that same routing and then builds a transaction, resolves its lookup tables, and simulates it. Charging both “one request” makes the budget meaningless for whichever of the two you sized it against, so each request debits your bucket by its weight:
Through the table above that is 100 quotes/second, or 20 transaction builds/second, or any mix
of the two.
Rate limits do not vary by plan. Free, Pro, Scale and Enterprise keys are all rated at the
same 100 units/second. Plans differ in how many keys you may hold, not in throughput.This is deliberate. A ceiling derived from trailing volume cannot be capacity-planned against,
and it throttles a new integration hardest on day one — exactly when its quote-to-swap ratio is
at its worst and it needs headroom most.
Anonymous access (no API key)
GET /api/v1/quote, POST /api/v1/swap, POST /api/v1/instructions, and GET /api/v1/price
all work with no Authorization header — useful for trying the API before you get a key.
Anonymous callers share a small per-IP bucket, debited by the same cost table:
A burst of 5 is exactly one
POST /api/v1/swap. Anonymous access is for evaluation; for anything
else get a key — same mechanics, 100× the budget, scoped to your
account rather than shared with every anonymous caller on your IP.
GET /health requires no key and is not subject to any of these limits.
Per-IP ceiling (before authentication)
A second limiter runs before authentication and buckets by client IP rather than by key. It protects the auth path from unauthenticated floods, so it applies to every/api/v1/* request —
including ones with a missing or invalid key — and to the WebSocket upgrade.
It sits at twice the published per-key budget so it never binds on legitimate traffic from a
single customer; it should only trip on abuse. If you proxy many customers through one egress IP,
they share this ceiling even though their per-key budgets are separate.
The WebSocket handshake is covered by this per-IP limiter only — the per-key budget above is
not applied to the upgrade. Once connected, the stream is not rate limited per message.
Rate limit response
When rate limited, the API returns HTTP429:
Retry strategy
Use exponential backoff when you receive a429:
Best practices
- Don’t cache quotes. A quote’s firm commitment lives for
validForMs(~3 s) and its price-or-fail window forfirmForMs(~400 ms) — see Firm quotes. Re-fetch before you build. (lastValidBlockHeightbounds how long the transaction can land, ~60 s; that is a different clock from how long the price is honoured.) - Stream instead of polling. If you need continuously fresh prices, subscribe on
GET /api/v1/stream— the connection is not per-message rate limited, so it is strictly cheaper than spending 1 unit per/quote. - Prefer
/instructionsover/quote+/swap. OnePOST /api/v1/instructionscosts 5 units; aGET /api/v1/quotefollowed byPOST /api/v1/swapcosts 6 and makes the engine route twice.