Skip to main content
Use emails.send when your backend needs to send one email to one primary recipient, such as an order confirmation, password reset, account invite, receipt, shipping update, lead magnet delivery, or product update. emails.send creates one durable EmailSend. The REST route is POST /api/v1/emails; each accepted request freezes one content source, resolves one primary Profile, freezes the effective envelope, enqueues delivery, and returns the EmailSend status handle. Use emails.batchSend when your backend already has several independent EmailSends to create at once. Each item has its own primary recipient, data, idempotency key, durable status record, and result. If you are deciding between one email, batch email, event-triggered Journeys, Broadcasts, or Newsletter Issues, start with Which API should I use?.
EmailSend accepts exactly one content source: a saved Email Template (templateKey or templateId) or a rendered JSX Email wrapper (content). Do not send raw top-level html, text, react, inline template content, Template aliases, Template slugs, Template names, or locale-key resolution in v1.

Prerequisites

  • A saved, active Email Template, or rendered content produced by the official TypeScript SDK JSX Email helper or another HTML renderer.
  • A verified sending domain.
  • A SenderProfile on that verified sending domain.
  • A purpose-scoped API Key with emails:write to send and emails:read to retrieve status.
  • A caller-generated Idempotency-Key for every emails.send request, or an item-level idempotencyKey for every emails.batchSend item.
EmailSend accepts saved Email Templates and rendered JSX Email content. Purpose determines send policy:
  • Transactional templates are treated as transactional sends and do not require subscriptionGroupId.
  • Promotional, Newsletter, LeadMagnetDelivery, and General templates are treated as marketing-class sends and require subscriptionGroupId.
  • Rendered content must include an explicit purpose: "transactional", "marketing", or "newsletter". Marketing and newsletter rendered sends require subscriptionGroupId; Segmentflow injects the compliance footer automatically.

Send one email

Use templateKey to choose a saved Email Template. Use envelope fields such as from, to.email, subject, replyTo, cc, and bcc the same way you would in an email provider API, while still keeping the content template-backed.
The response is the durable EmailSend status handle. Store send.id in your system and use it for reconciliation.
Ordinary create and retrieve responses echo the safe effective envelope: from, replyTo, subject, to, cc, and subscriptionGroupId. They do not echo bcc.

Send rendered JSX Email

For Node.js applications, use the official TypeScript SDK JSX Email helper. The SDK renders JSX locally with jsx-email and sends Segmentflow a rendered content payload. Other API clients can render HTML themselves and pass content: { type: "rendered", renderer: "jsx-email", html, text? }. Segmentflow freezes the rendered HTML/text as the send history; it does not create a fake reusable Template. Install the SDK, jsx-email, React, and the JSX Email peer plugins in the app that renders email components. The JSX Email helper requires Node.js 22 or later because jsx-email 3 requires Node.js 22 or later.
For purpose: "marketing" and purpose: "newsletter", Segmentflow automatically injects unsubscribe, preferences, and web-view footer links at send time. For purpose: "transactional", Segmentflow does not inject a marketing footer. The helper records source metadata with @segmentflow/segmentflow-typescript/jsx-email. Other SDKs and direct HTTP integrations can send the rendered wrapper directly when they already rendered HTML in their app:
Rendered content rules:
  • content.type must be "rendered" and content.renderer must be "jsx-email".
  • purpose is required for rendered sends.
  • subject is required because there is no saved Template subject fallback.
  • content.text is optional. Segmentflow generates a plain-text fallback from HTML when omitted.
  • Rendered HTML is limited to 1 MiB UTF-8, rendered text to 256 KiB, and the combined rendered body to 1.25 MiB.
  • Customer headers are not accepted through the TypeScript SDK JSX Email helper or EmailSend API.
  • Marketing and newsletter rendered sends use Segmentflow-injected unsubscribe, preferences, and web-view footer links.
  • Web-view HTML shows the compliance-injected content before click tracking rewrites. Provider HTML may include Segmentflow tracking redirects.
Rendered responses return templateId: null and a rendered source:

Recipient resolution

Every EmailSend has exactly one primary recipient. That primary recipient resolves to one Profile and creates at most one Message. Use to.email when you know the recipient email address:
Add to.externalId when you want Segmentflow to link or reconcile the Profile against your stable customer id:
Use top-level profileId when you already know the Segmentflow Profile. If you omit to.email, Segmentflow uses the Profile’s canonical email for delivery.
profileId and to.email must refer to the same Profile. to.externalId alone must resolve to an existing Profile; include to.email when the send may need to create a new Profile. EmailSend does not update durable Profile properties. Use the Profiles API or events.track profile.properties when you need future segmentation or personalization state.

Content source, sender, and subject

