Emails

List inbound emails

Changed on

Returns a paginated list of INBOUND emails received at your verified domains. Outbound messages sent via /send-mail are not included; this endpoint is the inbox view, not a unified send/receive history.

Supports filtering by domain, status, date range, and free-text search across subject, sender, and recipient fields.

For a compact text-table summary of the most recent N inbounds (no filters, no cursor pagination), the CLI ships primitive emails:latest as a one-line-per-email shortcut. It's TTY-aware so id columns are full UUIDs when piped, and a --json flag returns the same envelope this endpoint does. Use whichever fits the call site.

get/emails

Request

  • Base URL
    https://api.primitive.dev/v1
  • URL
    https://api.primitive.dev/v1/emails
  • Auth
    HTTP bearer

Query parameters

cursorstring

Pagination cursor from a previous response's meta.cursor field. Format: {ISO-datetime}|{id}

limitinteger

Number of results per page

domain_idstring uuid

Filter by domain ID

status'pending' | 'accepted' | 'completed' | 'rejected'

Lifecycle status of an INBOUND email (a row in the emails table). Distinct from SentEmailStatus, which describes the OUTBOUND lifecycle (the sent_emails table) and uses a different vocabulary because the lifecycles differ. Possible values:

  • pending: the row was inserted at ingestion (mx_main) and has not yet completed the spam / filter / auth pipeline. Body and parsed fields are present; webhook delivery is not yet scheduled. Most rows transition out of pending within seconds.
  • accepted: the inbound passed the policy gates and is queued for webhook delivery. The webhook_status field tracks the separate webhook-delivery lifecycle from this point.
  • completed: terminal success. Webhook delivery attempted and acknowledged by every active endpoint, OR no endpoints are configured, so the row is durably archived.
  • rejected: terminal failure at ingestion (spam, blocked sender, filter rule, malformed). The body and metadata are stored for auditing but no webhook fires and the row is not repliable.

See also webhook_status (separate enum tracking the webhook-delivery state machine) and SentEmailStatus (the outbound vocabulary).

Filter inbound rows by lifecycle status. See EmailStatus for what each value means. Note that the webhook delivery state is a SEPARATE lifecycle on the same row; filter by webhook_status semantics is not currently supported on this endpoint.

searchstring

Search subject, sender, and recipient (case-insensitive)

date_fromstring date-time

Filter emails created on or after this timestamp. An ISO 8601 timestamp with Z or a numeric UTC offset (2026-10-02T00:00:00Z, 2026-10-02T00:00:00-04:00). An offset is read as the instant it names. A time with no zone, or a bare date, is rejected.

date_tostring date-time

Filter emails created on or before this timestamp. An ISO 8601 timestamp with Z or a numeric UTC offset (2026-10-02T00:00:00Z, 2026-10-02T00:00:00-04:00). An offset is read as the instant it names. A time with no zone, or a bare date, is rejected.

sincestring

Forward-tail cursor. Returns rows that became visible AFTER this cursor, oldest-first, so a caller can stream new inbound mail by re-passing the cursor from each response. Mutually exclusive with cursor (which pages history newest-first). Pass the meta.cursor from the previous since response; an empty page means caught up.

waitinteger

Long-poll: hold the request up to this many seconds waiting for new mail past since, returning as soon as any arrives (or an empty page when the wait elapses). Requires since. Omitted means no wait (returns immediately); the server treats an absent value as 0. NOT given an OpenAPI default on purpose: a default makes some generators (e.g. openapi-python-client) send wait=0 on every call, which then fails the wait requires since check for plain history listings.

awaiting'you' | 'them'

Only return emails whose awaiting has this value. awaiting=you lists mail waiting on your reply. Combines with every other filter and with both cursor and since. The filter (either value, here, on search and as the awaiting: search term) matches delivered mail only: emails whose status is rejected are never returned by it. A rejected email (for example one refused because the organization is over its storage limit) was never delivered, so nobody can answer it and it is awaiting no one; its own awaiting field still reports the stored value, usually you. Whose turn it is in this email's conversation. A send counts as a reply unless its status is gate_denied, agent_failed, canceled (queued and scheduled replies count: they are committed to go). For an email with a thread_id: them when the thread's latest counted outbound send (by send created_at, including any counted reply to this email itself) is at or after the thread's latest inbound message (by received_at); otherwise you. For an email with no thread_id: them when it has at least one counted reply (reply_count > 0 for an API key), otherwise you. It is a thread-level fact: every email in a thread carries the same value, and it reflects sends made by any credential in the organization, including other agent connections. It changes without a new inbound message, for example when a reply is sent, a queued reply fails, a scheduled reply is canceled, or a message is deleted, and is always current when read.

automated'true' | 'false'

