Send limits, reputation & budgets
Two safety valves that stop one runaway agent from sinking everyone's delivery — an automatic brake and a hard cap you set in advance.
When many agents send on your behalf, one bad actor — a loop that blasts a stale list, a prompt that emails the wrong people — can drag down delivery for everyone. Dairo gives you two ways to contain it: a budget is the hard cap you set in advance, and reputation is the automatic brake that reacts to bounces and complaints. Use either or both.
Both are part of the optional agent layer. They use separate scopes: reading
reputation uses agents:read and clearing a tripped agent uses agents:write;
reading budgets uses budgets:read and setting or deleting one uses
budgets:write.
Reputation
Reputation watches each agent's bounces and complaints and gives you a simple
shouldSend signal to check before you dispatch. If an agent goes off the rails,
it's contained automatically.
Check before you send
The fastest use: read one agent's state and gate on shouldSend (or
verdict === "allow") before a batch.
Each agent reports a state, a verdict, its live bounce and complaint rates
over the window, and a shouldSend boolean:
state | verdict | Meaning |
|---|---|---|
healthy | allow | Sending normally. |
throttled | throttle | Rate-limited after warning-level signals. |
quarantined | block | Tripped — sends are paused. |
review | review | Held for a human decision. |
overrideLocked flags an agent an organization owner or admin pinned from the
dashboard so it won't auto-trip; such an override lasts 1 hour by default and at
most 24 hours (overrideLockedUntil), and an API key cannot set one.
See your whole fleet
GET /v1/agents/reputation returns every agent's state, newest-tripped first,
with the window and thresholds alongside the data.
Clear a tripped agent
DELETE /v1/agents/{id}/reputation is an operator override: it lifts a
quarantine or resolves a review back to healthy, and returns the reset state.
It uses agents:write and is recorded in your audit log.
Send budgets
A budget is a hard ceiling on sending that Dairo enforces for you. Set one on your whole account, a single API key, or an individual agent, and Dairo stops the next send the moment it would cross the line — so one bad loop can never quietly torch your sender reputation. If a human triggers every send, you may never need it. If code or an AI agent sends on its own, a budget is the seatbelt.
Pick what a budget covers
A budget attaches to one of three things. Set the ceiling where it makes sense — on the whole account, on the key a service uses, or on a specific agent.
| Covers | Use it for | What you pass |
|---|---|---|
| Account | A single ceiling across everything you send. | scope: "account" |
| Key | One service or integration, isolated from the rest. | scope: "key" + the key's id |
| Agent | One agent, so a misbehaving bot can't spend the whole account. | scope: "agent" + the agent's id |
Set a budget
One call creates or updates a budget. Pass the scope, the thing it covers, and at least one limit. You get back the budget with its live usage so far.
The limits you can set
Set any combination of these. A budget needs at least one.
| Limit | What it caps |
|---|---|
maxSendsPerDay | Total sends in a rolling 24-hour window. |
maxNewRecipientsPerHour | First-time recipients per hour — the classic shape of a runaway loop blasting a fresh list. |
hardStopOnComplaint | When true, the moment a recipient reports spam, every further send under this budget stops until you intervene. |
An account budget also takes maxSpendPerDayCents, a cap on metered spend (calls,
letters, AI) over a rolling day. It applies to account budgets only; on a key or
agent budget it is a 400. See spend caps.
What happens at the ceiling
When a send would cross a budget, Dairo refuses it with a 429 carrying the
budget_exceeded error code — whether the ceiling it hit was a send cap, a
new-recipient cap, or the complaint hard-stop. The code lets an agent branch
cleanly: back off, queue for later, or alert a human, instead of retrying into a
wall.
An agent that reacts to its own ceiling should catch budget_exceeded and pause
the loop rather than retry. See Errors for the full list of
codes and how to handle them.
Check usage against a cap
Every budget carries live usage, so you can see how close a scope is to its ceiling before it gets there. List all budgets, or fetch one.
Fetch one budget by passing account, or a key or agent id as the scopeId.
Remove a budget
Deleting a budget removes the cap entirely — sending under that scope is no longer ceilinged.
Setting or deleting a budget is a privileged action. A key that can only send mail can't raise its own ceiling — so a leaked sending key stays boxed in by the limits you set.