Skip to content
machinemail

API Keys

Organization, pod and inbox scoped keys.

MethodPathSummary
GET/v0/api-keysList API Keys
POST/v0/api-keysCreate API Key
GET/v0/api-keys/{api_key_id}Get API Key
PATCH/v0/api-keys/{api_key_id}Update API Key
DELETE/v0/api-keys/{api_key_id}Delete API Key
GET/v0/inboxes/{inbox_id}/api-keysList API Keys in Inbox
POST/v0/inboxes/{inbox_id}/api-keysCreate API Key in Inbox
GET/v0/inboxes/{inbox_id}/api-keys/{api_key_id}Get API Key in Inbox
PATCH/v0/inboxes/{inbox_id}/api-keys/{api_key_id}Update API Key in Inbox
DELETE/v0/inboxes/{inbox_id}/api-keys/{api_key_id}Delete API Key in Inbox
GET/v0/pods/{pod_id}/api-keysList API Keys in Pod
POST/v0/pods/{pod_id}/api-keysCreate API Key in Pod
GET/v0/pods/{pod_id}/api-keys/{api_key_id}Get API Key in Pod
PATCH/v0/pods/{pod_id}/api-keys/{api_key_id}Update API Key in Pod
DELETE/v0/pods/{pod_id}/api-keys/{api_key_id}Delete API Key in Pod

List API Keys

http
GET /v0/api-keys

Keys that are not revoked. Under /v0/pods/{pod_id} or /v0/inboxes/{inbox_id}, only the keys scoped to that pod or inbox; a pod or inbox credential sees only keys in its own scope.

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

Query parameters

type"bearer" | "public_key"
Only this credential family. Every key is bearer, so public_key returns an empty list.
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
ascendingboolean
Oldest first.

Response

200 A page of keys (application/json)

countintegerRequired
Number of items returned.
limitintegerRequired
Page size used.
next_page_tokenstring
Page token for pagination. Absent on the last page.
api_keysBearerApiKey[]Required
Keys in the route scope that are not revoked, ordered by created_at, newest first unless ascending is set.

Each item of api_keys is a BearerApiKey:

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "api_keys": [
    {
      "type": "bearer",
      "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
      "prefix": "mm_live_4f8K",
      "name": "Production",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "permissions": {
        "*": false,
        "inbox_read": false,
        "inbox_create": false,
        "inbox_update": false,
        "inbox_delete": false,
        "thread_read": false,
        "thread_delete": false,
        "message_read": false,
        "message_reply": false,
        "message_send": false,
        "message_update": false,
        "message_delete": false,
        "label_spam_read": false,
        "label_blocked_read": false,
        "label_unauthenticated_read": false,
        "label_trash_read": false,
        "draft_read": false,
        "draft_create": false,
        "draft_update": false,
        "draft_delete": false,
        "draft_send": false,
        "webhook_read": false,
        "webhook_create": false,
        "webhook_update": false,
        "webhook_delete": false,
        "domain_read": false,
        "domain_create": false,
        "domain_update": false,
        "domain_delete": false,
        "list_entry_read": false,
        "list_entry_create": false,
        "list_entry_delete": false,
        "metrics_read": false,
        "api_key_read": false,
        "api_key_create": false,
        "api_key_update": false,
        "api_key_delete": false,
        "pod_read": false,
        "pod_create": false,
        "pod_update": false,
        "pod_delete": false,
        "inbound_raw": false
      },
      "created_at": "2026-10-01T12:00:00.000Z",
      "expires_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "used_at": "2026-10-01T12:00:00.000Z",
      "revoked_at": "2026-10-01T12:00:00.000Z",
      "updated_at": "2026-10-01T12:00:00.000Z"
    }
  ]
}

Create API Key

http
POST /v0/api-keys

The route sets the scope of the new key: POST /v0/api-keys makes an organization key, POST /v0/pods/{pod_id}/api-keys a pod key, POST /v0/inboxes/{inbox_id}/api-keys an inbox key.

Only organization-scoped credentials (and dashboard sessions) can create keys, and only with permissions they have themselves (403). api_key is returned once.

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

