Skip to main content
POST
Send Email
Send an email using a saved template (by slug) or custom content. The endpoint defaults to transactional delivery. Use emailType: "marketing" for consented lifecycle or promotional messages that need unsubscribe handling. Use emailType to select delivery policy and trackingSettings to opt out of open or click tracking for one send. isMarketing is not a request field.
A successful response means the email was accepted for background processing. Transactional emails bypass subscriber unsubscribe and double opt-in status. Marketing emails honor those statuses. Both modes suppress hard bounces and spam complaints. A suppressed send is recorded instead of delivered. Use the returned emailSendId with the email-send details endpoint to inspect the final status and any provider failure reason.

Safe retries

string
A caller-owned key for one logical email, up to 255 characters. Agents and retrying workflows should generate the key before their first attempt and reuse that exact key for every retry of the same request.
Sequenzy retains the key and the accepted send for 14 days. Retrying with the same key and request returns the original response, includes Idempotent-Replayed: true, and does not create another delivery. The stored response is replayed as it was first returned, so a retry normally succeeds even if the template has since been renamed or disabled, or the sending domain’s verification lapsed. The exception is a send that is still queued and whose delivery job has to be rebuilt to recover it: that retry re-reads the template, so it fails if the template was deleted or disabled in the meantime. Reusing the key with different request content returns 409 IDEMPOTENCY_KEY_REUSED.
Do not generate a new idempotency key inside each retry attempt. A new key represents a new logical email and can create another delivery.

Repeated junk-content rejection

If identical transactional content reaches many distinct recipients within a short window, Sequenzy can review that content for junk/list testing. Identical content or high volume alone does not establish abuse. Sending continues while this review is pending or unavailable. A substantiated junk/list-testing verdict can reject subsequent matching deliveries before they are sent. The original API response still means accepted for background processing. Check Email Send Details for status: "failed" and an errorMessage beginning Transactional content rejected:. This is a terminal failure, not a queued hold: it is not automatically replayed when a decision expires. Correct the content or contact support before deliberately submitting a new logical send. Reusing the original idempotency key returns its original acceptance response and does not resend the failed delivery. Retrying a rejected delivery from the dashboard also fails without sending, including after the review decision expires. Submit corrected content as a new logical send instead. The same accepted-send and delivery-status behavior applies to CLI and MCP sends. This check does not pause your company or ban your account. Normal marketing misuse is advisory for this check; existing phishing and sender-health protections continue independently.

Rate limits

Sends are metered separately from the rest of the API: 1,000 requests per minute and 50 per second per API key, on top of the standard budget described in Rate Limiting. Each request sends to one recipient (or one to list), so a burst of confirmations does not starve the subscriber or campaign calls made on the same key. A 429 response carries Retry-After; queue and retry rather than dropping the send.

Request Body

Recipients

string | string[]
required
Recipient email address(es). Can be a single email string or an array of up to 50 emails. All recipients will receive the same email and can see each other in the To header.
string | string[]
Carbon-copy email address(es), visible to every recipient. A single email string or an array of up to 50. Addresses already present in to are removed. Transactional sends only.
string | string[]
Blind-carbon-copy email address(es), hidden from the other recipients. A single email string or an array of up to 50. Addresses already present in to or cc are removed. Transactional sends only.
cc and bcc are echoed back in the response when the accepted send has them, after the duplicates above are removed. The CLI exposes the same lists as sequenzy send <email...> with repeatable --cc <address> and --bcc <address> flags, and the MCP send_email tool as the to, cc, and bcc arguments.

Option 1: Send via template

string
Canonical transactional template slug (use this OR direct content).
string
Compatibility alias for slug. Despite the field name, pass the saved transactional email’s API slug, not its database ID.

Option 2: Send direct content

string
Email subject (required if no slug)
string
Canonical email HTML body (required if no template slug).
string
Compatibility alias for body, accepted with subject for direct sends.
string
Preview text
string
Names the email type, for example weekly-report, so every direct-content send with the same value is counted under one code-managed transactional email. See Track emails rendered in your code. Up to 255 ASCII letters, digits, spaces and . _ - : /, including at least one letter or digit. Cannot be combined with slug or templateId.
slug/body remain canonical. If you provide both slug and templateId, or both body and html, the paired values must match. A differing pair is rejected with 400 instead of silently choosing one.

Common fields

