Skip to content
machinemail

Threads

Conversation threads.

MethodPathSummary
GET/v0/inboxes/{inbox_id}/threadsList Threads
GET/v0/inboxes/{inbox_id}/threads/searchSearch Threads
GET/v0/inboxes/{inbox_id}/threads/{thread_id}Get Thread
PATCH/v0/inboxes/{inbox_id}/threads/{thread_id}Update Thread
DELETE/v0/inboxes/{inbox_id}/threads/{thread_id}Delete Thread
GET/v0/pods/{pod_id}/inboxes/{inbox_id}/threadsList Threads in Pod
GET/v0/pods/{pod_id}/inboxes/{inbox_id}/threads/searchSearch Threads in Pod
GET/v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}Get Thread in Pod
PATCH/v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}Update Thread in Pod
DELETE/v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}Delete Thread in Pod
GET/v0/pods/{pod_id}/threadsList Threads in Pod
GET/v0/pods/{pod_id}/threads/searchSearch Threads in Pod
GET/v0/pods/{pod_id}/threads/{thread_id}Get Thread in Pod
PATCH/v0/pods/{pod_id}/threads/{thread_id}Update Thread in Pod
DELETE/v0/pods/{pod_id}/threads/{thread_id}Delete Thread in Pod
GET/v0/threadsList Threads
GET/v0/threads/searchSearch Threads
GET/v0/threads/{thread_id}Get Thread
PATCH/v0/threads/{thread_id}Update Thread
DELETE/v0/threads/{thread_id}Delete Thread

List Threads

http
GET /v0/inboxes/{inbox_id}/threads

Threads, most recently active first. Pass q to keep only threads with a message matching the words.

Threads with a spam, blocked, trash, quarantined or unauthenticated message are hidden unless you pass the matching include_* flag or ask for the label in labels.

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

Path parameters

inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).

Query parameters

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
Sort oldest first.
labelsstring[]
Only items with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
include_spamboolean
Include spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.
qstring
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages.

Response

200 A page of threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Search Threads

http
GET /v0/inboxes/{inbox_id}/threads/search

Threads with a message whose subject, sender, recipients, body or attachment file names contain every word of q, ordered by thread activity (not ranked by relevance). Scans the newest 500 matching messages; the response has truncated: true when it hit that cap.

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

Path parameters

inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).

Query parameters

qstringRequired
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages. (min length 1)
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
ascendingboolean
Sort oldest first.
labelsstring[]
Only threads with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
include_spamboolean
Include threads with spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include threads with blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include threads with unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include threads with trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.

Response

200 A page of matching threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Matching threads, ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Get Thread

http
GET /v0/inboxes/{inbox_id}/threads/{thread_id}

The thread with its messages, which carry their bodies and trust reports. Messages come in pages of limit (default and maximum 500): the first page has the newest messages, oldest first within the page; follow next_page_token for older ones.

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

Path parameters

inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Query parameters

limitinteger
Maximum number of messages to return. Default and maximum 500.
page_tokenstring
next_page_token from the previous response: the next, older page of messages.

Response

200 The thread with a page of its messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.
countintegerRequired
Number of messages in this page.
limitinteger
Maximum number of messages requested for this page.
next_page_tokenstring
Token for the next, older page of messages. Absent when this page completes the thread.
messagesMessage[]Required
Messages in this page, oldest first. The first page has the newest messages; follow next_page_token for older ones.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