Request body

Content type: application/json.

The route sets the scope: /v0/api-keys makes an organization key, /v0/pods/{pod_id}/api-keys a pod key, /v0/inboxes/{inbox_id}/api-keys an inbox key.

namestring
Name of the key. Default API key.
permissionsobject | null
Permissions of the new key. Omitted or null: full access for the key scope (inbound_raw excepted).
expires_atstring (date-time) | null
When the key stops working (a past time creates a key that is already expired). Omitted, the key does not expire. It cannot be changed later.

Response

201 Created. api_key is shown once. (application/json)

api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
api_keystringRequired
The key itself (mm_live_ and 32 characters). Returned once; only a hash is stored.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X POST "https://api.machinemail.dev/v0/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 201
{
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "api_key": "mm_live_4f8Kq2ZbX9mN3pR7tV1wY6cH0jL5sD8a"
}

Get API Key

http
GET /v0/api-keys/{api_key_id}

Also returns revoked keys (with revoked_at).

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

Path parameters

api_key_idstringRequired
ID of the API key.

Response

200 The key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Update API Key

http
PATCH /v0/api-keys/{api_key_id}

Rename a key or replace its permissions. Only organization-scoped credentials (and dashboard sessions) can update keys, and cannot grant permissions they lack (403).

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

Path parameters

api_key_idstringRequired
ID of the API key.

Request body

Content type: application/json.

Fields you omit are unchanged. permissions replaces the permission object in full. Scope and expiry cannot be changed.

namestring
New name. A blank name is ignored.
permissionsobject
New permissions; replaces the permission object in full.

Response

200 The updated key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Delete API Key

http
DELETE /v0/api-keys/{api_key_id}

Revokes the key: it stops working immediately. The record is kept (with revoked_at) and no longer listed.

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

Path parameters

api_key_idstringRequired
ID of the API key.

Response

200 Revoked (application/json)

oktrueRequired

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X DELETE "https://api.machinemail.dev/v0/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "ok": true
}

List API Keys in Inbox

http
GET /v0/inboxes/{inbox_id}/api-keys

Same as List API Keys (GET /v0/api-keys), limited to the inbox.

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

Path parameters

inbox_idstringRequired
ID of the inbox.

Query parameters

type"bearer" | "public_key"
Only this credential family. Every key is bearer, so public_key returns an empty list.
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
ascendingboolean
Oldest first.

Response

200 A page of keys (application/json)

countintegerRequired
Number of items returned.
limitintegerRequired
Page size used.
next_page_tokenstring
Page token for pagination. Absent on the last page.
api_keysBearerApiKey[]Required
Keys in the route scope that are not revoked, ordered by created_at, newest first unless ascending is set.

Each item of api_keys is a BearerApiKey:

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "api_keys": [
    {
      "type": "bearer",
      "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
      "prefix": "mm_live_4f8K",
      "name": "Production",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "permissions": {
        "*": false,
        "inbox_read": false,
        "inbox_create": false,
        "inbox_update": false,
        "inbox_delete": false,
        "thread_read": false,
        "thread_delete": false,
        "message_read": false,
        "message_reply": false,
        "message_send": false,
        "message_update": false,
        "message_delete": false,
        "label_spam_read": false,
        "label_blocked_read": false,
        "label_unauthenticated_read": false,
        "label_trash_read": false,
        "draft_read": false,
        "draft_create": false,
        "draft_update": false,
        "draft_delete": false,
        "draft_send": false,
        "webhook_read": false,
        "webhook_create": false,
        "webhook_update": false,
        "webhook_delete": false,
        "domain_read": false,
        "domain_create": false,
        "domain_update": false,
        "domain_delete": false,
        "list_entry_read": false,
        "list_entry_create": false,
        "list_entry_delete": false,
        "metrics_read": false,
        "api_key_read": false,
        "api_key_create": false,
        "api_key_update": false,
        "api_key_delete": false,
        "pod_read": false,
        "pod_create": false,
        "pod_update": false,
        "pod_delete": false,
        "inbound_raw": false
      },
      "created_at": "2026-10-01T12:00:00.000Z",
      "expires_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "used_at": "2026-10-01T12:00:00.000Z",
      "revoked_at": "2026-10-01T12:00:00.000Z",
      "updated_at": "2026-10-01T12:00:00.000Z"
    }
  ]
}

