Latest API and SDK updates. Subscribe via RSS · Discord

Summary

You can now create and manage webhooks scoped to a single pod or inbox from dedicated endpoints, instead of only filtering an organization-level webhook with pod_ids / inbox_ids. The scope comes from the path, so pod- and inbox-scoped API keys can manage just their own webhooks.

What’s new?

New endpoints:

  • GET|POST /v0/pods/:pod_id/webhooks and GET|PATCH|DELETE /v0/pods/:pod_id/webhooks/:webhook_id - Manage webhooks scoped to a pod.
  • GET|POST /v0/inboxes/:inbox_id/webhooks and GET|PATCH|DELETE /v0/inboxes/:inbox_id/webhooks/:webhook_id - Manage webhooks scoped to an inbox.

Behavior:

  • A pod-scoped webhook receives events for the whole pod, and can be narrowed to specific inboxes in the pod with inbox_ids. You don’t pass pod_ids — the pod is the path.
  • An inbox-scoped webhook is fixed to that inbox; only its event_types can be changed.
  • A scoped webhook must always keep at least one pod or inbox subscription.

Use cases

Build agents that:

  • Give each tenant’s pod-scoped API key its own webhook, isolated from other tenants
  • Register a webhook for a single high-volume inbox without touching org-wide delivery
  • Let an inbox-scoped key manage only its own event subscriptions
1from agentmail import AgentMail
2
3client = AgentMail(api_key="your-api-key")
4
5# webhook scoped to a single pod
6client.pods.webhooks.create(
7 pod_id="pod_abc123",
8 url="https://your-server.com/webhooks",
9 event_types=["message.received"],
10)

Summary

Agents can now create reply, reply-all, and forward drafts directly from a message, instead of rebuilding the recipients, subject, and threading by hand. The draft is saved rather than sent, so a human can review it before it goes out — then send it with Send Draft. This makes human-in-the-loop review and scheduled follow-ups a first-class part of the reply flow.

What’s new?

New endpoints:

  • POST /v0/inboxes/:inbox_id/messages/:message_id/draft-reply - Create a draft replying to the sender. Set reply_all to address the whole thread.
  • POST /v0/inboxes/:inbox_id/messages/:message_id/draft-reply-all - Create a draft replying to everyone on the thread.
  • POST /v0/inboxes/:inbox_id/messages/:message_id/draft-forward - Create a draft forwarding the message.

New features:

  • Derived from the source message: recipients, subject, and threading (in_reply_to / references) are taken from the original message, so you only supply your note.
  • Forwards: the original body and attachments are merged in at send time; recipients are optional, so a forward draft can be saved now and addressed later.
  • Composable: pass send_at to schedule the draft, or review and send it later with inboxes.drafts.send.

Changes:

  • Draft responses now include forward_of, the ID of the message a forward draft was created from.

Use cases

Build agents that:

  • Draft a reply for human approval before anything leaves the inbox
  • Forward a flagged message to a teammate, then send once reviewed
  • Schedule a reply-all for the recipient’s business hours
  • Prepare a response while still gathering data, and finalize it later
1from agentmail import AgentMail
2
3client = AgentMail(api_key="your-api-key")
4
5# create a reply draft from a received message
6draft = client.inboxes.messages.draft_reply(
7 inbox_id="agent@agentmail.to",
8 message_id="<message-id@agentmail.to>",
9 text="Thanks — looping in my manager for approval.",
10)
11
12# review, then send when ready
13client.inboxes.drafts.send(inbox_id="agent@agentmail.to", draft_id=draft.draft_id)

See the Drafts guide for the full reply and forward flow.