Transactional

Send transactional or marketing email

Changed on

Queues an email for sending. The default emailType is transactional. Set it to marketing for a consented single-recipient lifecycle or promotional message. Marketing mode creates or links a minimal subscriber, honors unsubscribe suppression, adds the standard marketing footer, and emits RFC 8058 one-click-unsubscribe headers. The caller remains responsible for having consent or another lawful basis.

For callers that may retry, send a stable Idempotency-Key header. The same key and request returns the original emailSendId for 14 days without another delivery. Reusing a key with different request content returns 409.

Repeated identical transactional content reaching many distinct recipients can trigger a junk/list-testing review. Sending continues while review is pending or unavailable. A substantiated verdict can reject later matching deliveries before sending; these become terminal failed sends with an errorMessage beginning Transactional content rejected:. Read GET /email-sends/{emailSendId} for the final outcome. Failed deliveries are not held or replayed automatically, and replaying the same Idempotency-Key returns the original acceptance response. Dashboard retries of rejected deliveries also fail without sending, even after the decision expires. Correct the content or contact support before deliberately submitting a new logical send. This check does not pause the company or ban the account.

You can either:

  • Provide a canonical slug (or compatibility alias templateId) to use a saved template
  • Provide subject and canonical body (or compatibility alias html) to send custom content directly

If both a canonical field and its alias are provided, slug must match templateId and body must match html.

Tracking direct-content sends:

  • Set trackAs on a direct-content send (for example weekly-report) to count it under one code-managed transactional email. The first send with a new value creates it with managedBy: code; later sends with the same value link to it. The value may use up to 255 ASCII letters, digits, spaces and . _ - : /, and is normalized like a slug (Weekly Report and weekly-report are the same email). Other values, including empty ones, return 400 INVALID_TRACK_AS.
  • Opens, clicks, bounces and the other transactional stats then aggregate on that email, and it appears in GET /transactional next to your saved templates. Its subject, preview text and HTML are a snapshot of a recent send, refreshed at most every 10 minutes and stored before variable substitution.
  • Disabling the code-managed email makes further sends with that trackAs fail with 400 TRACKED_EMAIL_DISABLED until you enable it again. Deleting it lets the next send recreate it with fresh stats.
  • trackAs cannot be combined with slug/templateId, cannot reuse the slug of a template managed in the dashboard, and a company can have at most 100 code-managed emails. Use a stable name for an email type, never per-recipient values. Code-managed emails cannot be sent by slug.
  • The email is created after the send passes request validation, so an invalid send does not create it. A send that fails later, for example on an Idempotency-Key conflict, can still leave the newly created email with no sends.

Recipients:

  • to can be a single email or an array of up to 50 emails
  • Duplicate emails are automatically deduplicated
  • Marketing mode requires exactly one to recipient and does not support cc or bcc

Attachments:

  • Attachments can be provided as Base64-encoded content or URLs
  • Maximum 10 attachments and 15MB total per email
  • Any file type supported (PDFs, images, documents, etc.)
  • Set contentId on an attachment to embed it as an inline image referenced from the HTML as <img src="cid:VALUE">

A successful response means the email was accepted for background processing. Transactional emails are not blocked by subscriber unsubscribe or double opt-in status. If a recipient is suppressed because of a hard bounce or spam complaint, the worker records the send as suppressed instead of delivering it.

Optionally set from (domain must be verified) and replyTo addresses. When reply tracking is enabled, Sequenzy uses a unique trackable Reply-To header and treats the resolved reply destination as the forwarding destination for captured replies. Without a reply identity override, saved-template sends prefer the template reply profile. Otherwise sends prefer the effective sending domain's default reply profile, then the company default, then the first company reply profile. The resolved destination is retained whether or not reply tracking is enabled; it is sent as the Reply-To header only when reply tracking is disabled. Variables can be passed to customize the email content. Nested objects and arrays are supported for repeat blocks, such as items. {{viewInBrowserUrl}} is generated automatically for a hosted copy link. For a single recipient, Sequenzy matches an existing subscriber by subscriberExternalId or email and backfills stored first and last names when the corresponding request variables are omitted; explicit variables take precedence. Returns immediately with a durable emailSendId and the accepted emailType. If Sequenzy detects likely missing or unused variables before queueing, the successful response includes a non-blocking diagnostics warning object. Missing values do not block queueing or sending; a required variable that is not provided and has no default renders as an empty string.