Each item of messages is a Message:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
message_idstringRequired
ID of the message.
labelsstring[]Required
Labels of the message.
timestampstring (date-time)Required
Time at which the message was sent or received.
fromstringRequired
Address of the sender. In format username@domain.com or Display Name <username@domain.com>.
tostring[]Required
Addresses of the recipients. In format username@domain.com or Display Name <username@domain.com>.
ccstring[]
Addresses of the CC recipients. In format username@domain.com or Display Name <username@domain.com>.
bccstring[]
Addresses of the BCC recipients. In format username@domain.com or Display Name <username@domain.com>.
subjectstring
Subject of the message.
previewstring
Text preview of the message.
attachmentsAttachment[]
Attachments of the message.
in_reply_tostring
ID of the message being replied to.
referencesstring[]
IDs of previous messages in the thread.
headersRecord<string, string>
Headers of the message.
sizeintegerRequired
Size of the message in bytes.
updated_atstring (date-time)Required
Time at which the message was last updated.
created_atstring (date-time)Required
Time at which the message was created.
pod_idstringRequired
ID of the pod.
direction"inbound" | "outbound"Required
Whether the message was received or sent.
delivery_status"sent" | "delivered" | "bounced" | "complained"
Outbound only: last delivery state reported by the transport.
trust_level"verified" | "known" | "unknown" | "suspicious" | "quarantined"
Inbound only: trust.level, for list badges.
reply_tostring[]
Reply-to addresses. In format username@domain.com or Display Name <username@domain.com>.
textstring
Plain text body. Untrusted: agents should read trust.content.text or extracted_text.
htmlstring
HTML body. Untrusted.
extracted_textstring
New text content, without quoted replies.
extracted_htmlstring
New HTML content, without quoted replies.
received_via"raw"
raw when the message was injected with POST /inbound/raw (authentication not verified).
Trust report of an inbound message.

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/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "messages": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "from": "Support Agent <agent@machinemail.dev>",
      "to": ["customer@example.com"],
      "cc": ["team@example.com"],
      "bcc": ["audit@example.com"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "in_reply_to": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "references": ["string"],
      "headers": {
        "key": "value"
      },
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "direction": "inbound",
      "delivery_status": "sent",
      "trust_level": "verified",
      "reply_to": ["agent@machinemail.dev"],
      "text": "Thanks for the quick reply.",
      "html": "<p>Thanks for the quick reply.</p>",
      "extracted_text": "Thanks for the quick reply.",
      "extracted_html": "<p>Thanks for the quick reply.</p>",
      "received_via": "raw",
      "trust": {
        "level": "verified",
        "score": 0.8,
        "authentication": {
          "spf": "pass",
          "dkim": "pass",
          "dmarc": "pass",
          "aligned": false
        },
        "sender": {
          "address": "agent@machinemail.dev",
          "domain": "example.com",
          "prior_correspondence": false,
          "on_allow_list": false,
          "on_block_list": false,
          "free_mail_provider": false
        },
        "content": {
          "text": "Thanks for the quick reply.",
          "html": "<p>Thanks for the quick reply.</p>",
          "segments": [{}],
          "hidden_text_found": false,
          "zero_width_found": false,
          "tracking_pixels": 1
        },
        "links": [
          {
            "href": "string",
            "text": "Thanks for the quick reply.",
            "final_url": "https://example.com",
            "domain": "example.com",
            "display_mismatch": false,
            "shortener": false,
            "suspicious": false,
            "reasons": []
          }
        ],
        "attachments": [
          {
            "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
            "filename": "invoice.pdf",
            "content_type": "application/pdf",
            "risk": "low",
            "reasons": [],
            "extracted_text": "Thanks for the quick reply."
          }
        ],
        "classification": {
          "is_spam": 0.8,
          "is_phishing": 0.8,
          "contains_instructions_to_agent": 0.8,
          "requests_credentials_or_payment": 0.8,
          "urgency": 0.8,
          "category": "transactional",
          "language": "string",
          "backend": "string",
          "input_hash": "string",
          "cached": false
        },
        "reasons": ["string"],
        "computed_at": "2026-10-01T12:00:00.000Z"
      }
    }
  ]
}

Update Thread

http
PATCH /v0/inboxes/{inbox_id}/threads/{thread_id}

Adds and removes labels on every message in the thread (up to 500 messages); the thread labels are their union. Labels are free strings, system labels included. Returns the updated thread without messages.

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

Path parameters

inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Request body

Content type: application/json.

add_labelsstring | string[]
Label or labels to add to every message in the thread.
remove_labelsstring | string[]
Label or labels to remove from every message in the thread. Applied after add_labels.

Response

200 The updated thread, without messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "add_labels": "string"
}'
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
}

Delete Thread

http
DELETE /v0/inboxes/{inbox_id}/threads/{thread_id}

