Skip to content
AI Inbx
Esc
navigateopen⌘Jpreview
On this page

Core concepts

Understand workspaces, sending identities, emails, threads, events, and customer spaces.

A workspace contains your API keys, sending identities, messages, and configuration. Use the resources below to configure where mail comes from, work with conversations, and handle delivery outcomes.

The two halves

Everything here divides cleanly. On one side are the objects that establish who you can send as: a domain you publish DNS for, or a mailbox a customer authorized. On the other are the objects that carry what you sent and what came back: emails, threads, and the events they emit.

You need exactly one thing from the first half before anything in the second half works.

Identity

Domain and Mailbox — the two ways an address becomes yours to send from. Pick one; most products end up with both.

Traffic

Email, Thread, Attachment — the messages themselves, and the conversation each one belongs to.

Identity

Domain

A domain you control the DNS for. Creating one returns the records to publish — SPF, DKIM, DMARC, a return path, and an MX record if you want to receive on it — and the domain can send once its DKIM identity is verified. Receiving also requires the inbound MX record.

A domain does not have to be yours. Publishing the records at a customer’s registrar makes their domain send through you, which is how a product sends as support@theircompany.com.

dom_… → verified_at, region, records[]

Domains

Each record, what diagnostics reports when one won’t resolve, and regions.

Mailbox

A Gmail or Outlook account a customer authorized over OAuth. No DNS, no verification — they click through a consent screen and the mailbox is live. In exchange you get one address rather than a whole domain, and the authorization can expire.

mbx_… → address, provider, app_id, state

Mailboxes

The connect flow, ref for matching a mailbox to your user, and reauth.

Traffic

Email

One message, inbound or outbound, with its addresses, bodies, headers, and attachments. Sending returns one; receiving one fires a webhook that names it.

An email’s status reports acceptance, not delivery — queued, sending, sent, scheduled. What actually happened at the far end arrives later, as events.

eml_… → thread_id, status, suppressed[], pacing

Thread

The conversation an email belongs to, and the reason this API exists. A reply is matched onto its thread by RFC headers first, then by quoted content — never by subject line alone, which is what makes unrelated “Re: Hi” messages collide elsewhere.

Because the thread is a real object, replying takes the thread ID and your text. The sender, the recipients, the subject, and the In-Reply-To/References headers are inferred from what’s already on the thread.

thr_… → subject, mailbox, messages[]

Threads

How matching decides, and what threads.reply fills in for you.

Attachment

A file on an email. Outbound, you pass base64 content. Inbound, you get metadata plus a preparation field — AI Inbx extracts a received PDF to Markdown so an agent can read it without you running a parser.

att_… → filename, content_type, size, preparation

Delivery outcomes

Event and webhook endpoint

Everything that happens after acceptance is an event: delivered, bounced, complained, opened, clicked, unsubscribed, plus the inbound email.received that starts most applications. A webhook endpoint is a URL subscribed to some of them.

Subscribe to webhooks for delivery outcomes as they occur. You can also retrieve an email and inspect its events array. A provider accepting a message does not establish that it reached the recipient’s inbox.

whk_… → url, subscriptions[], secret
evt_… → type, created_at, data

Sending controls

Two objects exist only to stop a send that shouldn’t happen.

Suppression

An address that must not be mailed, on a named list. Bounces and complaints create these automatically; unsubscribes and your own calls add more. Every send is checked against the list named by suppression_key, plus the org-wide * list.

Suppression is why a send can succeed with recipients missing — read suppressed on the response.

sup_… → address, key, scope, reason

Pacing rule

A ceiling on how fast a lane sends: a window, a rate, a spread. A held message comes back with a non-null pacing object naming the rule and projecting when it will go.

Transactional mail shouldn’t queue behind a campaign, so a send can set pacing.skip.

pace_… → window, rate, spread

Grouping by customer

Space

Optional. A group inside the workspace — one per customer, typically — that owns domains and mailboxes, and with them every email and thread that went through those. Pacing rules and suppression lists can be put in a space too, and then reach that space alone. API keys and webhook endpoints are workspace-wide.

Mail is never told its space: an email is in the space of the domain or mailbox it went through, and a reply is in its thread’s. Any space-aware resource created without a space belongs to the workspace itself and reads space_id: null.

spc_… → name

Spaces

When you need one, and a platform walkthrough end to end.

A message, through all of it

You send

POST /emails checks the from address against a verified domain or an active mailbox, checks each recipient against the suppression lists, and asks the pacing rules whether the lane has room.

An email and a thread exist

You get an email back with a thread_id — a new thread if nothing matched, an existing one if thread_id was passed. suppressed lists who was dropped; pacing is non-null if the message is held.

Events arrive

email.sent, then email.delivered — or email.bounced, which writes a suppression so the next send to that address never leaves.

They reply

Their message is matched onto the same thread and arrives as email.received, carrying the thread_id and a category that tells you how the message was classified. Classification is a signal for your application, not proof of sender identity.

You reply

threads.reply with the thread ID and your text. Every header that makes it a real reply is filled in from the thread.

Everything has an ID

Prefixed, opaque, stable, safe to store. The prefix is part of the ID — an ID of the wrong type is a 404, never a silent match against another resource.

Conventions

The full prefix table, pagination, timestamps, request IDs, and idempotency.

Last updated on September 9, 2026

Was this page helpful?