Select existing identities with senderProfileId or fromEmail (and optional fromName), and replyProfileId or replyTo (with optional replyToName). These inputs look up profiles rather than create them. Use emailType, not isMarketing, to choose delivery policy.

post/transactional/send

Request

  • Base URL
    https://api.sequenzy.com/api/v1
  • URL
    https://api.sequenzy.com/api/v1/transactional/send
  • Auth
    HTTP bearer

Headers

Idempotency-Keystring

Caller-owned key for one logical email. Reuse the same key and request on retries to receive the original send for 14 days. Reusing the key with different content returns 409.

Request body

slugstring

Canonical slug of the transactional email template to use (mutually exclusive with direct content).

templateIdstring

Compatibility alias for slug. Despite the field name, pass the saved transactional email API slug, not its database ID. Must match slug when both are provided.

subscriberExternalIdstring

Customer-owned subscriber ID for single-recipient sends. If it matches an existing subscriber, analytics and localization use that subscriber; the value is also stored on the send and emitted as external_id in outbound email webhooks even when no subscriber exists. Maximum length is 255 characters.

emailType'transactional' | 'marketing'

Delivery policy. Marketing mode requires one recipient, creates or links a minimal subscriber, honors unsubscribe suppression, adds the standard footer, and emits RFC 8058 List-Unsubscribe and List-Unsubscribe-Post headers.

subjectstring

Email subject (required if not using slug)

bodystring

Canonical email body HTML content (required if not using a template slug).

htmlstring

Compatibility alias for body. Accepted with subject for direct sends and must match body when both are provided.

previewstring

Preview text for the email (only used with direct content)

trackAsstring

Direct content only. Names the email type so its sends are counted under one code-managed transactional email, created on first use. Up to 255 ASCII letters, digits, spaces and . _ - : /, including at least one letter or digit; it is normalized like a slug. Cannot be combined with slug/templateId.

variablesobject