Permanently deletes the thread and its messages (up to 500).

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

Path parameters

inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Response

200 Deleted (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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

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

List Threads in Pod

http
GET /v0/pods/{pod_id}/inboxes/{inbox_id}/threads

Same as List Threads (GET /v0/inboxes/{inbox_id}/threads), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).

Query parameters

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
Sort oldest first.
labelsstring[]
Only items with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
include_spamboolean
Include spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.
qstring
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages.

Response

200 A page of threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/inboxes/agent@machinemail.dev/threads" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Search Threads in Pod

http
GET /v0/pods/{pod_id}/inboxes/{inbox_id}/threads/search

Same as Search Threads (GET /v0/inboxes/{inbox_id}/threads/search), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).

Query parameters

qstringRequired
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages. (min length 1)
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
ascendingboolean
Sort oldest first.
labelsstring[]
Only threads with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
include_spamboolean
Include threads with spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include threads with blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include threads with unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include threads with trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.

Response

200 A page of matching threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Matching threads, ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/inboxes/agent@machinemail.dev/threads/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Get Thread in Pod

http
GET /v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}

Same as Get Thread (GET /v0/inboxes/{inbox_id}/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Query parameters

limitinteger
Maximum number of messages to return. Default and maximum 500.
page_tokenstring
next_page_token from the previous response: the next, older page of messages.

Response

200 The thread with a page of its messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.
countintegerRequired
Number of messages in this page.
limitinteger
Maximum number of messages requested for this page.
next_page_tokenstring
Token for the next, older page of messages. Absent when this page completes the thread.
messagesMessage[]Required
Messages in this page, oldest first. The first page has the newest messages; follow next_page_token for older ones.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

Each item of messages is a Message:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
message_idstringRequired
ID of the message.
labelsstring[]Required
Labels of the message.
timestampstring (date-time)Required
Time at which the message was sent or received.
fromstringRequired
Address of the sender. In format username@domain.com or Display Name <username@domain.com>.
tostring[]Required
Addresses of the recipients. In format username@domain.com or Display Name <username@domain.com>.
ccstring[]
Addresses of the CC recipients. In format username@domain.com or Display Name <username@domain.com>.
bccstring[]
Addresses of the BCC recipients. In format username@domain.com or Display Name <username@domain.com>.
subjectstring
Subject of the message.
previewstring
Text preview of the message.
attachmentsAttachment[]
Attachments of the message.
in_reply_tostring
ID of the message being replied to.
referencesstring[]
IDs of previous messages in the thread.
headersRecord<string, string>
Headers of the message.
sizeintegerRequired
Size of the message in bytes.
updated_atstring (date-time)Required
Time at which the message was last updated.
created_atstring (date-time)Required
Time at which the message was created.
pod_idstringRequired
ID of the pod.
direction"inbound" | "outbound"Required
Whether the message was received or sent.
delivery_status"sent" | "delivered" | "bounced" | "complained"
Outbound only: last delivery state reported by the transport.
trust_level"verified" | "known" | "unknown" | "suspicious" | "quarantined"
Inbound only: trust.level, for list badges.
reply_tostring[]
Reply-to addresses. In format username@domain.com or Display Name <username@domain.com>.
textstring
Plain text body. Untrusted: agents should read trust.content.text or extracted_text.
htmlstring
HTML body. Untrusted.
extracted_textstring
New text content, without quoted replies.
extracted_htmlstring
New HTML content, without quoted replies.
received_via"raw"
raw when the message was injected with POST /inbound/raw (authentication not verified).
Trust report of an inbound message.

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/inboxes/agent@machinemail.dev/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "messages": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "from": "Support Agent <agent@machinemail.dev>",
      "to": ["customer@example.com"],
      "cc": ["team@example.com"],
      "bcc": ["audit@example.com"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "in_reply_to": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "references": ["string"],
      "headers": {
        "key": "value"
      },
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "direction": "inbound",
      "delivery_status": "sent",
      "trust_level": "verified",
      "reply_to": ["agent@machinemail.dev"],
      "text": "Thanks for the quick reply.",
      "html": "<p>Thanks for the quick reply.</p>",
      "extracted_text": "Thanks for the quick reply.",
      "extracted_html": "<p>Thanks for the quick reply.</p>",
      "received_via": "raw",
      "trust": {
        "level": "verified",
        "score": 0.8,
        "authentication": {
          "spf": "pass",
          "dkim": "pass",
          "dmarc": "pass",
          "aligned": false
        },
        "sender": {
          "address": "agent@machinemail.dev",
          "domain": "example.com",
          "prior_correspondence": false,
          "on_allow_list": false,
          "on_block_list": false,
          "free_mail_provider": false
        },
        "content": {
          "text": "Thanks for the quick reply.",
          "html": "<p>Thanks for the quick reply.</p>",
          "segments": [{}],
          "hidden_text_found": false,
          "zero_width_found": false,
          "tracking_pixels": 1
        },
        "links": [
          {
            "href": "string",
            "text": "Thanks for the quick reply.",
            "final_url": "https://example.com",
            "domain": "example.com",
            "display_mismatch": false,
            "shortener": false,
            "suspicious": false,
            "reasons": []
          }
        ],
        "attachments": [
          {
            "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
            "filename": "invoice.pdf",
            "content_type": "application/pdf",
            "risk": "low",
            "reasons": [],
            "extracted_text": "Thanks for the quick reply."
          }
        ],
        "classification": {
          "is_spam": 0.8,
          "is_phishing": 0.8,
          "contains_instructions_to_agent": 0.8,
          "requests_credentials_or_payment": 0.8,
          "urgency": 0.8,
          "category": "transactional",
          "language": "string",
          "backend": "string",
          "input_hash": "string",
          "cached": false
        },
        "reasons": ["string"],
        "computed_at": "2026-10-01T12:00:00.000Z"
      }
    }
  ]
}