Only return emails whose automated has this value. awaiting=you&automated=false lists mail from people that is waiting on your reply. Combines with every other filter and with both cursor and since. An inbound email is automated when any of these holds, decided once when it arrives: null_envelope_sender (an empty MAIL FROM, a bounce); no_identifiable_sender (no address in the envelope or From); own_address (a sender address is exactly one of the addresses the mail was delivered to; sharing a domain with the recipient is not enough, so a colleague or another agent in the organization is not automated); mailer_daemon (mailer-daemon@ or postmaster@ on any domain); auto_submitted (Auto-Submitted with any keyword but no, an empty one included); precedence (Precedence bulk, list, junk or auto_reply); list_unsubscribe (List-Unsubscribe present); list_id (List-Id present); auto_response_suppress (X-Auto-Response-Suppress asks for no automatic reply: All, OOF or AutoReply); failed_recipients (X-Failed-Recipients present, a bounce); report (a delivery, feedback or disposition report). Mail Primitive's own automatic responders decline to answer is always automated. The header rules only see headers captured at ingest, so older mail may lack them. This is loop and noise protection, not sender authentication.

recipientstring email

Exact case-insensitive delivered recipient mailbox, applied before pagination. Combines with existing filters and cursors; does not search message text.

exclude_fyi'true' | 'false'

With true, leave out emails whose fyi is true. Combines with every other filter and with both cursor and since.

from_verified'true' | 'false'

Only return emails whose from_verified (the From domain was authenticated on arrival; see the field) has this value. Combines with every other filter and with both cursor and since.

includestring
Example:body_text,headers

Extra parts on every row, comma-separated: body_text, body_html, headers, attachments. Reads a page of messages in one request instead of one detail read per row. Parts are withheld where the detail read withholds them. Each body field is cut to 64 KiB per row and a response carries at most 2048 KiB of body text, in page order; a cut or omitted body is named in truncated_fields. Unknown values are a validation_error.

thread_idstring uuid

Only return emails in this thread (the thread_id on an email or sent email). Combines with every other filter and with both cursor and since. Returns the same emails the list would return without it, narrowed to the thread, so an agent connection key still sees only mail delivered to its address.

exclude_muted'true' | 'false'

With true, leave out emails whose muted is true. Combines with every other filter and with both cursor and since.

search_regex'true' | 'false'

With true, search is a POSIX regular expression matched against the subject, sender and recipient (case-insensitive unless search_case_sensitive is true). At most 100 characters; nested quantifiers, groups of five or more alternatives and repeated range quantifiers are refused with 400. Needs a non-empty search; not with wait.

search_case_sensitive'true' | 'false'

With true, search matches case exactly. Needs a non-empty search; not with wait.

search_negate'true' | 'false'

With true, keep only emails whose subject, sender and recipient all fail to match search (an empty field counts as not matching). Needs a non-empty search; not with wait.

kind'regular' | 'dsn' | 'complaint' | 'auto_reply' | 'tls_report' | 'dmarc_report' | 'dmarc_failure'

Only received messages of this kind: regular mail, a delivery status notification (dsn), a complaint, an auto_reply, or a tls_report, dmarc_report or dmarc_failure report.

content_discarded'true' | 'false'

With true, only emails whose content was discarded after delivery; with false, only emails that still have it.

include_presence'true' | 'false'

Receiver presence mail: the presence probes sent to a connected agent and its answers. Left out by default for a connected-agent credential and listed by default for any other credential. true lists it, false leaves it out. Presence mail that inbound processing verified as presence on arrival expects no answer and does not count toward awaiting. Presence mail stored before that verification existed keeps the awaiting value it was stored with, so it can still count toward awaiting; include_presence=true, or any credential other than a connected agent's, still lists it. Combines with every other filter and with both cursor and since.

Response

Paginated list of emails

successtrue required

