Skip to content

Questions · Published 2026-09-29 · Updated 2026-09-29 · AgentiSend

How do I let an AI agent send email?

To let an AI agent send email, create a key, set a ceiling the key cannot raise, then send. A refusal comes back with a code and a fix.

To let an AI agent send email, make three requests, in this order. POST /api-keys creates a key with permission sending_access. PATCH /limits/keys/{id} sets budget_per_period, period, and rate_ceiling_per_minute. POST /emails is the send. The agent cannot raise its own ceiling. A refusal carries code, message, fix, and retryable, and the agent stops when retryable is false.

The three requests

POST /api-keys returns the secret once. Keep it on that agent alone. The default budget on a new key is the plan's monthly inclusion, which on the Free plan is 1,000 emails a month. A person tightens it before handing the key over.

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": 1000,
  "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",
  "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"
}
Response

PATCH /limits/keys/{id} is the ceiling. An API key may lower its own budget. Raising one is a person's decision, made in the console. A key that sends a higher budget_per_period is answered human_action_required. Read the ceiling back with GET /limits/keys/{id}.

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"
}
Response

POST /emails is the send. Before a domain is verified, onboarding@agentisend.com delivers only to member sign-in addresses, and an address at simulator.agentisend.com costs nothing and reaches nobody.

curl -sS -X POST https://api.agentisend.com/emails \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"from":"billing@yourdomain.com","to":"delivered@simulator.agentisend.com","subject":"Your receipt","text":"Thanks — the details are attached."}'
201
{
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "simulated": true,
  "warnings": []
}
Response

What a refusal looks like

A send past the budget answers agent_budget_exceeded. A held send answers approval_required. A paused key answers kill_switch_active. Each page quotes the catalogue message and the fix. The agent quotes code and fix and does not invent a retry when retryable is false.

How do I put a spending limit on an AI agent? is the ceiling in more detail. How do I stop an AI agent from sending too many emails? is the same door from the other side.

Next

Written by the AgentiSend team.