Update Thread in Pod

http
PATCH /v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}

Same as Update Thread (PATCH /v0/inboxes/{inbox_id}/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Request body

Content type: application/json.

add_labelsstring | string[]
Label or labels to add to every message in the thread.
remove_labelsstring | string[]
Label or labels to remove from every message in the thread. Applied after add_labels.

Response

200 The updated thread, without messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/agent@machinemail.dev/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "add_labels": "string"
}'
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
}

Delete Thread in Pod

http
DELETE /v0/pods/{pod_id}/inboxes/{inbox_id}/threads/{thread_id}

Same as Delete Thread (DELETE /v0/inboxes/{inbox_id}/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
inbox_idstringRequired
ID of the inbox: its email address, as in AgentMail (inbox_id == email).
thread_idstringRequired
ID of the thread.

Response

200 Deleted (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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

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

List Threads in Pod

http
GET /v0/pods/{pod_id}/threads

Same as List Threads (GET /v0/threads), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.

Query parameters

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
Sort oldest first.
labelsstring[]
Only items with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
include_spamboolean
Include spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.
qstring
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages.

Response

200 A page of threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Search Threads in Pod

http
GET /v0/pods/{pod_id}/threads/search

Same as Search Threads (GET /v0/threads/search), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.

Query parameters

qstringRequired
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages. (min length 1)
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
ascendingboolean
Sort oldest first.
labelsstring[]
Only threads with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
include_spamboolean
Include threads with spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include threads with blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include threads with unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include threads with trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.

Response

200 A page of matching threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Matching threads, ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Get Thread in Pod

http
GET /v0/pods/{pod_id}/threads/{thread_id}

Same as Get Thread (GET /v0/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
thread_idstringRequired
ID of the thread.

Query parameters

limitinteger
Maximum number of messages to return. Default and maximum 500.
page_tokenstring
next_page_token from the previous response: the next, older page of messages.

Response

200 The thread with a page of its messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.
countintegerRequired
Number of messages in this page.
limitinteger
Maximum number of messages requested for this page.
next_page_tokenstring
Token for the next, older page of messages. Absent when this page completes the thread.
messagesMessage[]Required
Messages in this page, oldest first. The first page has the newest messages; follow next_page_token for older ones.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

Each item of messages is a Message:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
message_idstringRequired
ID of the message.
labelsstring[]Required
Labels of the message.
timestampstring (date-time)Required
Time at which the message was sent or received.
fromstringRequired
Address of the sender. In format username@domain.com or Display Name <username@domain.com>.
tostring[]Required
Addresses of the recipients. In format username@domain.com or Display Name <username@domain.com>.
ccstring[]
Addresses of the CC recipients. In format username@domain.com or Display Name <username@domain.com>.
bccstring[]
Addresses of the BCC recipients. In format username@domain.com or Display Name <username@domain.com>.
subjectstring
Subject of the message.
previewstring
Text preview of the message.
attachmentsAttachment[]
Attachments of the message.
in_reply_tostring
ID of the message being replied to.
referencesstring[]
IDs of previous messages in the thread.
headersRecord<string, string>
Headers of the message.
sizeintegerRequired
Size of the message in bytes.
updated_atstring (date-time)Required
Time at which the message was last updated.
created_atstring (date-time)Required
Time at which the message was created.
pod_idstringRequired
ID of the pod.
direction"inbound" | "outbound"Required
Whether the message was received or sent.
delivery_status"sent" | "delivered" | "bounced" | "complained"
Outbound only: last delivery state reported by the transport.
trust_level"verified" | "known" | "unknown" | "suspicious" | "quarantined"
Inbound only: trust.level, for list badges.
reply_tostring[]
Reply-to addresses. In format username@domain.com or Display Name <username@domain.com>.
textstring
Plain text body. Untrusted: agents should read trust.content.text or extracted_text.
htmlstring
HTML body. Untrusted.
extracted_textstring
New text content, without quoted replies.
extracted_htmlstring
New HTML content, without quoted replies.
received_via"raw"
raw when the message was injected with POST /inbound/raw (authentication not verified).
Trust report of an inbound message.

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/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "messages": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "from": "Support Agent <agent@machinemail.dev>",
      "to": ["customer@example.com"],
      "cc": ["team@example.com"],
      "bcc": ["audit@example.com"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "in_reply_to": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "references": ["string"],
      "headers": {
        "key": "value"
      },
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "direction": "inbound",
      "delivery_status": "sent",
      "trust_level": "verified",
      "reply_to": ["agent@machinemail.dev"],
      "text": "Thanks for the quick reply.",
      "html": "<p>Thanks for the quick reply.</p>",
      "extracted_text": "Thanks for the quick reply.",
      "extracted_html": "<p>Thanks for the quick reply.</p>",
      "received_via": "raw",
      "trust": {
        "level": "verified",
        "score": 0.8,
        "authentication": {
          "spf": "pass",
          "dkim": "pass",
          "dmarc": "pass",
          "aligned": false
        },
        "sender": {
          "address": "agent@machinemail.dev",
          "domain": "example.com",
          "prior_correspondence": false,
          "on_allow_list": false,
          "on_block_list": false,
          "free_mail_provider": false
        },
        "content": {
          "text": "Thanks for the quick reply.",
          "html": "<p>Thanks for the quick reply.</p>",
          "segments": [{}],
          "hidden_text_found": false,
          "zero_width_found": false,
          "tracking_pixels": 1
        },
        "links": [
          {
            "href": "string",
            "text": "Thanks for the quick reply.",
            "final_url": "https://example.com",
            "domain": "example.com",
            "display_mismatch": false,
            "shortener": false,
            "suspicious": false,
            "reasons": []
          }
        ],
        "attachments": [
          {
            "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
            "filename": "invoice.pdf",
            "content_type": "application/pdf",
            "risk": "low",
            "reasons": [],
            "extracted_text": "Thanks for the quick reply."
          }
        ],
        "classification": {
          "is_spam": 0.8,
          "is_phishing": 0.8,
          "contains_instructions_to_agent": 0.8,
          "requests_credentials_or_payment": 0.8,
          "urgency": 0.8,
          "category": "transactional",
          "language": "string",
          "backend": "string",
          "input_hash": "string",
          "cached": false
        },
        "reasons": ["string"],
        "computed_at": "2026-10-01T12:00:00.000Z"
      }
    }
  ]
}

Update Thread in Pod

http
PATCH /v0/pods/{pod_id}/threads/{thread_id}

Same as Update Thread (PATCH /v0/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
thread_idstringRequired
ID of the thread.

Request body

Content type: application/json.

add_labelsstring | string[]
Label or labels to add to every message in the thread.
remove_labelsstring | string[]
Label or labels to remove from every message in the thread. Applied after add_labels.

Response

200 The updated thread, without messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "add_labels": "string"
}'
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
}