Changes

    • warning

      added the new access_mode_unavailable enum value to the / response property for the response status

    • warning

      added the new access_mode_unavailable enum value to the / response property for the response status

    • warning

      added the new builtin_role enum value to the / response property for the response status

    • warning

      added the new builtin_role enum value to the / response property for the response status

    • warning

      added the new cleanup_incomplete enum value to the / response property for the response status

    • warning

      added the new cleanup_incomplete enum value to the / response property for the response status

    • warning

      added the new cli_access_refused enum value to the / response property for the response status

    • warning

      added the new cli_access_refused enum value to the / response property for the response status

    • warning

      added the new confirmation_required enum value to the / response property for the response status

    • warning

      added the new confirmation_required enum value to the / response property for the response status

    • warning

      added the new connection_owner_address_required enum value to the / response property for the response status

    • warning

      added the new connection_owner_address_required enum value to the / response property for the response status

    • warning

      added the new email_rule_author_only enum value to the / response property for the response status

    • warning

      added the new email_rule_author_only enum value to the / response property for the response status

    • warning

      added the new email_rule_compiler_unavailable enum value to the / response property for the response status

    • warning

      added the new email_rule_compiler_unavailable enum value to the / response property for the response status

    • warning

      added the new email_rule_conflict enum value to the / response property for the response status

    • warning

      added the new email_rule_conflict enum value to the / response property for the response status

    • warning

      added the new email_rule_not_compiled enum value to the / response property for the response status

    • warning

      added the new email_rule_not_compiled enum value to the / response property for the response status

    • warning

      added the new grant_forbidden enum value to the / response property for the response status

    • warning

      added the new grant_forbidden enum value to the / response property for the response status

    • warning

      added the new keep_refused enum value to the / response property for the response status

    • warning

      added the new keep_refused enum value to the / response property for the response status

    • warning

      added the new last_owner enum value to the / response property for the response status

    • warning

      added the new last_owner enum value to the / response property for the response status

    • warning

      added the new mailbox_not_claimable enum value to the / response property for the response status

    • warning

      added the new mailbox_not_claimable enum value to the / response property for the response status

    • warning

      added the new mailbox_shared_with_others enum value to the / response property for the response status

    • warning

      added the new mailbox_shared_with_others enum value to the / response property for the response status

    • warning

      added the new member_address_reserved enum value to the / response property for the response status

    • warning

      added the new member_address_reserved enum value to the / response property for the response status

    • warning

      added the new plan_required enum value to the / response property for the response status

    • warning

      added the new plan_required enum value to the / response property for the response status

    • warning

      added the new redeploy_failed enum value to the / response property for the response status

    • warning

      added the new redeploy_failed enum value to the / response property for the response status

    • warning

      added the new removal_failed enum value to the / response property for the response status

    • warning

      added the new removal_failed enum value to the / response property for the response status

    • warning

      added the new removal_timeout enum value to the / response property for the response status

    • warning

      added the new removal_timeout enum value to the / response property for the response status

    • warning

      added the new role_assigned enum value to the / response property for the response status

    • warning

      added the new role_assigned enum value to the / response property for the response status

    • warning

      added the new role_assignment_unavailable enum value to the / response property for the response status

    • warning

      added the new role_assignment_unavailable enum value to the / response property for the response status

    • warning

      added the new role_key_taken enum value to the / response property for the response status

    • warning

      added the new role_key_taken enum value to the / response property for the response status

    • warning

      added the new rotation_in_progress enum value to the / response property for the response status

    • warning

      added the new rotation_in_progress enum value to the / response property for the response status

    • warning

      added the new rotation_incomplete enum value to the / response property for the response status

    • warning

      added the new rotation_incomplete enum value to the / response property for the response status

    • warning

      added the new step_up_invalid enum value to the / response property for the response status

    • warning

      added the new step_up_invalid enum value to the / response property for the response status

    • warning

      added the new step_up_not_accepted enum value to the / response property for the response status

    • warning

      added the new step_up_not_accepted enum value to the / response property for the response status

    • warning

      added the new step_up_refused enum value to the / response property for the response status

    • warning

      added the new step_up_refused enum value to the / response property for the response status

    • warning

      added the new step_up_required enum value to the / response property for the response status

    • warning

      added the new step_up_required enum value to the / response property for the response status

    • warning

      added the new template_role enum value to the / response property for the response status

    • warning

      added the new template_role enum value to the / response property for the response status

    • warning

      added the new upstream_unavailable enum value to the / response property for the response status

    • warning

      added the new upstream_unavailable enum value to the / response property for the response status

    This list may be incomplete.

    • warning

      added the new agent_changed enum value to the / response property for the response status

    • warning

      added the new agent_changed enum value to the / response property for the response status

    • warning

      added the new agent_limit enum value to the / response property for the response status

    • warning

      added the new agent_limit enum value to the / response property for the response status

    • warning

      added the new already_member enum value to the / response property for the response status

    • warning

      added the new already_member enum value to the / response property for the response status

    • warning

      added the new directory_limit enum value to the / response property for the response status

    • warning

      added the new directory_limit enum value to the / response property for the response status

    • warning

      added the new invitation_accepted enum value to the / response property for the response status

    • warning

      added the new invitation_accepted enum value to the / response property for the response status

    • warning

      added the new invitation_changed enum value to the / response property for the response status

    • warning

      added the new invitation_changed enum value to the / response property for the response status

    • warning

      added the new invitation_pending enum value to the / response property for the response status

    • warning

      added the new invitation_pending enum value to the / response property for the response status

    • warning

      added the new invitation_sending enum value to the / response property for the response status

    • warning

      added the new invitation_sending enum value to the / response property for the response status

    • warning

      added the new invitation_unconfirmed enum value to the / response property for the response status

    • warning

      added the new invitation_unconfirmed enum value to the / response property for the response status

    • warning

      added the new invitations_pending enum value to the / response property for the response status

    • warning

      added the new invitations_pending enum value to the / response property for the response status

    • warning

      added the new member_changed enum value to the / response property for the response status

    • warning

      added the new member_changed enum value to the / response property for the response status

    • warning

      added the new project_changed enum value to the / response property for the response status

    • warning

      added the new project_changed enum value to the / response property for the response status

    • warning

      added the new recipient_changed enum value to the / response property for the response status

    • warning

      added the new recipient_changed enum value to the / response property for the response status