Sending

Send outbound email

Changed on

Sends an outbound email through Primitive's outbound relay. By default the request returns once the relay accepts the message for delivery. Set wait: true to wait for the first downstream SMTP delivery outcome.

Host routing. /send-mail is served by the canonical API host (https://api.primitive.dev/v1) so the request body can carry inline attachments up to ~30 MiB raw. The legacy dashboard compatibility host (https://www.primitive.dev/api/v1) also accepts /send-mail, but Vercel request body limits apply before proxying. The typed SDKs route /send-mail to the canonical API host automatically.

post/send-mail

Request

  • Base URL
    https://api.primitive.dev/v1
  • URL
    https://api.primitive.dev/v1/send-mail
  • Auth
    HTTP bearer

Headers

Idempotency-Keystring

Optional customer-supplied idempotency key. If omitted, Primitive derives one from the canonical request payload and echoes the effective value in the Idempotency-Key response header.

Request body

fromstring required

RFC 5322 From header. The sender domain must be a verified outbound domain for your organization.

tostring required

Recipient address. Recipient eligibility depends on your account's outbound entitlements.

subjectstring required

Subject line for the outbound message

body_textstring

Plain-text message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes.

body_htmlstring

HTML message body. At least one of body_text or body_html is required. The combined UTF-8 byte length of body_text and body_html must be at most 262144 bytes.

in_reply_tostring

Message-ID of the direct parent email when sending a threaded reply.

referencesstring[]

Full ordered message-id chain for the thread.

waitboolean

When true, wait for the first downstream SMTP delivery outcome before returning.

wait_timeout_msinteger

Maximum time to wait for a delivery outcome when wait is true. Defaults to 30000.

scheduled_atstring date-time

Optional future execution time (ISO 8601). When set, the send is recorded with status scheduled and executed at the requested time instead of immediately. Must be in the future and at most 30 days out. Incompatible with wait (a scheduled send resolves after this request completes) and with attachments / payload_attachments (not yet supported on scheduled sends). Reschedule via PATCH /sent-emails/{id}; cancel via /sent-emails/{id}/cancel. Accepts Z or a numeric UTC offset (2026-10-09T17:00:00Z, 2026-10-09T13:00:00-04:00); an offset is converted to UTC, so the stored and echoed value is UTC. A time with no zone, or a bare date, is rejected.

if_latest_message_idstring uuid

Send only if this message id is still the newest message in the thread this send joins, as this credential can see it. Newest means the message that joined the thread last, in the order messages were attached to it, not by timestamp: a message accepted earlier but attached later is newer. Messages stored before join order was recorded count as older than every message that has one, and among themselves sort by timestamp (received_at for mail received, created_at for mail sent), ties going to the larger id. Pass latest_message_id from GET /emails/{id}/conversation: it is read by the same rule, whereas the last message listed there is ordered by timestamp and can differ when mail joined the thread late. An organization credential sees every message in the thread; a mailbox-scoped agent connection key sees only mail received at its address and mail sent from it. Mail awaiting sender authentication never counts. Otherwise nothing is sent and the response is 409 latest_message_mismatch with error.details.latest_message_id, latest_message_at and thread_id. If in_reply_to resolves to no single thread this credential can check, the response is 422 latest_message_thread_unresolved; that does not change on retry. If the thread stays locked by another writer for longer than the send waits, the response is 503 thread_busy with Retry-After; nothing was sent and the same request can be retried. Checked inside the send transaction under a lock on the thread, so two sends conditioned on the same id cannot both go out. The value is part of the request a replay is matched on: a replay of an already accepted request with the same idempotency key, or the identical request within the automatic deduplication window, returns the original result without checking again, and a request that differs only in if_latest_message_id is not a replay. On /send-mail it requires in_reply_to; it cannot be combined with scheduled_at or repeat, because it is checked when the request is accepted.

fyiboolean

Send an informational message the receiver need not answer or wake for. It is sent as an ack signal (status received) about the message in in_reply_to, whose note is body_text (at most 2000 characters, which may be omitted). Receivers see it as fyi: true. Plain text only: it cannot be combined with body_html, attachments, payload_attachments or scheduled_at, and on /send-mail it requires in_reply_to.

headersobject

Extra headers, as { "Name": "value" }, at most 25. A name is one of Auto-Submitted, Precedence, X-Auto-Response-Suppress, X-Primitive-Interaction, X-Primitive-Interaction-Ref, X-Primitive-Function-Hop, or a custom X- name of letters, digits and hyphens that is not credential-like (a word such as auth, token, key, secret, session or bearer, joined forms included) and not in a reserved family: X-Primitive*, X-Original-, X-Originating-, X-Forwarded-, X-Received, X-Authenticated*, X-Envelope-, X-Delivered-To, X-Apparently-To, X-Failed-Recipients, X-Loop, X-Priority, X-MSMail-, X-MS-, X-Microsoft-, X-Forefront-, X-Exchange-, X-Google-, X-GM-, X-Apple-, X-Yahoo-, X-YMail-, X-AOL-, X-Spam*, X-Virus-, X-Proofpoint-, X-Barracuda-, X-Rspamd-, X-Mimecast-, X-IronPort-, X-Sophos-, X-Report-Abuse, X-CSA-*. Names compare case-insensitively (_ and . count as - for families); a repeated or any other name is a validation_error. Values: 1 to 200 printable ASCII characters. Custom headers are sent as spelled, are not DKIM-signed, and can be searched with header on GET /sent-emails.

Example request

{
  "headers": {
    "X-Campaign-Id": "spring-sale",
    "Auto-Submitted": "auto-generated"
  }
}

Response

Outbound relay result

successtrue required

Changes

    • 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_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_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_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_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_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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

    • 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

    • 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

    • 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

    • 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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • warning

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

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the non-success response with the status

    • info

      added the non-success response with the status