The Thread object
The Inbox API reads and triages the team's shared email inbox, the one on the Emails page. It works on conversations, not single messages: every message that shares a provider thread belongs to one conversation, and a message with no thread is a conversation of its own.
Each conversation has a threadKey. Use it with every Inbox API endpoint. Wherever a threadKey is accepted you can also pass the ID of any message in the conversation, which is handy when you only have a message ID from GET /api/v1/emails.
Places and states
A conversation is in one folder (a place) and carries state on top of that:
| Folder | What is in it |
|---|---|
inbox | Conversations with at least one received message that are not archived or snoozed |
snoozed | Conversations hidden until a later time |
archived | Conversations archived out of the Inbox |
sent | Conversations you have sent mail in |
drafts | Conversations holding an unsent draft |
all | Everything except spam, trash and bulk |
bulk | Machine mail: newsletters, reports, autoresponders |
spam | Marked as spam by a person |
trash | Moved to the trash |
Spam, trash and bulk are held apart. A conversation in one of them appears only there.
Ownership and open or closed are not folders. They are filters you add to a folder, so "unassigned mail in the Inbox" is folder=inbox&assignee=unassigned.
Archive is not close
Archive takes a conversation out of the Inbox until the next reply arrives, which brings it back. Closed is the team's shared "handled" state and stays closed when new mail arrives.
Fields
| Field | Type | Notes |
|---|---|---|
threadKey | string | The conversation's stable key |
latestMessageId | string | The newest message. Changes when mail arrives |
subject | string | The first message's subject |
snippet | string | Short plain-text preview of the latest message |
messageCount | integer | |
unreadCount | integer | Received messages nobody has opened in the app |
lastAt | string (ISO 8601) | Latest activity |
latestDirection | string | INBOUND or OUTBOUND |
state | string | OPEN or CLOSED |
closedAt | string or null | |
assignee | object or null | { id, name }. Null means Unassigned |
spam | boolean | |
trashed | boolean | |
archived | boolean | |
snoozedUntil | string or null | |
bulk | boolean | Machine mail |
hasDraft | boolean | |
tags | array | { id, name, color }. The same tags contacts and deals use |
mailbox | object or null | The connected mailbox the conversation lives in: { id, address, label } |
contact / lead | object or null | The CRM record the conversation belongs to |
unmatchedSender | object or null | Who wrote in, when there is no contact or lead |
replyClass | string or null | Classification of the latest received message, such as INTERESTED |
campaign / deal | object or null | { id, name } when the conversation is filed under one |
aging | object | See below |
Aging
aging answers "is this waiting on us, and for how long". It is worked out from the messages each time you read it.
| Field | Notes |
|---|---|
waitingOnUs | true when the conversation is open and the customer's message is the latest one |
waitingSince | When the first unanswered message in the current run arrived. Three follow-ups over two days is a two-day wait |
waitingMins | Minutes since waitingSince |
overdue | Past the workspace's first-response target. Always false when no target is set |
Example
{
"threadKey": "18c2f0a9b1d4e5f6",
"latestMessageId": "cmq5mail0alk34567890",
"subject": "Pricing for 500 units",
"snippet": "Hi, could you send pricing for 500 units delivered to Toronto?",
"messageCount": 3,
"unreadCount": 1,
"lastAt": "2026-09-27T14:02:00.000Z",
"latestDirection": "INBOUND",
"state": "OPEN",
"closedAt": null,
"assignee": { "id": "cmq1user0alk34567891", "name": "Rita Cole" },
"spam": false,
"trashed": false,
"archived": false,
"snoozedUntil": null,
"bulk": false,
"hasDraft": false,
"tags": [{ "id": "cmq7tag00alk34567890", "name": "Pricing", "color": null }],
"mailbox": { "id": "cmq8acct0alk34567890", "address": "sales@example.com", "label": "Sales" },
"contact": { "id": "cmq2cont0alk34567891", "name": "Ann Lee", "email": "ann@customer.co" },
"lead": null,
"unmatchedSender": null,
"replyClass": "INTERESTED",
"campaign": null,
"deal": null,
"aging": { "waitingOnUs": true, "waitingSince": "2026-09-27T14:02:00.000Z", "waitingMins": 42, "overdue": false }
}Scopes
| Scope | Endpoints |
|---|---|
read:emails | Listing and reading conversations, reading comments, the summary and the assignee list |
write:emails | Assign, close and reopen, spam, trash, archive, snooze, tags, and adding comments |
None of these endpoints send mail. Replies are drafted with POST /api/v1/emails/{id}/reply.