View as markdown ↓

Quickstart

Postfleet is an email API built for autonomous agents. This page takes you from zero to a sent email, an inbound webhook, and an MCP connection.

Every endpoint lives under the canonical /api/v1/ prefix and authenticates with a bearer pf_ key. See Authentication for the full key model.

1. Get an API key

API keys are created and revoked in the dashboard (this is a control-plane action — it is not exposed over the data-plane API). A key is a bearer secret that starts with pf_.

Keys carry a scope:

  • bootstrap — provision-only. Can create mailboxes, nothing else.
  • api / mcp — the working data-plane scopes: send, read, and manage drafts.

Send every request with the key in the Authorization header:

Authorization: Bearer pf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2. Create a mailbox

A mailbox is an email address your agent owns. Create one with an account-wide key (mailbox-bound keys cannot create mailboxes):

curl -X POST https://your-app.example.com/api/v1/mailboxes \
  -H "Authorization: Bearer pf_..." \
  -H "Content-Type: application/json" \
  -d '{"slug": "support"}'

Response (201):

{ "id": "b1a2...", "address": "agent-support@your-domain.example" }

3. Send your first email

POST /api/v1/send takes exactly one recipient. mailbox_id and text are required; to is required unless you set reply_to_message_id, and subject is optional.

curl -X POST https://your-app.example.com/api/v1/send \
  -H "Authorization: Bearer pf_..." \
  -H "Content-Type: application/json" \
  -d '{
    "mailbox_id": "b1a2...",
    "to": "person@example.com",
    "subject": "Hello from my agent",
    "text": "This email was sent by an autonomous agent."
  }'

Success (201):

{ "id": "m_123...", "thread_id": "t_456...", "provider_message_id": "prov_789..." }

Pass an optional client_id to make the send idempotent — a retried request with the same client_id and body replays the stored result instead of sending twice. See Sending & idempotency.

If the mailbox requires human approval, POST /api/v1/send returns 202 {"draft_id": "...", "status": "pending_approval"} instead of a message id. That is not a failure and must not be retried — the email goes out once a human approves it. See Drafts & human-in-the-loop.

4. Receive inbound mail via webhook

Configure a webhook URL and signing secret in the dashboard. When mail arrives, Postfleet POSTs a message.received event to your endpoint, signed with a custom HMAC:

  • x-postfleet-signature — hex HMAC-SHA256(secret, "{timestamp}.{rawBody}")
  • x-postfleet-timestamp — millisecond epoch, part of the signed payload

Verify every event before trusting it, and reject stale timestamps (>5 minutes). Deliveries are at-least-once, so dedupe on the payload's event_id. The full recipe and a copy-pasteable verification snippet are in Webhooks.

5. Connect over MCP (one-liner)

Point any MCP client at the Postfleet MCP server and pass your key as a bearer header:

{
  "mcpServers": {
    "postfleet": {
      "url": "https://your-app.example.com/api/mcp",
      "headers": { "Authorization": "Bearer pf_..." }
    }
  }
}

This exposes tools like send_email, reply_email, list_inbox, read_email, wait_for_email, and the draft tools. See MCP setup.

Where to next