Webhooks · MachineMail Docs

Skip to content Skip to content

[01/30]List Webhooks in Inbox

Method Path Summary
GET /v0/inboxes/{inbox_id}/webhooks List Webhooks in Inbox
POST /v0/inboxes/{inbox_id}/webhooks Create Webhook in Inbox
GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id} Get Webhook in Inbox
PATCH /v0/inboxes/{inbox_id}/webhooks/{webhook_id} Update Webhook in Inbox
DELETE /v0/inboxes/{inbox_id}/webhooks/{webhook_id} Delete Webhook in Inbox
GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/deliveries List Deliveries in Inbox
POST /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/replay Replay Delivery in Inbox
GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/headers Get Webhook Headers in Inbox
PATCH /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/headers Update Webhook Headers in Inbox
POST /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/test Send Test Event in Inbox
GET /v0/pods/{pod_id}/webhooks List Webhooks in Pod
POST /v0/pods/{pod_id}/webhooks Create Webhook in Pod
GET /v0/pods/{pod_id}/webhooks/{webhook_id} Get Webhook in Pod
PATCH /v0/pods/{pod_id}/webhooks/{webhook_id} Update Webhook in Pod
DELETE /v0/pods/{pod_id}/webhooks/{webhook_id} Delete Webhook in Pod
GET /v0/pods/{pod_id}/webhooks/{webhook_id}/deliveries List Deliveries in Pod
POST /v0/pods/{pod_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/replay Replay Delivery in Pod
GET /v0/pods/{pod_id}/webhooks/{webhook_id}/headers Get Webhook Headers in Pod
PATCH /v0/pods/{pod_id}/webhooks/{webhook_id}/headers Update Webhook Headers in Pod
POST /v0/pods/{pod_id}/webhooks/{webhook_id}/test Send Test Event in Pod
GET /v0/webhooks List Webhooks
POST /v0/webhooks Create Webhook
GET /v0/webhooks/{webhook_id} Get Webhook
PATCH /v0/webhooks/{webhook_id} Update Webhook
DELETE /v0/webhooks/{webhook_id} Delete Webhook
GET /v0/webhooks/{webhook_id}/deliveries List Deliveries
POST /v0/webhooks/{webhook_id}/deliveries/{delivery_id}/replay Replay Delivery
GET /v0/webhooks/{webhook_id}/headers Get Webhook Headers
PATCH /v0/webhooks/{webhook_id}/headers Update Webhook Headers
POST /v0/webhooks/{webhook_id}/test Send Test Event

List Webhooks in Inbox

http

GET /v0/inboxes/{inbox_id}/webhooks

Same as List Webhooks (GET /v0/webhooks), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

Response

200 A page of webhooks (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

webhooks Webhook[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of webhooks is a Webhook:

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

event_types``("message.received" | "message.received.spam" | "message.received.quarantined" | "message.received.unauthenticated" | "message.received.blocked" | "message.sent" | "message.delivered" | "message.bounced" | "message.complained" | "message.rejected" | "domain.verified" | "domain.updated" | "inbox.created" | "inbox.expired" | "draft.sent" | "webhook.test" | "trusted_domain.created" | "trusted_domain.updated" | "trusted_domain.deleted")[]Required

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Status Meaning
400 Invalid request: error.type is validation and error.param names the field.
401 Missing, invalid, expired or revoked credential.
403 The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register).
404 Not found. Also returned for resources outside the credential scope.
500 Unexpected server error.

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "webhooks": [\
    {\
      "webhook_id": "whk_01k6x3c2jp0000f2p8rw4a7h9k",\
      "url": "https://example.com/webhooks/machinemail",\
      "event_types": ["message.received"],\
      "pod_ids": ["pod_01k6x2m9qd0001b8j4mr0w3d5f"],\
      "inbox_ids": ["agent@machinemail.dev"],\
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",\
      "inbox_id": "agent@machinemail.dev",\
      "secret": "whsec_0123456789abcdef",\
      "enabled": true,\
      "updated_at": "2026-10-01T12:00:00.000Z",\
      "created_at": "2026-10-01T12:00:00.000Z",\
      "client_id": "my-client-id",\
      "status": "active",\
      "header_names": ["string"],\
      "headers_updated_at": "2026-10-01T12:00:00.000Z"\
    }\
  ]
}

Create Webhook in Inbox

http

POST /v0/inboxes/{inbox_id}/webhooks

Same as Create Webhook (POST /v0/webhooks), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_create.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

Request body

Content type: application/json.

FieldDescription

url``stringRequired

Endpoint URL: a public http(s) URL (private and loopback addresses are rejected, and re-checked before every delivery).

event_types``("message.received" | "message.received.spam" | "message.received.quarantined" | "message.received.unauthenticated" | "message.received.blocked" | "message.sent" | "message.delivered" | "message.bounced" | "message.complained" | "message.rejected" | "domain.verified" | "domain.updated" | "inbox.created" | "inbox.expired" | "draft.sent" | "webhook.test" | "trusted_domain.created" | "trusted_domain.updated" | "trusted_domain.deleted")[]

Event types the webhook receives. Omit it or send an empty array to receive every event type except domain.updated and trusted_domain.*, which are sent only when listed.

client_id``string

Idempotency key: a create with a client_id already used in the organization returns that webhook with 200, or 409 when that webhook is outside the pod or inbox of the API key or route.

inbox_ids``string[]

Only deliver events of these inboxes.

pod_ids``string[]

Only deliver events of these pods.

headers``Record<string, string>

Custom HTTP headers sent with every delivery to this webhook (every attempt, retry, replay and test event), alongside the X-MachineMail-* headers, for example {"Authorization": "Bearer "} for an endpoint that requires one. Values are write-only: they are stored encrypted and no response returns them; reads list the names (header_names). The headers are not part of the signed payload: X-MachineMail-Signature covers the body only. At most 10 headers. Names are HTTP tokens of up to 64 characters, compared without regard to case; values are printable ASCII (no line breaks or control characters) of up to 4096 characters, with surrounding spaces removed, and names plus values total at most 8192 bytes. Reserved names are refused with 400: Host, Content-Length, Content-Type, Content-Encoding, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, Expect, User-Agent, Accept-Encoding, and every name starting with Proxy-, Sec-, X-MachineMail-, Svix- or Webhook-. Authorization and Cookie are allowed.

Response

200 A webhook with this client_id already exists; it is returned unchanged. (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

201 Created (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/webhooks/machinemail",
  "event_types": [\
    "message.received"\
  ]
}'

Response 200

{
  "webhook_id": "whk_01k6x3c2jp0000f2p8rw4a7h9k",
  "url": "https://example.com/webhooks/machinemail",
  "event_types": ["message.received"],
  "pod_ids": ["pod_01k6x2m9qd0001b8j4mr0w3d5f"],
  "inbox_ids": ["agent@machinemail.dev"],
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "secret": "whsec_0123456789abcdef",
  "enabled": true,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "client_id": "my-client-id",
  "status": "active",
  "header_names": ["string"],
  "headers_updated_at": "2026-10-01T12:00:00.000Z"
}

Get Webhook in Inbox

http

GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id}

Same as Get Webhook (GET /v0/webhooks/{webhook_id}), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Response

200 The webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Status Meaning
401 Missing, invalid, expired or revoked credential.
403 The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register).
404 Not found. Also returned for resources outside the credential scope.
500 Unexpected server error.

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Update Webhook in Inbox

http

PATCH /v0/inboxes/{inbox_id}/webhooks/{webhook_id}

Same as Update Webhook (PATCH /v0/webhooks/{webhook_id}), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

FieldDescription

Replaces the subscribed event types in full (not a merge). An empty array subscribes to every event type except domain.updated and trusted_domain.*, which are sent only when listed. Omit it to keep the types.

enabled``boolean

false disables the webhook: no new deliveries are queued (deliveries already queued are still attempted). true enables it again. Events that occurred while it was disabled are not delivered later.

add_inbox_ids``string[]

Inboxes to add to inbox_ids.

remove_inbox_ids``string[]

Inboxes to remove from inbox_ids.

add_pod_ids``string[]

Pods to add to pod_ids.

remove_pod_ids``string[]

Pods to remove from pod_ids.

url``string

New endpoint URL: a public http(s) URL.

headers``Record<string, string> | null

Replaces the custom delivery headers in full (not a merge): the webhook then sends exactly these. null or {} removes them all; omit it to keep them. To change one header and keep the others, use PATCH /v0/webhooks/{webhook_id}/headers. Values are write-only. At most 10 headers. Names are HTTP tokens of up to 64 characters, compared without regard to case; values are printable ASCII (no line breaks or control characters) of up to 4096 characters, with surrounding spaces removed, and names plus values total at most 8192 bytes. Reserved names are refused with 400: Host, Content-Length, Content-Type, Content-Encoding, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, Expect, User-Agent, Accept-Encoding, and every name starting with Proxy-, Sec-, X-MachineMail-, Svix- or Webhook-. Authorization and Cookie are allowed.

Response

200 The updated webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event_types": [\
    "message.received"\
  ],
  "url": "https://example.com/webhooks/machinemail"
}'

Response 200

Delete Webhook in Inbox

http

DELETE /v0/inboxes/{inbox_id}/webhooks/{webhook_id}

Same as Delete Webhook (DELETE /v0/webhooks/{webhook_id}), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_delete.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Response

200 Deleted (application/json)

FieldDescription

ok``trueRequired

Errors

Error bodies use the error envelope.

Example

Request

curl -X DELETE "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "ok": true
}