Create API Key in Inbox

http
POST /v0/inboxes/{inbox_id}/api-keys

Same as Create API Key (POST /v0/api-keys), limited to the inbox.

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

Path parameters

inbox_idstringRequired
ID of the inbox.

Request body

Content type: application/json.

The route sets the scope: /v0/api-keys makes an organization key, /v0/pods/{pod_id}/api-keys a pod key, /v0/inboxes/{inbox_id}/api-keys an inbox key.

namestring
Name of the key. Default API key.
permissionsobject | null
Permissions of the new key. Omitted or null: full access for the key scope (inbound_raw excepted).
expires_atstring (date-time) | null
When the key stops working (a past time creates a key that is already expired). Omitted, the key does not expire. It cannot be changed later.

Response

201 Created. api_key is shown once. (application/json)

api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
api_keystringRequired
The key itself (mm_live_ and 32 characters). Returned once; only a hash is stored.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X POST "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 201
{
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "api_key": "mm_live_4f8Kq2ZbX9mN3pR7tV1wY6cH0jL5sD8a"
}

Get API Key in Inbox

http
GET /v0/inboxes/{inbox_id}/api-keys/{api_key_id}

Same as Get API Key (GET /v0/api-keys/{api_key_id}), limited to the inbox.

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

Path parameters

inbox_idstringRequired
ID of the inbox.
api_key_idstringRequired
ID of the API key.

Response

200 The key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Update API Key in Inbox

http
PATCH /v0/inboxes/{inbox_id}/api-keys/{api_key_id}

Same as Update API Key (PATCH /v0/api-keys/{api_key_id}), limited to the inbox.

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

Path parameters

inbox_idstringRequired
ID of the inbox.
api_key_idstringRequired
ID of the API key.

Request body

Content type: application/json.

Fields you omit are unchanged. permissions replaces the permission object in full. Scope and expiry cannot be changed.

namestring
New name. A blank name is ignored.
permissionsobject
New permissions; replaces the permission object in full.

Response

200 The updated key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Delete API Key in Inbox

http
DELETE /v0/inboxes/{inbox_id}/api-keys/{api_key_id}

Same as Delete API Key (DELETE /v0/api-keys/{api_key_id}), limited to the inbox.

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

Path parameters

inbox_idstringRequired
ID of the inbox.
api_key_idstringRequired
ID of the API key.

Response

200 Revoked (application/json)

oktrueRequired

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X DELETE "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "ok": true
}

List API Keys in Pod

http
GET /v0/pods/{pod_id}/api-keys

Same as List API Keys (GET /v0/api-keys), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.

Query parameters

type"bearer" | "public_key"
Only this credential family. Every key is bearer, so public_key returns an empty list.
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
ascendingboolean
Oldest first.

Response

200 A page of keys (application/json)

countintegerRequired
Number of items returned.
limitintegerRequired
Page size used.
next_page_tokenstring
Page token for pagination. Absent on the last page.
api_keysBearerApiKey[]Required
Keys in the route scope that are not revoked, ordered by created_at, newest first unless ascending is set.