string
default:"transactional"
Delivery policy. Use transactional for messages that are necessary to complete a user-requested action or service. Use marketing for consented lifecycle or promotional messages. Marketing mode requires exactly one to recipient and does not support cc or bcc. It creates or links a minimal subscriber, honors unsubscribe suppression, adds Sequenzy’s standard marketing footer, and emits the RFC 8058 List-Unsubscribe and List-Unsubscribe-Post headers. The caller remains responsible for having a lawful basis or consent to send the message. A marketing send to a contact our team is reviewing is accepted but stays pending, with an errorMessage starting Held for review, and is sent once the review clears the contact.
object
Template variables for personalization. Values can be scalars, nested objects, or arrays. Repeat blocks read arrays from paths such as items. Raw HTML templates can also use subscriber/custom-attribute conditionals like {{#if subscriber.plan}}...{{else}}...{{/if}} and {{#unless subscriber.plan}}...{{/unless}}. If Sequenzy detects likely variable issues before queueing, the successful response includes diagnostics warnings. Missing required values do not block queueing; the worker renders values without defaults as empty strings and continues sending. For a single recipient, Sequenzy also matches an existing subscriber by subscriberExternalId or email and uses the stored first and last name when those values are omitted from variables. Explicit variables take precedence. Variables are always HTML-escaped. To insert a trusted HTML value unescaped (for example a prerendered order summary), prefix the tag with html. in the template: {{html.prerenderedHtml}}. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs are stripped), only applies in HTML text position, and must not contain end-user input. See Raw HTML variables.
{{ viewInBrowserUrl }} and {{ VIEW_IN_BROWSER_URL }} are reserved variables. Sequenzy replaces either form with a hosted copy URL at send time, so do not include them in variables. The hosted copy remains available while the email body is retained (normally 14 days).
string
Customer-owned subscriber ID for single-recipient sends. If it matches an existing subscriber, analytics, localization, and engagement attach to that subscriber even if the delivery email changed. Sequenzy also stores this value on the send, so outbound email webhooks include it as external_id even when no subscriber record exists. Maximum length: 255 characters.In marketing mode, this ID must either be unused or belong to the same email address. Sequenzy rejects an identity mismatch instead of risking an unsubscribe action against the wrong subscriber.
string
Custom from address. Format: "Name <email>" or just "email". The domain must be verified for your account. If not verified, this field is silently ignored and the default sender profile is used. When the address exactly matches an existing sender identity (the display name disambiguates if several share it), that identity - including its sending route - is used for the send. Mutually exclusive with senderProfileId and fromEmail.
string
Existing sender profile ID. Sends this email as that verified From identity (address and display name) instead of the company default or the saved template’s sender. Get IDs from List Sender Profiles. Mutually exclusive with fromEmail and from.
string
From address of an existing verified sender profile in this company. Mutually exclusive with senderProfileId and from. If the address has several identities, pass fromName to choose one (or senderProfileId). This field does not create a new sender profile.
string
Display name of an existing verified sender identity on fromEmail. Use this when one address has several identities, for example StudyBoost vs StudyBoost News. Requires fromEmail. Mutually exclusive with senderProfileId and from. Does not create a new sender profile.
string
Reply-to address. Format: "Name <email>" or just "email". Can be any valid email address. Mutually exclusive with replyProfileId. Pair a bare address with replyToName instead of embedding the name.When reply tracking is disabled, this is sent as the email’s Reply-To header. When reply tracking is enabled, Sequenzy sends a unique trackable Reply-To address instead and stores this value as the forwarding destination for replies.
string
Display name for a bare replyTo address. Requires replyTo. Mutually exclusive with replyProfileId. Does not create a reply profile.
string
Existing reply profile ID. Sends this email with that Reply-To identity instead of the company default or the saved template’s reply profile. Get IDs from List Sender Profiles. Mutually exclusive with replyTo.
from and replyTo control message identity, not the outbound transport. A mailbox or alias hosted by Hostinger or another provider can be used as from after its domain is verified, and as replyTo without domain verification. Sequenzy still performs delivery through SES or Sequenzy’s MTA; custom outbound SMTP relays are not supported.
Direct-content sends without a reply identity override prefer the effective sending domain’s default reply profile, then the company’s default reply profile, then the first reply profile in the company. Sequenzy retains that resolved address in originalReplyTo. When reply tracking is disabled, it is sent as the Reply-To header; when reply tracking is enabled, Sequenzy sends a unique trackable Reply-To and uses originalReplyTo as the forwarding destination. Template sends prefer the request override, then the template reply profile, then the same domain, company and first-profile fallback order.
array
File attachments to include with the email. Maximum 10 attachments, 15MB total.Each attachment object has:
  • filename (required): The name of the file as it will appear to the recipient
  • content: Base64-encoded file content (use this OR path)
  • path: URL to fetch the file from (use this OR content)
  • contentId: Embeds the file as an inline image instead of attaching it. Reference it from your HTML as <img src="cid:VALUE">
  • contentType: MIME type override. Defaults to the type inferred from filename
You must provide either content or path, but not both.
object
Per-send tracking opt-outs. When a field is omitted, the corresponding Transactional API default from Settings → Tracking applies. Set a field to false to disable that tracking for this send only. These fields can only opt out; they cannot enable tracking disabled by either an account-wide or Transactional API setting.
object
Extra email headers as an object of header names to string values, for example { "X-Entity-Ref-ID": "digest-42" }. Up to 50 headers are applied. Names may contain letters, digits and hyphens (up to 100 characters). Values must be one line of printable ASCII, and each Name: value line must fit in 998 characters.
  • Your own unsubscribe link: on a transactional send you can set List-Unsubscribe, and List-Unsubscribe-Post with the exact value List-Unsubscribe=One-Click for RFC 8058 one-click unsubscribe. List-Unsubscribe-Post is only applied together with List-Unsubscribe. Unsubscribes through your link go to your system; Sequenzy does not suppress the address.
  • Marketing mode: Sequenzy always adds its own signed unsubscribe headers and bulk signals, so List-Unsubscribe, List-Unsubscribe-Post, Precedence and Feedback-ID are not applied.
  • Headers Sequenzy manages are never applied: From, Sender, To, Cc, Bcc, Reply-To, Subject, Date, Message-ID, MIME-Version, Return-Path, Received, Received-SPF, Delivered-To, DKIM-Signature, Authentication-Results, and names starting with Content-, X-Sequenzy-, X-SES-, ARC- or Resent-. Use the dedicated request fields for sender, recipients, reply-to and subject.
A header that cannot be applied never fails the request. The send is queued without it and the response lists it in ignoredHeaders with a reason. Header names are matched case-insensitively. When names differ only in case, only the first one is considered, so later ones are ignored even if the first one was not applied. Headers apply to every automatic delivery attempt of the queued send. A retry of a failed delivery, from the dashboard or during Sequenzy’s outage recovery, resends the stored message without them.

Example: Send via template

Example: Send a consented lifecycle message

Sequenzy adds the visible unsubscribe footer and signed one-click headers. Do not supply an unsubscribe URL in the request. List-Unsubscribe headers in headers are not applied to a marketing send and are listed in ignoredHeaders. The successful queue response includes the accepted policy:

Example: Send array data to a repeat block

If a template contains a repeat block with source items and item alias item, child blocks can use merge tags like {{item.title}} and {{item.description}}.

Example: Send to multiple recipients

Example: Send direct content

The same direct send can use the html compatibility alias:

Track emails rendered in your code

Some emails are easier to build in your own code, like a weekly summary with per-account numbers. Send them as direct content and add trackAs to review their performance in one place:
  • The first send with a new trackAs creates a transactional email with managedBy: "code". Later sends with the same value link to it. The value is normalized like a slug, so Weekly Report and weekly-report are the same email. Its display name starts as a title (weekly-report becomes Weekly report) and can be renamed without affecting tracking. It may use up to 255 ASCII letters, digits, spaces and . _ - : /; anything else, including an empty value, returns 400 INVALID_TRACK_AS.
  • Sends, deliveries, opens, clicks and bounces aggregate on it like on a saved template. It is listed by GET /api/v1/transactional and in the dashboard, where you can review its stats and a snapshot of recent content. The snapshot refreshes at most every 10 minutes and is stored before variable substitution.
  • Your code stays the source of truth. A code-managed email cannot be sent by slug, and updates only accept name, enabled and labels.
  • Disabling it rejects further sends with that trackAs (400 TRACKED_EMAIL_DISABLED) until you enable it again. Sends already queued still go out. Deleting it also deletes its content snapshot; past sends stay in email-send history, and the next send creates a new email with fresh stats.
  • A value that matches the slug of a template managed in the dashboard is rejected (400 TRACK_AS_MANAGED_IN_DASHBOARD). Each company can have up to 100 code-managed emails (400 CODE_MANAGED_LIMIT_REACHED), so use a stable name for an email type and never include per-recipient values.
  • The email is created after the send passes request validation, so an invalid send does not create it. A send that fails later, such as an Idempotency-Key conflict, can leave the new email with no sends. The response includes a transactional object with its id, slug and name.

Example: Send with custom from and reply-to

Example: Send with URL-based attachment

Example: Send with Base64 attachment

Example: Send with an inline (CID) image

Set contentId and reference it from your HTML. The image is sent as a multipart/related part rather than a file attachment, which is the only form Gmail renders - it drops data: URI images.
If nothing in the HTML references cid:ticket-qr, the file is sent as a normal attachment instead. Keep your own per-email-type unsubscribe on a transactional send by passing your one-click URL in headers:
Your endpoint must accept the RFC 8058 POST that mailbox providers send to this URL and stop that email type for the recipient.

Responses

Emails are queued for background processing. Track the returned emailSendId with GET /api/v1/email-sends/{emailSendId}. For single-recipient sends without cc or bcc, EMAIL resolves from the recipient address. If the recipient matches a stored subscriber, FIRST_NAME, LAST_NAME, and NAME use the saved profile values when the request omits them. Passing name, firstName, lastName, FIRST_NAME, or LAST_NAME in variables overrides the corresponding saved value.
For aggregate Send API open and click rates, call GET /api/v1/metrics?period=30d&emailType=transactional, run sequenzy stats --email-type transactional --period 30d, or call the MCP get_stats tool with emailType: "transactional".
When using multiple to recipients, all recipient addresses are visible to each other. Use single-recipient sends when recipients should not see each other.
Multi-recipient sends produce a single email send record. The full recipient list (to/cc/bcc) is stored on the record and returned as additionalRecipients from the email-sends API. Opens and clicks are tracked for the message as a whole, not per recipient.