Pass exactly one of templateKey, templateId, or content. For saved Templates, pass the stable templateKey. templateId remains available as an advanced fallback when you need to pin an exact database id. v1 does not resolve aliases, slugs, locale keys, or template names. If you edit the Template after a send is accepted, the existing EmailSend still uses the Frozen Email Instance created for that send. For rendered JSX Email in Node.js, call client.v1.emails.sendJsxEmail. The TypeScript SDK renders locally with jsx-email and sends Segmentflow a rendered content payload. Other clients can pass content: { type: "rendered", renderer: "jsx-email", html, text? } directly. Segmentflow stores source metadata on the frozen Email Instance so dashboards and API responses can show that the send came from rendered JSX Email without pretending it used a saved Template. SenderProfile resolution is deterministic:
  1. Use request from or senderProfileId when present.
  2. If both from and senderProfileId are present, they must resolve to the same SenderProfile.
  3. For saved Template sends, otherwise use the SenderProfile saved on the Template.
  4. For rendered sends, from or senderProfileId is required.
  5. If no compatible SenderProfile on a verified domain resolves, the send is rejected or skipped with InvalidSenderProfile.
from accepts a bare email or "Name <email@example.com>". The email must exactly match a verified SenderProfile email. A verified domain does not authorize arbitrary local-parts. replyTo accepts one bare email or "Name <email@example.com>". It may differ from from, but it must use a verified sender domain owned by your Organization. Request-level subject is final text. Segmentflow freezes it onto the EmailSend and does not interpolate it. If you omit subject on a saved Template send, the saved Template subject is frozen instead. Rendered sends must include subject.

Copied recipients

Use cc and bcc to copy operational recipients on the same provider envelope.
cc and bcc accept a single friendly-address string or an array of friendly-address strings. Segmentflow validates and stores them for provider handoff. Copied recipients are envelope-only in v1:
  • They do not create Profiles.
  • They do not create Messages.
  • They do not own personalization.
  • They do not receive separate Delivery Events.
  • Primary Profile erasure, suppression, and subscription checks apply to the primary recipient, not copied recipients.
cc is returned in ordinary create and retrieve responses for operational visibility. bcc is stored for delivery and retry behavior, but ordinary API responses, Resource Events, and dashboard list rows do not expose it.

Batch independent sends

emails.batchSend accepts up to 100 independent items. Use shared defaults for fields that are identical across the batch, then override specific fields on each item.
Batch defaults can include templateKey, templateId, content, purpose, from, senderProfileId, subject, replyTo, subscriptionGroupId, and tracking. Each item can override those defaults. After defaults merge with an item, each item must have exactly one effective content source: templateKey, templateId, or content. If an item supplies any source field, that item source replaces the default source fields. Batch defaults cannot include profileId, to, data, cc, or bcc. Recipient identity, one-send data, and copied recipients must stay item-specific. Malformed batch envelopes fail the whole request. Item-specific validation, idempotency, sender, template, or recipient failures return Rejected results for those items without rolling back accepted items. emails.batchSend is not a campaign sender. Use Broadcasts or Newsletter Issues when the system should compute or manage an audience, scheduling, campaign review, compliance controls, or one shared message sent to a segment.

Tracking

Click tracking is enabled by default. Set tracking.clicks: false for sends where links should not pass through a redirect. In rendered HTML, add data-no-track, data-segmentflow-no-track, or ses:no-track to individual links that must never be rewritten. Compliance links are never tracked. Open tracking is disabled for email in v1 and cannot be enabled per request.

Subscription groups

Pass subscriptionGroupId when this email should respect a specific SubscriptionGroup. If the primary recipient is not subscribed according to that group’s OptIn or OptOut policy, Segmentflow creates a durable skipped EmailSend with skippedReason: "ProfileUnsubscribed". Omit subscriptionGroupId only for transactional sends, such as password resets or receipts. For Promotional, Newsletter, LeadMagnetDelivery, and General saved Templates, subscriptionGroupId is required so Segmentflow can apply consent policy. For rendered content, purpose: "marketing" and purpose: "newsletter" require subscriptionGroupId; Segmentflow injects compliance links automatically.

Retrieve status

Store the returned id in your system. Use it as the durable handle for reconciliation when Resource Events are delayed or unavailable.
Retrieve responses follow the same envelope echo rules as create responses: safe fields such as from, replyTo, subject, to, and cc are returned, while bcc is not.

Idempotency

Every emails.send request requires an Idempotency-Key header. Every emails.batchSend item requires an idempotencyKey field. Choose a stable key from your business event, such as order-confirmation:ord_9421 or password-reset:user_123:<reset-request-id>. Idempotency is scoped to your Organization and the full effective request. The effective request includes the resolved recipient identity, content source, sender, subject, replyTo, copied recipients, tracking settings, subscription gate, and one-send data. For rendered content, the fingerprint includes rendered HTML, rendered text, purpose, purpose-resolved compliance behavior, tracking settings, and source metadata.
  • Reusing the same key with the same effective request returns the existing EmailSend with its current status.
  • Reusing the same key with a different effective request returns 409 Conflict for emails.send or a Rejected item result for emails.batchSend.
  • Keys remain reserved for the lifetime of the EmailSend record.
  • Idempotent replay does not re-enqueue, re-render, recreate a Message, or send a duplicate email.
Moving a batch field between defaults and an item does not change idempotency when the merged effective request is the same.

Status lifecycle

Delivery, open, click, bounce, and complaint outcomes are separate Delivery Records or Message events. They do not mutate the EmailSend lifecycle status.

Raw HTTP

See the API Reference for the complete request and response schema.