Delete Thread in Pod

http
DELETE /v0/pods/{pod_id}/threads/{thread_id}

Same as Delete Thread (DELETE /v0/threads/{thread_id}), limited to the pod.

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

Path parameters

pod_idstringRequired
ID of the pod.
thread_idstringRequired
ID of the thread.

Response

200 Deleted (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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

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

List Threads

http
GET /v0/threads

Threads, most recently active first. Pass q to keep only threads with a message matching the words.

Threads with a spam, blocked, trash, quarantined or unauthenticated message are hidden unless you pass the matching include_* flag or ask for the label in labels.

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

Query parameters

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
Sort oldest first.
labelsstring[]
Only items with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
include_spamboolean
Include spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.
qstring
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages.

Response

200 A page of threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Search Threads

http
GET /v0/threads/search

Threads with a message whose subject, sender, recipients, body or attachment file names contain every word of q, ordered by thread activity (not ranked by relevance). Scans the newest 500 matching messages; the response has truncated: true when it hit that cap.

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

Query parameters

qstringRequired
Full-text filter: threads with a message whose subject, sender, recipients, body or attachment file names contain the words. Scans the newest 500 matching messages. (min length 1)
limitinteger
Maximum number of items to return. Default 50, maximum 500; larger values are capped.
page_tokenstring
next_page_token from the previous page.
beforestring (date-time)
Only items with a timestamp before this time.
afterstring (date-time)
Only items with a timestamp after this time.
ascendingboolean
Sort oldest first.
labelsstring[]
Only threads with any of these labels. Asking for SPAM, BLOCKED, TRASH, QUARANTINE or UNAUTHENTICATED includes them.
include_spamboolean
Include threads with spam (needs label_spam_read; ignored without it).
include_blockedboolean
Include threads with blocked mail (needs label_blocked_read; ignored without it).
include_unauthenticatedboolean
Include threads with unauthenticated mail (needs label_unauthenticated_read; ignored without it).
include_trashboolean
Include threads with trash (needs label_trash_read; ignored without it).
include_quarantineboolean
Include threads that have a quarantined message.

Response

200 A page of matching threads (application/json)

countintegerRequired
Number of items returned.
limitinteger
Maximum number of items per page. Default 50, maximum 500; larger values are capped.
next_page_tokenstring
Page token for pagination. Absent on the last page.
threadsThreadItem[]Required
Matching threads, ordered by timestamp, newest first unless ascending is set.
truncatedtrue
Present when q matched more than 500 messages: only the threads of the newest 500 matching messages were considered.

Each item of threads is a ThreadItem:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

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/threads/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "threads": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "received_timestamp": "2026-10-01T12:00:00.000Z",
      "sent_timestamp": "2026-10-01T12:00:00.000Z",
      "senders": ["customer@example.com"],
      "recipients": ["agent@machinemail.dev"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "message_count": 1,
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
    }
  ],
  "truncated": true
}