List Deliveries in Inbox

http

GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/deliveries

Same as List Deliveries (GET /v0/webhooks/{webhook_id}/deliveries), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

status``"pending" | "delivered" | "failed"

Only deliveries with this status.

Response

200 A page of deliveries (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

deliveries WebhookDelivery[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of deliveries is a WebhookDelivery:

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

event_type``"message.received" | "message.received.spam" | "message.received.quarantined" | "message.received.unauthenticated" | "message.received.blocked" | "message.sent" | "message.delivered" | "message.bounced" | "message.complained" | "message.rejected" | "domain.verified" | "domain.updated" | "inbox.created" | "inbox.expired" | "draft.sent" | "webhook.test" | "trusted_domain.created" | "trusted_domain.updated" | "trusted_domain.deleted"Required

Type of event. AgentMail has no message.received.quarantined, domain.updated, inbox.created, inbox.expired, draft.sent or webhook.test; MachineMail does not emit message.opened or calendar.event.*. domain.updated is sent whenever a DNS check changes the domain status or a record status (the change to VERIFIED also sends domain.verified). trusted_domain.created, .updated and .deleted (MachineMail) record changes to trusted domains. Webhooks and WebSocket subscriptions receive domain.updated and the trusted_domain.* types only when their event_types list them, while the SSE stream and the event log always include them.

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "deliveries": [\
    {\
      "delivery_id": "dlv_01k6x3f1ns0000j5s1vz7d0m2p",\
      "webhook_id": "whk_01k6x3c2jp0000f2p8rw4a7h9k",\
      "event_id": "evt_01k6x3g4pt0000k6t2wa8e1n3q",\
      "event_type": "message.received",\
      "attempt": 1,\
      "status": "pending",\
      "response_status": 1,\
      "response_body": "string",\
      "next_attempt_at": "2026-10-01T12:00:00.000Z",\
      "last_error": "string",\
      "delivered_at": "2026-10-01T12:00:00.000Z",\
      "created_at": "2026-10-01T12:00:00.000Z",\
      "updated_at": "2026-10-01T12:00:00.000Z"\
    }\
  ]
}

Replay Delivery in Inbox

http

POST /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/replay

Same as Replay Delivery (POST /v0/webhooks/{webhook_id}/deliveries/{delivery_id}/replay), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

delivery_id``stringRequired

ID of the delivery to replay.

Response

200 The new delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries/dlv_01k6x3f1ns0000j5s1vz7d0m2p/replay" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "delivery_id": "dlv_01k6x3f1ns0000j5s1vz7d0m2p",
  "webhook_id": "whk_01k6x3c2jp0000f2p8rw4a7h9k",
  "event_id": "evt_01k6x3g4pt0000k6t2wa8e1n3q",
  "event_type": "message.received",
  "attempt": 1,
  "status": "pending",
  "response_status": 1,
  "response_body": "string",
  "next_attempt_at": "2026-10-01T12:00:00.000Z",
  "last_error": "string",
  "delivered_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Get Webhook Headers in Inbox

http

GET /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/headers

Same as Get Webhook Headers (GET /v0/webhooks/{webhook_id}/headers), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Response

200 The header names (application/json)

FieldDescription

header_names``string[]Required

Names of the custom delivery headers of this webhook, as they were set. Values are never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "header_names": ["string"],
  "headers_updated_at": "2026-10-01T12:00:00.000Z"
}

