Control plane
Budgets and the kill switch
Per-key spend ceilings, what happens when one is reached, and the one request that stops everything.
This page answers how to cap what an agent can send and how to stop every agent at once. It exists because an agent can send ten thousand emails while you are at lunch.
A budget is a ceiling, not an alert
A budget is attached to a key, not to an account, and it is enforced before the send, not reported after it. When a key reaches its ceiling the API refuses further sends from that key with agent_budget_exceeded; the fix names PATCH /limits/keys/{id}. The account plan inclusion is a separate ceiling: when it is spent the refusal is plan_limit_reached. Nothing queues up behind the refusal and nothing is silently dropped.
Set a key budget with PATCH /limits/keys/{id} and read the current state with GET /limits/keys/{id}.
Two counters, deliberately
- Sends — how many messages this key may send in the period.
- Spend — what those messages may cost.
A key that sends few large messages and a key that sends many small ones fail differently, so both are capped.
Warnings arrive before the wall
limit.warning fires on the way up — at 80% of a key budget and at 80% of the plan inclusion — and limit.exceeded fires at the ceiling. Subscribe to both on a webhook endpoint — see the event catalogue — and you get the first one while there is still something to do about it.
The kill switch
One request pauses every key on the account:
curl -X POST https://api.agentisend.com/limits/kill-all \
-H "Authorization: Bearer $AGENTISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "invoice-bot loop"}'It is one request because the moment you need it is the moment you do not want to be reading documentation. While it is on, every send is refused with kill_switch_active; queued sends stay queued and are not lost. Turning it off is a second explicit request, and both are written to the audit log with the reason you typed:
curl -X POST https://api.agentisend.com/limits/resume-all \
-H "Authorization: Bearer $AGENTISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "loop confirmed stopped"}'A single key is paused with POST /limits/keys/{id}/kill and resumed with POST /limits/keys/{id}/resume.
Loop detection
A key that sends the same body to the same recipient repeatedly is caught before the budget is, and the send is held rather than delivered. The held send appears in the approvals queue with the duplicate it matched, so you can see why it stopped.
Rate limits
Every response carries ratelimit-limit, ratelimit-remaining and ratelimit-reset. A 429 carries retry-after and a retry_after_seconds in the body. Wait the stated time; a backoff you guessed is how a backoff becomes a hot loop.