Get Thread

http
GET /v0/threads/{thread_id}

The thread with its messages, which carry their bodies and trust reports. Messages come in pages of limit (default and maximum 500): the first page has the newest messages, oldest first within the page; follow next_page_token for older ones.

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

Path parameters

thread_idstringRequired
ID of the thread.

Query parameters

limitinteger
Maximum number of messages to return. Default and maximum 500.
page_tokenstring
next_page_token from the previous response: the next, older page of messages.

Response

200 The thread with a page of its messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.
countintegerRequired
Number of messages in this page.
limitinteger
Maximum number of messages requested for this page.
next_page_tokenstring
Token for the next, older page of messages. Absent when this page completes the thread.
messagesMessage[]Required
Messages in this page, oldest first. The first page has the newest messages; follow next_page_token for older ones.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

Each item of messages is a Message:

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
message_idstringRequired
ID of the message.
labelsstring[]Required
Labels of the message.
timestampstring (date-time)Required
Time at which the message was sent or received.
fromstringRequired
Address of the sender. In format username@domain.com or Display Name <username@domain.com>.
tostring[]Required
Addresses of the recipients. In format username@domain.com or Display Name <username@domain.com>.
ccstring[]
Addresses of the CC recipients. In format username@domain.com or Display Name <username@domain.com>.
bccstring[]
Addresses of the BCC recipients. In format username@domain.com or Display Name <username@domain.com>.
subjectstring
Subject of the message.
previewstring
Text preview of the message.
attachmentsAttachment[]
Attachments of the message.
in_reply_tostring
ID of the message being replied to.
referencesstring[]
IDs of previous messages in the thread.
headersRecord<string, string>
Headers of the message.
sizeintegerRequired
Size of the message in bytes.
updated_atstring (date-time)Required
Time at which the message was last updated.
created_atstring (date-time)Required
Time at which the message was created.
pod_idstringRequired
ID of the pod.
direction"inbound" | "outbound"Required
Whether the message was received or sent.
delivery_status"sent" | "delivered" | "bounced" | "complained"
Outbound only: last delivery state reported by the transport.
trust_level"verified" | "known" | "unknown" | "suspicious" | "quarantined"
Inbound only: trust.level, for list badges.
reply_tostring[]
Reply-to addresses. In format username@domain.com or Display Name <username@domain.com>.
textstring
Plain text body. Untrusted: agents should read trust.content.text or extracted_text.
htmlstring
HTML body. Untrusted.
extracted_textstring
New text content, without quoted replies.
extracted_htmlstring
New HTML content, without quoted replies.
received_via"raw"
raw when the message was injected with POST /inbound/raw (authentication not verified).
Trust report of an inbound message.

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/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "messages": [
    {
      "inbox_id": "agent@machinemail.dev",
      "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
      "message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "labels": ["UNREAD"],
      "timestamp": "2026-10-01T12:00:00.000Z",
      "from": "Support Agent <agent@machinemail.dev>",
      "to": ["customer@example.com"],
      "cc": ["team@example.com"],
      "bcc": ["audit@example.com"],
      "subject": "Order #1042",
      "preview": "Thanks for the quick reply.",
      "attachments": [
        {
          "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
          "filename": "invoice.pdf",
          "size": 2048,
          "content_type": "application/pdf",
          "content_disposition": "string",
          "content_id": "string"
        }
      ],
      "in_reply_to": "msg_01k6x3a1g00000d0m6pt2y5f7h",
      "references": ["string"],
      "headers": {
        "key": "value"
      },
      "size": 2048,
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "direction": "inbound",
      "delivery_status": "sent",
      "trust_level": "verified",
      "reply_to": ["agent@machinemail.dev"],
      "text": "Thanks for the quick reply.",
      "html": "<p>Thanks for the quick reply.</p>",
      "extracted_text": "Thanks for the quick reply.",
      "extracted_html": "<p>Thanks for the quick reply.</p>",
      "received_via": "raw",
      "trust": {
        "level": "verified",
        "score": 0.8,
        "authentication": {
          "spf": "pass",
          "dkim": "pass",
          "dmarc": "pass",
          "aligned": false
        },
        "sender": {
          "address": "agent@machinemail.dev",
          "domain": "example.com",
          "prior_correspondence": false,
          "on_allow_list": false,
          "on_block_list": false,
          "free_mail_provider": false
        },
        "content": {
          "text": "Thanks for the quick reply.",
          "html": "<p>Thanks for the quick reply.</p>",
          "segments": [{}],
          "hidden_text_found": false,
          "zero_width_found": false,
          "tracking_pixels": 1
        },
        "links": [
          {
            "href": "string",
            "text": "Thanks for the quick reply.",
            "final_url": "https://example.com",
            "domain": "example.com",
            "display_mismatch": false,
            "shortener": false,
            "suspicious": false,
            "reasons": []
          }
        ],
        "attachments": [
          {
            "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
            "filename": "invoice.pdf",
            "content_type": "application/pdf",
            "risk": "low",
            "reasons": [],
            "extracted_text": "Thanks for the quick reply."
          }
        ],
        "classification": {
          "is_spam": 0.8,
          "is_phishing": 0.8,
          "contains_instructions_to_agent": 0.8,
          "requests_credentials_or_payment": 0.8,
          "urgency": 0.8,
          "category": "transactional",
          "language": "string",
          "backend": "string",
          "input_hash": "string",
          "cached": false
        },
        "reasons": ["string"],
        "computed_at": "2026-10-01T12:00:00.000Z"
      }
    }
  ]
}

