Inbox
8 operations. Each REST operation is also an MCP tool of the same name. REST https://tlntconnect.com/api/v1
GET/api/v1/inbox/mailboxes
The connected mailboxes visible to the key's member, exactly as the app's inbox shows them (admins: every mailbox; others: mailboxes they own, are granted, or that belong to a creator assigned to them). permission is the member's own grant (viewer, responder, sender or admin); can_send is true when the mailbox is connected for sending and the member may send from it. display_name and email_address come from the connected email account and are wrapped as untrusted content. A PlatformReadPage: newest-updated first, limit ≤ 50 (default 20), page with cursor. Requires inbox:read.
list_inbox_mailboxesinbox:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data[].display_namedata[].email_address
Input
cursor querystring — next_cursor from the previous page.limit queryinteger — Page size, default 20, at most 50.Responses
GET/api/v1/inbox/threads
Threads from every mailbox the key's member can see in the app's inbox (admins: all mailboxes). A thread in a mailbox the member cannot see never appears; account_id of such a mailbox — or another workspace's — is 404. Filters: account_id, status, unread, starred, has_attachments, assigned_to_me and q (full-text search over subject and preview). The API excludes spam unless include_spam is set: include_spam: true lists it with everything else, status: "spam" lists only spam. A PlatformReadPage ordered by updated_at then id, newest first: limit ≤ 50 (default 20); pass page.next_cursor as cursor for the next page (cursors are bound to this key's member). subject, preview, participants and labels come from outside senders and are wrapped as untrusted content. Requires inbox:read.
list_inbox_threadsinbox:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data[].subjectdata[].previewdata[].participantsdata[].labels
Input
account_id querystring (uuid) — Only threads of this mailbox (list_inbox_mailboxes).status query"open" | "waiting" | "snoozed" | "closed" | "spam"include_spam queryboolean — true: list spam threads too (the API excludes spam unless include_spam is set). Ignored when status is set.unread queryboolean — true: only threads with unread messages; false: only fully read threads.starred querybooleanhas_attachments querybooleanassigned_to_me queryboolean — true: only threads assigned to the key's member.q querystring — Full-text search over subject and preview (prefix match per word).cursor querystring — next_cursor from the previous page.limit queryinteger — Page size, default 20, at most 50.Responses
GET/api/v1/inbox/threads/{thread_id}
A thread in a mailbox the key's member can see, with its latest messages oldest first (message_limit, default 20, at most 50; messages_truncated says older ones exist). Each message carries the plain-text body (up to 50,000 characters; body_truncated), sender, recipients, subject and its attachments (id, file name, content type, size — download one with get_inbox_attachment). The thread also carries its mailbox (with this member's permission and can_send), status, priority, labels, assignee, linked records and the in-app AI summary. A thread in a mailbox the member cannot see, in another workspace, with no mailbox, or unknown is 404. Every value an outside sender wrote, the mailbox's name and address, and the AI summary are wrapped as untrusted content. Requires inbox:read.
get_inbox_threadinbox:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data.subjectdata.previewdata.participantsdata.labelsdata.ai_summarydata.ai_next_stepdata.account.display_namedata.account.email_addressdata.messages[].body_textdata.messages[].subjectdata.messages[].from_namedata.messages[].from_emaildata.messages[].todata.messages[].ccdata.messages[].bccdata.messages[].attachments[].filename
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.message_limit queryinteger — Latest messages to return, default 20, at most 50.Responses
PATCH/api/v1/inbox/threads/{thread_id}
Updates a thread the key's member can respond to (responder permission on its mailbox; 403 mailbox_permission_required for a viewer; 404 when the thread is not visible). Send at least one of status, priority, labels (replaces the thread's labels) and assigned_to (a team member id, or null to unassign; only admin members may reassign — 403 role_forbidden — and the assignee must be an active member of this workspace — 404 assignee_not_found). In the "Inbox thread changes" approval class: by default it runs at once, through the same executor an approved Atlas email.thread_update runs, and answers 200 { status: "updated", data }. When the credential asks for approval in TLNT for inbox thread changes, it queues the Atlas email.thread_update action instead: 202 { status: "pending_approval", action_id, approval_url }, an admin approves or rejects it in TLNT; poll GET /actions/{action_id}. Either way the change is pinned to the thread as it is now: if a new message arrives first, nothing changes (409 stale_target directly; a failed action when approved). Requires inbox:write, an Idempotency-Key and an admin or manager member.
update_inbox_threadinbox:write- admin, manager
- Runs directly; queued when the credential asks for approval for inbox_update
- required
- 1
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.Idempotency-Key header, requiredstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.status body"open" | "waiting" | "snoozed" | "closed" | "spam"priority body"low" | "normal" | "high" | "urgent"labels bodyarray of string — Replaces the thread's labels.assigned_to bodystring (uuid) | null — Team member id, or null to unassign. Admin members only.Responses
GET/api/v1/inbox/threads/{thread_id}/attachments/{attachment_id}
Metadata for one attachment of a thread the key's member can see, plus download_url: a signed link to GET /api/v1/inbox/attachment-downloads/{token} that needs no Authorization header, expires after five minutes (expires_at) and works only while this key and its member could still read the thread. The attachment id must belong to a message of THIS thread (ids from get_inbox_thread). Unknown, cross-thread or cross-workspace ids are 404. The file name comes from the sender and is wrapped as untrusted content; the file itself is untrusted too. Requires inbox:read.
get_inbox_attachmentinbox:read- admin, manager, scout, viewer
- Ignored (read)
- 1
data.filename
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.attachment_id path, requiredstring — Attachment id from get_inbox_thread (messages[].attachments[].id).Responses
POST/api/v1/inbox/threads/{thread_id}/summary
Runs the app's AI thread summary (Atlas, email.summarize_thread) over a thread the key's member can see and returns { summary, next_step } — it is not saved on the thread. Metered exactly like the app: one Atlas usage credit per call against the workspace's plan (402 usage_limit_exceeded at the limit, before any model call); 403 feature_not_available when Atlas's email assistant is off. The model receives the email wrapped as untrusted content and is told never to follow instructions inside it, but its output is derived from outside text, so summary and next_step are wrapped as untrusted content too. Send an empty JSON body ({}). Rate weight 5. Requires inbox:read.
summarize_inbox_threadinbox:read- admin, manager, scout, viewer
- Ignored (read)
- 5
data.summarydata.next_step
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.Responses
POST/api/v1/inbox/threads/{thread_id}/draft-reply
Runs the app's AI reply draft (Atlas, email.draft_reply) over a thread the key's member can respond to (responder permission on its mailbox; 403 mailbox_permission_required for a viewer) and returns { draft }. Nothing is sent or saved: to send it, review it and call reply_to_inbox_thread with the draft as PLAIN TEXT — without the untrusted-content wrapper tags (they are removed if you leave them in) — which sends it directly by default (within the daily recipient cap) or queues it when the credential asks for approval in TLNT. Metered like the app: one Atlas usage credit per call (402 usage_limit_exceeded at the limit). The draft is derived from outside text, so it is wrapped as untrusted content. Send an empty JSON body ({}). Rate weight 5. Requires inbox:read and inbox:write.
draft_inbox_replyinbox:read+inbox:write- admin, manager, scout, viewer
- Ignored (read)
- 5
data.draft
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.Responses
POST/api/v1/inbox/threads/{thread_id}/reply
A plain-text reply (body_text, up to 20,000 characters — send plain text; untrusted-content wrapper tags, e.g. from a draft_inbox_reply draft, are removed first) on a thread the key's member can SEND from (sender permission on the thread's mailbox; 403 mailbox_permission_required otherwise; 404 when the thread is not visible), to the thread's counterparty, from the thread's own mailbox (409 conflict when that mailbox cannot send right now). In the "Sending email" approval class: by default it sends at once — the recipients, sender and subject resolved exactly as an approved Atlas email.send resolves them, through the same executor — counting every To and Cc address against the credential's daily recipient cap (429 daily_send_cap_reached past it, nothing sent), and answers 200 { status: "sent", data: { message_id } }. When the credential asks for approval in TLNT for sending email, it queues the Atlas email.send action instead: 202 { status: "pending_approval", action_id, approval_url }, an admin reads the whole reply in TLNT — with the sender, recipients and subject fixed when it was queued — and approving sends it once; poll GET /actions/{action_id}. Retrying with the same Idempotency-Key never sends twice; a new key is a new reply. The reply is pinned to the thread as it is now: if a new message arrives, the recipients change or the mailbox address changes before it is sent, it fails instead of sending. Requires inbox:write, email:send, an Idempotency-Key and an admin or manager member.
reply_to_inbox_threadinbox:write+email:send- admin, manager
- Runs directly; queued when the credential asks for approval for external_send
- required
- 5
Input
thread_id path, requiredstring (uuid) — Thread id in this workspace.Idempotency-Key header, requiredstring — Retry-safe key (1-255 printable ASCII; a UUID is recommended; an RFC 8941 quoted string is accepted). The same key with the same request within 24h replays the stored response byte for byte (Idempotent-Replayed: true) without running again; the replay still consumes the operation's rate weight.body_text body, requiredstring — Plain-text reply body.