Features
Approvals for agent email
Let agents draft emails, and have a human approve every message before it leaves.
Agents are great at drafting email, but you may not want them to hit send on their own. With approvals turned on, outgoing mail from agents waits until an owner or admin approves it.
Turn it on — per agent
Approvals are configured per agent, so a trusted CI bot can keep sending freely while a new sales agent has to ask first.
- API keys: Agents & API → API keys → Approval switch, or tick Require my approval before this agent sends email when creating a key. Via API:
PATCH /api/v1/keys/{id}with{"require_approval": true}. - OAuth apps (claude.ai, Claude Desktop, …): the consent screen has Ask me before this app sends email, checked by default.
Team members signed in to the dashboard always send directly.
What happens when an agent sends
- The agent calls
send_email(MCP) orPOST /api/v1/inboxes/{id}/send. - Instead of sending, Squadmail stores the draft with status
pendingand returns it with HTTP202. - Owners and admins see it instantly: a live notification in the dashboard, a counter on Approvals in the sidebar, and an
outbound.pendingwebhook (perfect for Slack or your on-call tool). - They review it, can edit subject and text, add a note, and Approve & send or Reject.
- The agent learns the outcome with
get_send_status(MCP) orGET /api/v1/outbox/{id}?wait=60.
Requests nobody decides on expire after 7 days.
⚙ send_email { inbox: "sales@acme-agents.com", to: ["lead@example.org"],
subject: "Following up", text: "…", reason: "Lead asked for pricing" }
→ { id: "out_…", status: "pending", message: "Waiting for human approval…" }
⚙ get_send_status { id: "out_…", wait_seconds: 120 }
→ { status: "sent", decided_by: "…", decision_note: "Looks good" } Tip: ask your agent to fill in reason. It is shown to the approver right above the draft.
Email notifications (optional)
In-app notifications and webhooks are free. If you also want an email with a one-click Review & approve link, enable Also notify owners & admins by email. Each notification counts as a sent email, so it is off by default. The link is signed and only works for that one request.
Statuses
| Status | Meaning |
|---|---|
pending | Waiting for a decision |
sent | Approved (or no approval needed) and delivered |
rejected | A human said no — see decision_note |
failed | Approved, but delivery failed — see error |
expired | Nobody decided within 7 days |
Webhooks
outbound.pending, outbound.sent, outbound.rejected and outbound.failed carry the full request in data.outbound.