Update Thread

http
PATCH /v0/threads/{thread_id}

Adds and removes labels on every message in the thread (up to 500 messages); the thread labels are their union. Labels are free strings, system labels included. Returns the updated thread without messages.

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

Path parameters

thread_idstringRequired
ID of the thread.

Request body

Content type: application/json.

add_labelsstring | string[]
Label or labels to add to every message in the thread.
remove_labelsstring | string[]
Label or labels to remove from every message in the thread. Applied after add_labels.

Response

200 The updated thread, without messages (application/json)

inbox_idstringRequired
ID of the inbox.
thread_idstringRequired
ID of the thread.
labelsstring[]Required
Labels of the thread: the union of the labels of its messages.
timestampstring (date-time)Required
Timestamp of the last sent or received message.
received_timestampstring (date-time)
Timestamp of the last received message.
sent_timestampstring (date-time)
Timestamp of the last sent message.
sendersstring[]Required
Senders in the thread. In format username@domain.com.
recipientsstring[]Required
Recipients (to and cc) in the thread. In format username@domain.com.
subjectstring
Subject of the thread.
previewstring
Text preview of the last message in the thread.
attachmentsAttachment[]
Attachments in the thread.
last_message_idstringRequired
ID of the last message in the thread.
message_countintegerRequired
Number of messages in the thread.
sizeintegerRequired
Size of the thread in bytes.
updated_atstring (date-time)Required
Time at which the thread was last updated.
created_atstring (date-time)Required
Time at which the thread was created.
pod_idstringRequired
ID of the pod.

