For agents

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":"yourdomain.com","permission":"sending_access"}'
201
{
  "budget_per_period": "string",
  "created_at": "2026-09-04T09:14:00Z",
  "domain_scope": "string",
  "expires_at": "2026-09-04T09:14:00Z",
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "last_used_at": "2026-09-04T09:14:00Z",
  "name": "yourdomain.com",
  "period": "hourly"
}
Response

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)"
200
{
  "api_key_id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "budget_per_period": "string",
  "consumed_in_period": 1,
  "consumed_in_window": 1,
  "paused": true,
  "paused_at": "2026-09-04T09:14:00Z",
  "paused_reason": "string",
  "period": "hourly"
}
Response

The body is three optional fields:

{ "budget_per_period": 500, "period": "daily", "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. 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": "Key budget for the current period is exhausted.",
    "fix": "Raise budget_per_period via PATCH /limits/keys/:id, or wait for the period to reset.",
    "docs_url": "https://agentisend.com/docs/errors",
    "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.

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.