Each item of api_keys is a BearerApiKey:

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "api_keys": [
    {
      "type": "bearer",
      "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
      "prefix": "mm_live_4f8K",
      "name": "Production",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "permissions": {
        "*": false,
        "inbox_read": false,
        "inbox_create": false,
        "inbox_update": false,
        "inbox_delete": false,
        "thread_read": false,
        "thread_delete": false,
        "message_read": false,
        "message_reply": false,
        "message_send": false,
        "message_update": false,
        "message_delete": false,
        "label_spam_read": false,
        "label_blocked_read": false,
        "label_unauthenticated_read": false,
        "label_trash_read": false,
        "draft_read": false,
        "draft_create": false,
        "draft_update": false,
        "draft_delete": false,
        "draft_send": false,
        "webhook_read": false,
        "webhook_create": false,
        "webhook_update": false,
        "webhook_delete": false,
        "domain_read": false,
        "domain_create": false,
        "domain_update": false,
        "domain_delete": false,
        "list_entry_read": false,
        "list_entry_create": false,
        "list_entry_delete": false,
        "metrics_read": false,
        "api_key_read": false,
        "api_key_create": false,
        "api_key_update": false,
        "api_key_delete": false,
        "pod_read": false,
        "pod_create": false,
        "pod_update": false,
        "pod_delete": false,
        "inbound_raw": false
      },
      "created_at": "2026-10-01T12:00:00.000Z",
      "expires_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "used_at": "2026-10-01T12:00:00.000Z",
      "revoked_at": "2026-10-01T12:00:00.000Z",
      "updated_at": "2026-10-01T12:00:00.000Z"
    }
  ]
}

Create API Key in Pod

http
POST /v0/pods/{pod_id}/api-keys

Same as Create API Key (POST /v0/api-keys), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.

Request body

Content type: application/json.

The route sets the scope: /v0/api-keys makes an organization key, /v0/pods/{pod_id}/api-keys a pod key, /v0/inboxes/{inbox_id}/api-keys an inbox key.

namestring
Name of the key. Default API key.
permissionsobject | null
Permissions of the new key. Omitted or null: full access for the key scope (inbound_raw excepted).
expires_atstring (date-time) | null
When the key stops working (a past time creates a key that is already expired). Omitted, the key does not expire. It cannot be changed later.

Response

201 Created. api_key is shown once. (application/json)

api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
api_keystringRequired
The key itself (mm_live_ and 32 characters). Returned once; only a hash is stored.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/api-keys" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 201
{
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "api_key": "mm_live_4f8Kq2ZbX9mN3pR7tV1wY6cH0jL5sD8a"
}

Get API Key in Pod

http
GET /v0/pods/{pod_id}/api-keys/{api_key_id}