Each item of attachments is a Attachment:

attachment_idstringRequired
ID of the attachment.
filenamestring
Filename of the attachment.
sizeintegerRequired
Size of the attachment in bytes.
content_typestring
Content type of the attachment.
content_dispositionstring
Content disposition of the attachment (inline or attachment).
content_idstring
Content ID of the attachment.

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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

Request
curl -X PATCH "https://api.machinemail.dev/v0/threads/thd_01k6x3a1fz0000c9k5ns1x4e6g" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "add_labels": "string"
}'
Response 200
{
  "inbox_id": "agent@machinemail.dev",
  "thread_id": "thd_01k6x3a1fz0000c9k5ns1x4e6g",
  "labels": ["UNREAD"],
  "timestamp": "2026-10-01T12:00:00.000Z",
  "received_timestamp": "2026-10-01T12:00:00.000Z",
  "sent_timestamp": "2026-10-01T12:00:00.000Z",
  "senders": ["customer@example.com"],
  "recipients": ["agent@machinemail.dev"],
  "subject": "Order #1042",
  "preview": "Thanks for the quick reply.",
  "attachments": [
    {
      "attachment_id": "att_01k6x3h7qv0000m7v3xb9f2p4r",
      "filename": "invoice.pdf",
      "size": 2048,
      "content_type": "application/pdf",
      "content_disposition": "string",
      "content_id": "string"
    }
  ],
  "last_message_id": "msg_01k6x3a1g00000d0m6pt2y5f7h",
  "message_count": 1,
  "size": 2048,
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f"
}

Delete Thread

http
DELETE /v0/threads/{thread_id}

Permanently deletes the thread and its messages (up to 500).

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

Path parameters

thread_idstringRequired
ID of the thread.

Response

200 Deleted (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.
409Conflicts with an existing resource.
500Unexpected server error.

Error bodies use the error envelope.

Example

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