Skip to main content
Transactional emails are programmatic, one-to-one emails sent in response to a user action or system event. Use them for password resets, order confirmations, account notifications, invoices, and any email that targets a specific individual rather than a broadcast audience.

Transactional vs. campaigns

TransactionalCampaigns
Triggered byAPI callDashboard action or schedule
AudienceOne or more specific recipientsAll subscribed contacts or a segment
Subscription checkIgnored — always deliveredRequired — only delivered to subscribed contacts
Use casePassword reset, invoice, notificationNewsletter, product announcement, promotion
Transactional emails bypass subscription state by design. A contact who has unsubscribed will still receive a transactional email. If you use a marketing template, however, that restriction still applies — see Template types.

Sending via the API

Use POST /v1/send with a secret API key. The endpoint accepts a single recipient or an array of recipients in one request.
curl -X POST https://api.useplunk.com/v1/send \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "[email protected]",
    "subject": "Your password reset link",
    "body": "<p>Click <a href=\"{{resetUrl}}\">here</a> to reset your password.</p>",
    "from": "[email protected]",
    "fromName": "Your App",
    "data": {
      "resetUrl": { "value": "https://yourapp.com/reset/abc123", "persistent": false }
    }
  }'

Request parameters

to
string | object | array
required
The recipient or recipients of the email.
subject
string
required
The email subject line. Supports {{variable}} substitution from the data object.
body
string
required
The HTML body of the email. Supports {{variable}} substitution and {{variable ?? 'fallback'}} syntax.
from
string | object
required
The sender address. Must belong to a verified domain in your project.
fromName
string
Display name for the sender. Alternative to passing from as an object with a name field.
reply
string
Reply-to email address.
template
string
ID of a template to use for the email. The template’s subject, body, from, and fromName are used as defaults — any fields provided in the request override the template values.
data
object
Key-value pairs used for template variable substitution and, by default, saved as contact data.
  • Persistent (default): "firstName": "Jane" — saved to the contact record and usable in future emails.
  • Non-persistent: "resetCode": { "value": "ABC123", "persistent": false } — used only for this email, not saved.
headers
object
Additional email headers to include, as a flat key-value object. For example, { "X-Campaign-ID": "welcome-flow" }.
attachments
array
Array of attachment objects. Maximum 10 attachments, 10 MB total. Each object requires:
  • filename — the filename displayed to the recipient
  • content — base64-encoded file content
  • contentType — MIME type, e.g. "application/pdf" or "image/png"
subscribed
boolean
Explicitly set the contact’s subscription state. If omitted, existing contacts keep their current state; new contacts default to unsubscribed.

Sending to multiple recipients

Pass an array to to to send the same email to multiple recipients in a single API call. Each recipient is processed independently — their contact record is created or updated, variables are resolved against their own data, and a separate email record is created for each.
{
  "to": [
    { "name": "Jane Doe", "email": "[email protected]" },
    { "name": "John Smith", "email": "[email protected]" }
  ],
  "subject": "Your invoice is ready",
  "body": "<p>Hi {{name}}, your invoice for {{amount}} is attached.</p>",
  "from": { "name": "Billing", "email": "[email protected]" },
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "JVBERi0xLjQK...",
      "contentType": "application/pdf"
    }
  ]
}

Sending with attachments

Include the attachments array in the request body. Each attachment must be base64-encoded.
{
  "to": "[email protected]",
  "subject": "Your receipt",
  "body": "<p>Thanks for your order. Your receipt is attached.</p>",
  "from": "[email protected]",
  "attachments": [
    {
      "filename": "receipt-1042.pdf",
      "content": "JVBERi0xLjQK...",
      "contentType": "application/pdf"
    }
  ]
}
Emails with attachments count as two emails toward your billing usage, regardless of the number of attachments. The maximum is 10 attachments and 10 MB total across all attachments in a single send.

Sending with a template

Pass the template parameter with a template ID to use a saved template. Any fields you provide in the request body (such as subject or from) override the template’s stored values.
{
  "to": "[email protected]",
  "template": "tpl_abc123",
  "data": {
    "firstName": "Jane",
    "resetUrl": { "value": "https://yourapp.com/reset/xyz", "persistent": false }
  }
}
The data object is merged with the contact’s existing data to resolve {{variable}} placeholders in the template. Non-persistent values (using { "value": "...", "persistent": false }) are available only for this send and are not saved to the contact record.
Use non-persistent data for one-time values like password reset tokens, OTP codes, or signed URLs — anything that should not overwrite the contact’s stored fields.

Subscription state behavior

Transactional emails are delivered regardless of the contact’s subscription state. This makes them appropriate for account and transactional notifications that the user must receive.
Contact stateEmail delivered?
SubscribedYes
UnsubscribedYes
The one exception is marketing templates — even through /v1/send, a marketing template will not be sent to an unsubscribed contact. Use a transactional template if the email must reach all contacts. See Template types.

API reference

See the full endpoint reference at POST /v1/send.

Build docs developers (and LLMs) love