Same as Get API Key (GET /v0/api-keys/{api_key_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
api_key_idstringRequired
ID of the API key.

Response

200 The key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Update API Key in Pod

http
PATCH /v0/pods/{pod_id}/api-keys/{api_key_id}

Same as Update API Key (PATCH /v0/api-keys/{api_key_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
api_key_idstringRequired
ID of the API key.

Request body

Content type: application/json.

Fields you omit are unchanged. permissions replaces the permission object in full. Scope and expiry cannot be changed.

namestring
New name. A blank name is ignored.
permissionsobject
New permissions; replaces the permission object in full.

Response

200 The updated key (application/json)

type"bearer"Required
Always bearer: MachineMail has no public-key credentials.
api_key_idstringRequired
ID of the API key.
prefixstringRequired
First 12 characters of the key (mm_live_ and 4 more), safe to display.
namestringRequired
Name of the key.
pod_idstring
Pod the key is scoped to: it can only access resources in this pod.
inbox_idstring
Inbox the key is scoped to: it can only access this inbox.
Permissions of the key, as { "<name>": true }. Only names set to true are granted; false is the same as leaving the name out. An omitted (or null) permission object means full access for the key scope, like {"*": true}; neither includes inbound_raw, which must be granted by name. A key can only be given permissions its creator has. Another name set to true (for example AgentMail’s calendar_*, app_* or account_update, which MachineMail does not support) is a 400.
created_atstring (date-time)Required
Time at which the key was created.
expires_atstring (date-time)
Time at which the key expires. Absent when it does not expire.
organization_idstringRequired
ID of the organization.
used_atstring (date-time)
Time at which the key was last used.
revoked_atstring (date-time)
When the key was deleted (revoked). Revoked keys are not listed but can still be fetched by ID.
updated_atstring (date-time)Required
Time at which the name, permissions or revocation last changed. Use does not change it.

permissions is a ApiKeyPermissions:

*boolean
Every permission except inbound_raw. {"*": true, "inbound_raw": true} is full access plus raw injection.
inbox_readboolean
Read inbox details.
inbox_createboolean
Create new inboxes.
inbox_updateboolean
Update inbox settings.
inbox_deleteboolean
Delete inboxes.
thread_readboolean
Read threads.
thread_deleteboolean
Delete threads.
message_readboolean
Read messages.
message_replyboolean
Reply and reply-all. message_send allows them too.
message_sendboolean
Send messages (and reply, reply-all, forward).
message_updateboolean
Update message labels. Also required to update threads.
message_deleteboolean
Delete messages.
label_spam_readboolean
Access messages labeled spam.
label_blocked_readboolean
Access messages labeled blocked.
label_unauthenticated_readboolean
Access messages labeled unauthenticated.
label_trash_readboolean
Access messages labeled trash.
draft_readboolean
Read drafts.
draft_createboolean
Create drafts.
draft_updateboolean
Update drafts.
draft_deleteboolean
Delete drafts.
draft_sendboolean
Send drafts.
webhook_readboolean
Read webhook configurations.
webhook_createboolean
Create webhooks.
webhook_updateboolean
Update webhooks.
webhook_deleteboolean
Delete webhooks.
domain_readboolean
Read domain details.
domain_createboolean
Create domains.
domain_updateboolean
Update domains.
domain_deleteboolean
Delete domains.
list_entry_readboolean
Read list entries and suppressions.
list_entry_createboolean
Create list entries and suppressions.
list_entry_deleteboolean
Delete list entries and suppressions.
metrics_readboolean
Read metrics and events.
api_key_readboolean
Read API keys.
api_key_createboolean
Create API keys.
api_key_updateboolean
Update API keys.
api_key_deleteboolean
Delete API keys.
pod_readboolean
Read pods.
pod_createboolean
Create pods.
pod_updateboolean
Update pods.
pod_deleteboolean
Delete pods.
inbound_rawboolean
Inject raw mail with POST /inbound/raw. Never implied by an unrestricted key or *: it must be granted by name.

Errors

StatusMeaning
400Invalid request: error.type is validation and error.param names the field.
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production"
}'
Response 200
{
  "type": "bearer",
  "api_key_id": "key_01k6x3e8mr0000h4r0ty6c9k1n",
  "prefix": "mm_live_4f8K",
  "name": "Production",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "permissions": {
    "*": false,
    "inbox_read": false,
    "inbox_create": false,
    "inbox_update": false,
    "inbox_delete": false,
    "thread_read": false,
    "thread_delete": false,
    "message_read": false,
    "message_reply": false,
    "message_send": false,
    "message_update": false,
    "message_delete": false,
    "label_spam_read": false,
    "label_blocked_read": false,
    "label_unauthenticated_read": false,
    "label_trash_read": false,
    "draft_read": false,
    "draft_create": false,
    "draft_update": false,
    "draft_delete": false,
    "draft_send": false,
    "webhook_read": false,
    "webhook_create": false,
    "webhook_update": false,
    "webhook_delete": false,
    "domain_read": false,
    "domain_create": false,
    "domain_update": false,
    "domain_delete": false,
    "list_entry_read": false,
    "list_entry_create": false,
    "list_entry_delete": false,
    "metrics_read": false,
    "api_key_read": false,
    "api_key_create": false,
    "api_key_update": false,
    "api_key_delete": false,
    "pod_read": false,
    "pod_create": false,
    "pod_update": false,
    "pod_delete": false,
    "inbound_raw": false
  },
  "created_at": "2026-10-01T12:00:00.000Z",
  "expires_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "used_at": "2026-10-01T12:00:00.000Z",
  "revoked_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}

Delete API Key in Pod

http
DELETE /v0/pods/{pod_id}/api-keys/{api_key_id}

Same as Delete API Key (DELETE /v0/api-keys/{api_key_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
api_key_idstringRequired
ID of the API key.

Response

200 Revoked (application/json)

oktrueRequired

Errors

StatusMeaning
401Missing, invalid, expired or revoked credential.
403The 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).
404Not found. Also returned for resources outside the credential scope.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X DELETE "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/api-keys/key_01k6x3e8mr0000h4r0ty6c9k1n" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "ok": true
}