Calls to Akadenia Security are limited with a leaky bucket, like Shopify's API. Each call adds its cost to a bucket, and the bucket drains at a steady rate. Bursts are fine as long as the average stays under the drain rate; a call that doesn't fit waits until there's room.
There are two kinds of bucket:
- The dashboard and API: one bucket per organization, shared by all of its members and their scripts.
- AI agents (MCP): one bucket per person per organization, counted in points. See Connecting AI agents for what each tool costs.
AI agents' limits are enforced now. The dashboard and API limits are measured now and will be enforced later: until then no call is refused for them and answers don't carry the headers below.
Limits by plan
| Plan | Dashboard and API: holds | Drains (a second) | MCP points: holds | Refills (a second) |
|---|---|---|---|---|
| Free and trial | 40 | 2 | 60 | 1 |
| Pay-as-you-go, Team | 80 | 4 | 120 | 2 |
| Business | 200 | 10 | 300 | 5 |
| Enterprise | 400 | 20 | 600 | 10 |
An Enterprise contract can set its own limits. A change of plan applies within a minute.
What a call costs
On the dashboard and API, reading something costs 1 and a change costs 2. Calls that send email, run a DNS check or open tickets (the sample alert, a webhook's test, an invitation, verifying a domain, opening tickets, deciding many findings at once) cost 5, and drafting a pentest report costs 10. Scan now keeps its own allowance by plan, on top of this.
What each answer says
Once the dashboard and API limits are enforced, every answer to an organization's call will say where its bucket stands:
RateLimit-Limit: how much the bucket holds;RateLimit-Remaining: how much room is left;RateLimit-Reset: seconds until it's empty again.
A call that doesn't fit will be answered 429 Too Many Requests, with {"code": "rate_limited"} and a Retry-After header: the whole seconds to wait before it fits.
MCP tools say the same in each result now: what the call cost, and the bucket's maximum, the points available and how many come back a second (_meta.cost.throttleStatus). An empty bucket's error says how many seconds to wait.
Waiting and retrying
AI agents should do this now; scripts that call the API can get ready for it.
- Honour
Retry-After: wait at least that long before sending the call again. - With no
Retry-After, back off exponentially (1 second, then 2, 4, 8, with some randomness), up to a minute or so. - Keep an eye on
RateLimit-Remainingand slow down before it reaches 0, rather than waiting to be refused. - For many changes at once, prefer the calls that take many (deciding many findings) to one call each.
The dashboard does this for you: it retries a refused read once, after the wait, and tells you how long to wait when a change is refused.
If your organization keeps reaching its limit, a larger plan has larger buckets; see Plans and billing. For limits beyond Enterprise's, talk to us.