For agents · Published 2026-09-18 · Updated 2026-10-26 · AgentiSend
Agent email budgets
To cap how much email an AI agent can send, give it its own API key and set a budget on that key with PATCH /limits/keys/{id}. The ceiling is enforced before the send.
To cap how much email an AI agent can send, give the agent its own API key and set a budget on that key with PATCH /limits/keys/{id}. The ceiling is checked before each send, the agent cannot raise it, and a send past it is refused with agent_budget_exceeded rather than queued or charged.
Do it in two requests
Create a key for the agent, so its ceiling is its own:
curl -sS -X POST https://api.agentisend.com/api-keys \
-H "Authorization: Bearer $AGENTISEND_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"example","permission":"full_access"}'201
{
"budget_per_period": 5000,
"created_at": "2026-09-04T09:14:00.000Z",
"domain_scope": "example",
"expires_at": "2026-09-04T09:14:00.000Z",
"id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
"last_used_at": "2026-09-04T09:14:00.000Z",
"loop_guard": "off",
"name": "example",
"object": "api_key",
"period": "monthly",
"permission": "full_access",
"previous_key_expires_at": "2026-09-04T09:14:00.000Z",
"rate_ceiling_per_minute": 600,
"request_count_30d": -9007199254740991,
"rotated_at": "2026-09-04T09:14:00.000Z",
"scopes": [],
"system": false,
"token": "as_abababababababababababababababababababababababababababababababab",
"token_prefix": "as_abababab"
}Then set the budget on it:
curl -sS -X PATCH https://api.agentisend.com/limits/keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \
-H "Authorization: Bearer $AGENTISEND_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"budget_per_period":500,"rate_ceiling_per_minute":20}'200
{
"api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
"budget_per_period": -9007199254740991,
"consumed_in_period": -9007199254740991,
"consumed_in_window": -9007199254740991,
"paused": false,
"paused_at": "2026-09-04T09:14:00.000Z",
"paused_reason": "example",
"period": "hourly",
"period_started_at": "2026-09-04T09:14:00.000Z",
"rate_ceiling_per_minute": -9007199254740991,
"rate_window_started_at": "2026-09-04T09:14:00.000Z",
"updated_at": "2026-09-04T09:14:00.000Z"
}The body is three optional fields:
{ "budget_per_period": 500, "rate_ceiling_per_minute": 20 }period is hourly, daily or monthly. budget_per_period counts sends in that period. rate_ceiling_per_minute is the separate burst ceiling. An API key can only lower its limits, and a shorter period is compared over 30 days: 500 a day is up to 15,000, far more than a new Free key's 5,000 a month, so a change like that is made by a person in the console. Passing null for either clears it.
Read the state back
GET /limits/keys/{id} returns budget_per_period, consumed_in_period, period_started_at, rate_ceiling_per_minute, consumed_in_window, and whether the key is paused. GET /limits/keys returns the same for every key on the account, plus each key's name, its last use and its current loop state.
What the agent sees at the ceiling
{
"error": {
"code": "agent_budget_exceeded",
"message": "This key has used 1 of its 1 recipients for the current monthly period. Each To, CC and BCC recipient counts as one email.",
"fix": "Wait for the period to reset — get_agent_budget and GET /limits/keys/:id both say when. Raising a budget is a person’s decision, made in the console; a key cannot raise its own.",
"docs_url": "https://agentisend.com/what-does-agent-budget-exceeded-mean#agent_budget_exceeded",
"retryable": false
}
}retryable is false, so a well-behaved client stops instead of spinning. Raising the budget is a human's call: there is no request an agent can make that lifts its own ceiling.
The account's plan inclusion is a second, separate ceiling. When that is spent the code is plan_limit_reached and sending pauses; nothing is auto-charged. On a paid plan an owner can turn overage on with a ceiling of their own; past that ceiling the code is overage_cap_reached.
Two ceilings a budget does not replace
A budget caps volume. It does not stop an agent that is repeating itself inside its budget, and it does not stop an agent a human wants stopped right now. Those are loop detection and the kill switch, POST /limits/kill-all.
Read next
- /email-for-ai-agents — every agent control in one page.
- /docs/guides/budgets-and-the-kill-switch — the guide, including what the console shows and how the two counters differ.