Update Webhook Headers in Inbox

http

PATCH /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/headers

Same as Update Webhook Headers (PATCH /v0/webhooks/{webhook_id}/headers), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

Sets, replaces or removes custom delivery headers; the headers you do not name are unchanged. Give at least one of headers (each name is added, or replaces the value of the header of that name in any case) or remove_headers. A name cannot be both set and removed in one request.

FieldDescription

headers``Record<string, string>

remove_headers``string[]

Names of custom headers to remove (any case). Names that are not set are ignored.

Response

204 Updated

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Send Test Event in Inbox

http

POST /v0/inboxes/{inbox_id}/webhooks/{webhook_id}/test

Same as Send Test Event (POST /v0/webhooks/{webhook_id}/test), limited to the inbox.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

inbox_id``stringRequired

ID of the inbox.

webhook_id``stringRequired

ID of the webhook.

Response

200 The test delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/test" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

List Webhooks in Pod

http

GET /v0/pods/{pod_id}/webhooks

Same as List Webhooks (GET /v0/webhooks), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

Response

200 A page of webhooks (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

webhooks Webhook[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of webhooks is a Webhook:

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Create Webhook in Pod

http

POST /v0/pods/{pod_id}/webhooks

Same as Create Webhook (POST /v0/webhooks), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_create.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

Request body

Content type: application/json.

FieldDescription

url``stringRequired

Endpoint URL: a public http(s) URL (private and loopback addresses are rejected, and re-checked before every delivery).

client_id``string

inbox_ids``string[]

Only deliver events of these inboxes.

pod_ids``string[]

Only deliver events of these pods.

headers``Record<string, string>

Response

200 A webhook with this client_id already exists; it is returned unchanged. (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

201 Created (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/webhooks/machinemail",
  "event_types": [\
    "message.received"\
  ]
}'

Response 200

Get Webhook in Pod

http

GET /v0/pods/{pod_id}/webhooks/{webhook_id}

Same as Get Webhook (GET /v0/webhooks/{webhook_id}), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Response

200 The webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Update Webhook in Pod

http

PATCH /v0/pods/{pod_id}/webhooks/{webhook_id}

Same as Update Webhook (PATCH /v0/webhooks/{webhook_id}), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

FieldDescription

enabled``boolean

add_inbox_ids``string[]

Inboxes to add to inbox_ids.

remove_inbox_ids``string[]

Inboxes to remove from inbox_ids.

add_pod_ids``string[]

Pods to add to pod_ids.

remove_pod_ids``string[]

Pods to remove from pod_ids.

url``string

New endpoint URL: a public http(s) URL.

headers``Record<string, string> | null

Response

200 The updated webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event_types": [\
    "message.received"\
  ],
  "url": "https://example.com/webhooks/machinemail"
}'

Response 200

Delete Webhook in Pod

http

DELETE /v0/pods/{pod_id}/webhooks/{webhook_id}

Same as Delete Webhook (DELETE /v0/webhooks/{webhook_id}), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_delete.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Response

200 Deleted (application/json)

FieldDescription

ok``trueRequired

Errors

Error bodies use the error envelope.

Example

Request

curl -X DELETE "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "ok": true
}

List Deliveries in Pod

http

GET /v0/pods/{pod_id}/webhooks/{webhook_id}/deliveries

Same as List Deliveries (GET /v0/webhooks/{webhook_id}/deliveries), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

status``"pending" | "delivered" | "failed"

Only deliveries with this status.

Response

200 A page of deliveries (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

deliveries WebhookDelivery[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of deliveries is a WebhookDelivery:

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Replay Delivery in Pod

http

POST /v0/pods/{pod_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/replay

Same as Replay Delivery (POST /v0/webhooks/{webhook_id}/deliveries/{delivery_id}/replay), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

delivery_id``stringRequired

ID of the delivery to replay.

Response

200 The new delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries/dlv_01k6x3f1ns0000j5s1vz7d0m2p/replay" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Get Webhook Headers in Pod

http

GET /v0/pods/{pod_id}/webhooks/{webhook_id}/headers

Same as Get Webhook Headers (GET /v0/webhooks/{webhook_id}/headers), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Response

200 The header names (application/json)

FieldDescription

header_names``string[]Required

Names of the custom delivery headers of this webhook, as they were set. Values are never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "header_names": ["string"],
  "headers_updated_at": "2026-10-01T12:00:00.000Z"
}

Update Webhook Headers in Pod

http

PATCH /v0/pods/{pod_id}/webhooks/{webhook_id}/headers

Same as Update Webhook Headers (PATCH /v0/webhooks/{webhook_id}/headers), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

FieldDescription

headers``Record<string, string>

remove_headers``string[]

Names of custom headers to remove (any case). Names that are not set are ignored.

Response

204 Updated

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Send Test Event in Pod

http

POST /v0/pods/{pod_id}/webhooks/{webhook_id}/test

Same as Send Test Event (POST /v0/webhooks/{webhook_id}/test), limited to the pod.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

pod_id``stringRequired

ID of the pod.

webhook_id``stringRequired

ID of the webhook.

Response

200 The test delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/test" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

List Webhooks

http

GET /v0/webhooks

With an organization credential, every webhook of the organization, paginated. With a pod or inbox credential (or under a scoped path), the webhooks in that scope from the newest 500, in one page without next_page_token.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

Response

200 A page of webhooks (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

webhooks Webhook[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of webhooks is a Webhook:

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Status Meaning
400 Invalid request: error.type is validation and error.param names the field.
401 Missing, invalid, expired or revoked credential.
403 The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register).
500 Unexpected server error.

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Create Webhook

http

POST /v0/webhooks

The response includes secret (whsec_...), the key of the X-MachineMail-Signature HMAC. See the webhooks section of this document for the request MachineMail sends for each event type.

Under /v0/pods/{pod_id} or /v0/inboxes/{inbox_id}, or with a pod- or inbox-scoped credential, the webhook belongs to that pod or inbox (pod_id, inbox_id) and never receives events outside it.

A webhook delivers no event its creator could not read: each listed event type needs its read permission (message.* needs message_read, inbox.*``inbox_read, domain.*``domain_read, draft.*``draft_read, webhook.test``webhook_read), else 403. An empty event_types from a credential without all of them is stored as the types it may read (403 when there are none).

Custom request headers in headers are sent with every delivery (for example Authorization: Bearer <token> for an endpoint that requires it). Their values are write-only: responses list only header_names.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_create.

Request body

Content type: application/json.

FieldDescription

url``stringRequired

Endpoint URL: a public http(s) URL (private and loopback addresses are rejected, and re-checked before every delivery).

client_id``string

inbox_ids``string[]

Only deliver events of these inboxes.

pod_ids``string[]

Only deliver events of these pods.

headers``Record<string, string>

Response

200 A webhook with this client_id already exists; it is returned unchanged. (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

201 Created (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Status Meaning
400 Invalid request: error.type is validation and error.param names the field.
401 Missing, invalid, expired or revoked credential.
403 The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account_suspended: error.message says what still works; do not retry or re-register).
409 Conflicts with an existing resource.
500 Unexpected server error.

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/webhooks" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/webhooks/machinemail",
  "event_types": [\
    "message.received"\
  ]
}'

Response 200

Get Webhook

http

GET /v0/webhooks/{webhook_id}

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Response

200 The webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Update Webhook

http

PATCH /v0/webhooks/{webhook_id}

Fields you omit are unchanged. Webhooks are never disabled automatically after failed deliveries; enabled: false is the only way to disable one. New event_types follow the same permission rule as POST /v0/webhooks, and changing url needs the read permission of every event type the webhook delivers (403 otherwise).

headers replaces the custom delivery headers in full, null or {} removes them, and omitting it keeps them. While a webhook has custom headers, changing url to another origin (scheme, host or port) needs headers in the same request (400 otherwise), so header values never follow the webhook to a new server unless you send them again.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

FieldDescription

enabled``boolean

add_inbox_ids``string[]

Inboxes to add to inbox_ids.

remove_inbox_ids``string[]

Inboxes to remove from inbox_ids.

add_pod_ids``string[]

Pods to add to pod_ids.

remove_pod_ids``string[]

Pods to remove from pod_ids.

url``string

New endpoint URL: a public http(s) URL.

headers``Record<string, string> | null

Response

200 The updated webhook (application/json)

FieldDescription

webhook_id``stringRequired

ID of the webhook.

url``stringRequired

URL of the webhook endpoint.

Event types the webhook receives. Empty: every event type except domain.updated and trusted_domain.*, which are sent only when listed.

pod_ids``string[]

Only events of these pods. Absent: every pod in scope.

inbox_ids``string[]

Only events of these inboxes. Absent: every inbox in scope.

pod_id``string

Set when the webhook was created with a pod-scoped credential (or under /v0/pods/{pod_id}): it never receives events outside that pod.

inbox_id``string

Set when the webhook was created with an inbox-scoped credential (or under /v0/inboxes/{inbox_id}): it only receives events of that inbox.

secret``stringRequired

Signing secret (whsec_...) for X-MachineMail-Signature. Returned on every read.

enabled``booleanRequired

Whether new events are delivered. Webhooks are never disabled automatically.

updated_at``string (date-time)Required

Time at which the webhook was last updated.

created_at``string (date-time)Required

Time at which the webhook was created.

client_id``string

Client ID given at creation (idempotency key).

status``"active" | "disabled"Required

active or disabled; mirrors enabled.

header_names``string[]Required

Names of the custom delivery headers (headers), as they were set; empty when there are none. Values are write-only and never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event_types": [\
    "message.received"\
  ],
  "url": "https://example.com/webhooks/machinemail"
}'

Response 200

Delete Webhook

http

DELETE /v0/webhooks/{webhook_id}

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_delete.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Response

200 Deleted (application/json)

FieldDescription

ok``trueRequired

Errors

Error bodies use the error envelope.

Example

Request

curl -X DELETE "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "ok": true
}

List Deliveries

http

GET /v0/webhooks/{webhook_id}/deliveries

Delivery attempts of the webhook, one per event (a replay is a new delivery).

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Query parameters

FieldDescription

limit``integer

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

page_token``string

next_page_token from the previous page.

ascending``boolean

Sort oldest first.

status``"pending" | "delivered" | "failed"

Only deliveries with this status.

Response

200 A page of deliveries (application/json)

FieldDescription

count``integerRequired

Number of items returned.

limit``integer

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

next_page_token``string

Page token for pagination. Absent on the last page.

deliveries WebhookDelivery[] Required

Ordered by created_at, newest first unless ascending is set.

Each item of deliveries is a WebhookDelivery:

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Replay Delivery

http

POST /v0/webhooks/{webhook_id}/deliveries/{delivery_id}/replay

Queues a new delivery of the same event to the webhook and attempts it right away, even when the webhook is disabled. Returns the new delivery after that attempt.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

delivery_id``stringRequired

ID of the delivery to replay.

Response

200 The new delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/deliveries/dlv_01k6x3f1ns0000j5s1vz7d0m2p/replay" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

Get Webhook Headers

http

GET /v0/webhooks/{webhook_id}/headers

Names of the custom HTTP headers sent with every delivery to this webhook. Values are write-only and never returned.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_read.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Response

200 The header names (application/json)

FieldDescription

header_names``string[]Required

Names of the custom delivery headers of this webhook, as they were set. Values are never returned.

headers_updated_at``string (date-time)

When the custom headers were last set or changed. Absent when they never were.

Errors

Error bodies use the error envelope.

Example

Request

curl "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

{
  "header_names": ["string"],
  "headers_updated_at": "2026-10-01T12:00:00.000Z"
}

Update Webhook Headers

http

PATCH /v0/webhooks/{webhook_id}/headers

Sets, replaces or removes custom delivery headers in one atomic change; headers you do not name keep their values. To replace the whole set (or clear it), use headers on PATCH /v0/webhooks/{webhook_id}. Values remain write-only.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Request body

Content type: application/json.

FieldDescription

headers``Record<string, string>

remove_headers``string[]

Names of custom headers to remove (any case). Names that are not set are ignored.

Response

204 Updated

Errors

Error bodies use the error envelope.

Example

Request

curl -X PATCH "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/headers" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Send Test Event

http

POST /v0/webhooks/{webhook_id}/test

Records a webhook.test event and delivers it to this webhook only (whatever its event_types, even when disabled), then returns the delivery after the first attempt.

Authentication:Authorization: Bearer <api key> or the dashboard mm_session cookie. Permission: webhook_update.

Path parameters

FieldDescription

webhook_id``stringRequired

ID of the webhook.

Response

200 The test delivery (application/json)

FieldDescription

delivery_id``stringRequired

ID of the delivery (X-MachineMail-Delivery-Id).

webhook_id``stringRequired

ID of the webhook.

event_id``stringRequired

ID of the event (X-MachineMail-Event-Id).

attempt``integerRequired

Number of attempts so far.

status``"pending" | "delivered" | "failed"Required

pending until a 2xx response (delivered), or failed when retries stop (5 days after the event) or the webhook or event was deleted.

response_status``integer

HTTP status of the last attempt.

response_body``string

First 1024 bytes of the last response body.

next_attempt_at``string (date-time)

When the next attempt is due, while pending.

last_error``string

Error of the last failed attempt (HTTP 500, a network error).

delivered_at``string (date-time)

When the delivery succeeded.

created_at``string (date-time)Required

When the delivery was queued.

updated_at``string (date-time)Required

Last change to the delivery.

Errors

Error bodies use the error envelope.

Example

Request

curl -X POST "https://api.machinemail.dev/v0/webhooks/whk_01k6x3c2jp0000f2p8rw4a7h9k/test" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"

Response 200

On this page

List Webhooks in Inbox Create Webhook in Inbox Get Webhook in Inbox Update Webhook in Inbox Delete Webhook in Inbox List Deliveries in Inbox Replay Delivery in Inbox Get Webhook Headers in Inbox Update Webhook Headers in Inbox Send Test Event in Inbox List Webhooks in Pod Create Webhook in Pod Get Webhook in Pod Update Webhook in Pod Delete Webhook in Pod List Deliveries in Pod Replay Delivery in Pod Get Webhook Headers in Pod Update Webhook Headers in Pod Send Test Event in Pod List Webhooks Create Webhook Get Webhook Update Webhook Delete Webhook List Deliveries Replay Delivery Get Webhook Headers Update Webhook Headers Send Test Event

100% readTop