Variables for template replacement (works with both modes). Values can be scalars, nested objects, or arrays used by repeat blocks. For a single recipient, stored subscriber first and last names fill missing name variables; explicit request variables take precedence. Raw HTML templates can use simple subscriber/custom-attribute conditionals such as {{#if subscriber.plan}}...{{else}}...{{/if}} and {{#unless subscriber.plan}}...{{/unless}}. Variables are always HTML-escaped; a template can prefix a tag with html. ({{html.prerenderedHtml}}) to insert a trusted HTML value unescaped. 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. Likely variable issues are returned as non-blocking diagnostics when possible; missing required variables without defaults render as empty strings and do not block sending.

fromstring

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. When the address exactly matches an existing sender identity (the display name disambiguates if several identities share the address), that identity - including its sending route - is used for the send; otherwise the template or company-default identity is kept and this field only changes the visible From. Mutually exclusive with senderProfileId, fromEmail and fromName.

replyTostring

Reply-to address as "Name <email>" or a bare email, optionally paired with replyToName. Mutually exclusive with replyProfileId. With reply tracking enabled, Sequenzy sends a trackable Reply-To and stores this address as its forwarding destination. Without a reply override, saved-template sends prefer the template reply profile; otherwise sends prefer the effective sending-domain default, then company default, then the first company reply profile.

headersobject

Extra email headers as header name to string value, up to 50 applied. Names use letters, digits and hyphens (max 100 characters); values are one line of printable ASCII and each Name: value line fits in 998 characters. A transactional send can carry your own List-Unsubscribe, plus List-Unsubscribe-Post: List-Unsubscribe=One-Click for RFC 8058 one-click unsubscribe; unsubscribes through your link are not suppressed in Sequenzy. Marketing sends always use Sequenzy's signed unsubscribe headers, so List-Unsubscribe, List-Unsubscribe-Post, Precedence and Feedback-ID are not applied. Headers Sequenzy manages (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-) are never applied. A header that cannot be applied never fails the request; it is listed in the response ignoredHeaders. Names match case-insensitively; when names differ only in case, only the first one is considered, even if it is not applied. A retry of a failed delivery (dashboard or outage recovery) resends without these headers.

senderProfileIdstring

Existing verified sender profile ID. Mutually exclusive with fromEmail, fromName and from. Selects that identity and its sending route; does not create a profile.

fromEmailstring

Address of an existing verified sender profile in this company. Mutually exclusive with senderProfileId and from. If several identities share the address, select one with fromName.

fromNamestring

Display name selecting an existing identity on fromEmail. Requires fromEmail; mutually exclusive with senderProfileId and from. Does not create a profile.

replyProfileIdstring

Existing reply profile ID. Mutually exclusive with replyTo and replyToName. Overrides the saved template and default reply identity.

replyToNamestring

Display name for a bare replyTo address. Requires replyTo and is mutually exclusive with replyProfileId. Does not create a profile.

Example request

{
  "slug": "welcome-email",
  "templateId": "welcome-email",
  "subscriberExternalId": "user_123",
  "emailType": "marketing",
  "subject": "Welcome to our platform!",
  "body": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
  "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
  "preview": "Welcome to our platform",
  "trackAs": "weekly-report",
  "variables": {
    "NAME": "John",
    "event": {
      "items": [
        {
          "title": "Pro plan",
          "description": "Monthly subscription"
        }
      ]
    }
  },
  "from": "Notifications <notifications@example.com>",
  "replyTo": "Support <support@example.com>",
  "attachments": [
    {
      "filename": "invoice.pdf",
      "path": "https://example.com/invoices/123.pdf"
    }
  ],
  "trackingSettings": {
    "clickTracking": false
  },
  "headers": {
    "List-Unsubscribe": "<https://example.com/unsubscribe/digest?token=abc>",
    "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
  }
}

Response

Email queued successfully

OR

Example response

{
  "success": true,
  "emailSendId": "send_abc123",
  "jobId": "job_abc123",
  "diagnostics": {
    "status": "warning",
    "message": "Email was queued. A required variable is missing and will render as an empty string.",
    "missingRequiredVariables": [
      {
        "name": "RESET_URL",
        "lookupName": "reset_url",
        "message": "Email was queued. Required variable \"RESET_URL\" is missing and will render as an empty string.",
        "usedIn": [
          {
            "surface": "block",
            "field": "url",
            "blockId": "reset-button",
            "blockType": "button"
          }
        ],
        "suggestions": [
          "resetpasswordlink"
        ]
      }
    ],
    "unusedVariables": [
      {
        "name": "resetpasswordlink",
        "message": "Variable \"resetpasswordlink\" was provided but is not used by the email template.",
        "suggestions": [
          "reset_url"
        ]
      }
    ]
  },
  "ignoredHeaders": [
    {
      "name": "List-Unsubscribe",
      "reason": "managed_in_marketing_mode"
    }
  ]
}

Changes

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • info

      added the optional property to the response with the status

    • breaking

      the / request property's minItems was increased to 1

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      the request property default value true was removed

    • info

      the request property default value true was removed

    • info

      added subschema #1: Slug-based response subschema #2: Direct content response to the response body anyOf list for the response status

    • info

      removed subschema #1: Slug-based response subschema #2: Direct content response from the response body oneOf list for the response status