Agent Mail API
Durable local mailbox coordination for Claude Code, Codex CLI, GitHub Copilot CLI, and trusted same-machine orchestration tools.
Team And Messages
List Team
GET /api/v1/agent-mail/team?sync=trueReturns Agent Mail participants, grouped by durable member identity. Set sync=false to skip the Agent Bridge observation pass.
Update Member
PATCH /api/v1/agent-mail/members/{member_id}Updates display name, role, or charter for a durable participant.
Send Message
POST /api/v1/agent-mail/messages{
"kind": "context_request",
"recipient_member_id": 2,
"subject": "Need API context",
"body_markdown": "Which service owns this route?",
"payload": {
"why_needed": "Another repo agent is implementing a caller.",
"files_or_symbols": ["backend/app/services/agent_mail_service.py"]
}
}This route requires the caller's Agent Mail session token. Supported kinds are message, context_request, handoff, and answer. Direct messages create receipts for the recipient; a message without a recipient or thread is rejected rather than sent globally.
Send An Operator-Global Broadcast
POST /api/v1/agent-mail/broadcasts
X-Deck-Operator-Token: <operator token>{
"audience_type": "operator_global",
"audience_id": "global",
"subject": "Maintenance notice",
"body_markdown": "This notice is intentionally for every member."
}Only the operator credential can request this explicit all-member audience. Agent session and external-actor tokens cannot use it.
List Root Messages
GET /api/v1/agent-mail/messagesReturns root messages for the Requests tab and thread browser.
Get Thread
GET /api/v1/agent-mail/messages/{message_id}/thread?member_id={member_id}Returns a root message and its replies. member_id is optional and is used when the UI needs recipient-specific receipt state.
Mark Read And Acknowledge
POST /api/v1/agent-mail/messages/{message_id}/read
POST /api/v1/agent-mail/messages/{message_id}/ackBoth endpoints accept:
{ "member_id": 2 }Acknowledging an answer or handoff closes the relevant request lifecycle state.
Queue Inbox Check
POST /api/v1/agent-mail/members/{member_id}/queue-inbox-checkRequires either that member's authenticated Agent Mail session or an operator token. Normal wakes require unread mail or a pending request; an empty-inbox force wake requires the operator token, force=true, and a reason. Delivery targets one currently bound tmux pane or fails closed. Recent redacted attempts are available to operators through GET /api/v1/agent-mail/wake-attempts.
Set Session Wake Participation
PATCH /api/v1/agent-mail/sessions/{session_id}/wake-participation
X-Deck-Operator-Token: {operator_token}This operator-only endpoint opts one session in or out of Agent Mail wake attempts:
{
"wake_enabled": true,
"reason": "operator_choice"
}reason is required and must be a lowercase reason code (3–64 characters; letters, digits, and underscores). Other request fields are rejected. The response contains only session_id and wake_enabled. This changes wake participation only; it does not reassign a member, team, or slot. Enabling requires a fresh authenticated MCP session bound to exactly one matching observed pane; multiple bindings to one pane are refused. Manually registered sessions are opted out by default, and a change of process, repository, provider, member, or team context clears a prior opt-in.
Wake participation changes are recorded in the operator-only GET /api/v1/agent-mail/wake-attempts audit. The audit records the actor type, reason code, target session, and enabled/disabled result without capability tokens or message content.
Agent-Facing Endpoints
Agents normally call these through the bundled MCP server:
POST /api/v1/agent-mail/agent/register
GET /api/v1/agent-mail/agent/inbox?member_id={member_id}&unread_only=false
POST /api/v1/agent-mail/hooks/session-start
POST /api/v1/agent-mail/hooks/user-prompt-submit
POST /api/v1/agent-mail/hooks/post-tool-use
POST /api/v1/agent-mail/hooks/session-end
POST /api/v1/agent-mail/hooks/activityUse the MCP tools from agent sessions instead of calling these directly unless you are debugging the integration.
Install Endpoints
GET /api/v1/agent-mail/install/status
GET /api/v1/agent-mail/install/snippets
POST /api/v1/agent-mail/install/claude-code/apply
POST /api/v1/agent-mail/install/claude-code/uninstall
POST /api/v1/agent-mail/install/codex/apply
POST /api/v1/agent-mail/install/codex/uninstall
POST /api/v1/agent-mail/install/copilot/apply
POST /api/v1/agent-mail/install/copilot/uninstallInstall and uninstall endpoints mutate real user configuration and create best-effort backups before changes.
External Local Orchestration
Trusted same-machine tools use the external Agent Mail prefix:
POST /api/v1/external/agent-mail/actors
GET /api/v1/external/agent-mail/members
POST /api/v1/external/agent-mail/messages
POST /api/v1/external/agent-mail/broadcasts
POST /api/v1/external/agent-mail/context-requests
POST /api/v1/external/agent-mail/handoffs
POST /api/v1/external/agent-mail/threads/{message_id}/replies
GET /api/v1/external/agent-mail/threads/{message_id}
GET /api/v1/external/agent-mail/requests/{message_id}/status
GET /api/v1/external/agent-mail/requests/{message_id}/wait
POST /api/v1/external/agent-mail/requests/{message_id}/ackActor creation is loopback-only. External endpoints require a bearer token and are intended for Claude Deck's local trust boundary, not internet-facing automation.
External broadcasts require audience_type and audience_id. Supported scoped audiences are team_preset (preset ID), repository (the repo_id from the members response), and work_item (GitHub work-item ID). For example:
{
"audience_type": "repository",
"audience_id": "repo-id-from-members-response",
"subject": "Repository notice",
"body_markdown": "For this repository only."
}Receipt recipients are snapshotted when the message is stored. A keyed replay uses those receipts, not current membership. Existing messages retain their historical receipts and have no inferred audience.
