Agents

Create, read, list, and tombstone agent mailboxes (master key required).

An agent is one Durable-Object-backed mailbox. Each agent has a 12-character lowercase id, an address on ${DEFAULT_EMAIL_DOMAIN}, and its own per-agent API key. Named agents use a slug of the name as the address local part; unnamed agents use the generated id.

All routes on this page require the master key unless explicitly noted.

Create an agent

  • Method: POST
  • Path: /agents
  • Auth: master key only

Request body

{
  "name": "Customer Success"
}
FieldTypeRequiredDescription
namestringNoDisplay name (1–120 chars). Defaults to "Untitled" if omitted.

Body cap: 4 KiB UTF-8 bytes.

Response 201 Created

{
  "id": "abc123def456",
  "email": "customer-success@agents.yourdomain.com",
  "name": "Customer Success",
  "api_key": "rA9-...long-base64url",
  "created_at": 1730000000
}

api_key is shown exactly once — only its HMAC hash is stored.

Errors

  • 400 — invalid JSON, body too large, or name outside 1–120 chars.
  • 401 — missing or wrong bearer token.

List agents

  • Method: GET
  • Path: /agents
  • Auth: master key only

Response 200 OK

{
  "agents": [
    {
      "id": "abc123def456",
      "email": "abc123def456@agents.yourdomain.com",
      "name": "Customer Success",
      "created_at": 1730000000
    }
  ]
}

Tombstoned agents (deleted_at IS NOT NULL) are filtered out.

Get one agent

  • Method: GET
  • Path: /agents/:id
  • Auth: master key, or this agent's own per-agent key

Path parameters

ParameterTypeDescription
idstring12 lowercase alphanumeric chars.

Response 200 OK

{
  "id": "abc123def456",
  "email": "abc123def456@agents.yourdomain.com",
  "name": "Customer Success",
  "created_at": 1730000000
}

Errors

  • 401 — missing or invalid bearer.
  • 403 — bearer is a per-agent key for a different agent.
  • 404 — id doesn't match any non-tombstoned agent.

GET /me

  • Method: GET
  • Path: /me
  • Auth: any per-agent key

Convenience route that returns the agent corresponding to the bearer token. Useful for the dashboard's "verify key works" probe.

Response 200 OK

{
  "id": "abc123def456",
  "email": "abc123def456@agents.yourdomain.com",
  "name": "Customer Success"
}

Delete an agent

  • Method: DELETE
  • Path: /agents/:id
  • Auth: master key only

The Worker:

  1. Looks up the agent and 404s if it's gone or already tombstoned.
  2. Calls markDeleted() on the per-agent Durable Object: sets a sticky deleted='1' flag in the agent's _meta table and truncates all per-agent SQLite tables (messages, threads, message_threads, message_recipients, webhook_attempts).
  3. Hard-deletes the agent's webhooks from D1 (the soft-delete on agents means the prior ON DELETE CASCADE no longer fires).
  4. Sets agents.deleted_at to the current Unix timestamp.

After delete, the agent's old API key returns 401, all /agents/:id/* routes return 404, and inbound mail to its address is dropped (the email handler can't resolve a tombstoned agent).

Response 204 No Content

Errors

  • 401 — missing or non-master bearer.
  • 404 — id unknown or already tombstoned.

Key rotation

There is no in-place rotate endpoint yet. To rotate a per-agent key:

  1. Note the agent's id and any state you care about (its message history is in DO storage and survives only as long as the agent does — read it first if you need to keep it).
  2. DELETE /agents/:id with the master key. The Worker tombstones the agent and purges its DO storage (see above).
  3. POST /agents with { "name": "..." } — Cloudflare assigns a fresh 12-char id, and you get a fresh api_key.
  4. Update consumers to use the new id + api_key. The old id will not be re-used unless generateAgentId collides on a 36^12 space (effectively impossible).

To rotate the master key, run wrangler secret put MASTER_KEY with a new value and wrangler deploy. Older requests using the old key will fail at the next request after the deploy propagates (~30s).