Skip to main content
senderkit send fires a send from your terminal — the same operation as the SDK’s send() and sendRaw(). Useful for smoke-testing templates while you build them, scripting one-off blasts, and triggering messages from cron or CI. Like the SDK, both commands return as soon as the API has accepted the message — the id you get back is a queued message, not a delivered one. Watch it with messages list.

senderkit send

Send a templated message, filling in variables at send time.
senderkit send <template> <to> [options]

Arguments

template
required
Template slug, e.g. "welcome" or "password-reset".
to
required
Recipient address — email, phone number, or push token, matching the template’s channel.

Options

--vars <json>
Template variables as a JSON object, e.g. '{"name":"Ada","city":"London"}'. Substituted into the template’s variable holes.
--channel <email|sms|push|web-push>
Force a channel. Defaults to the template’s primary channel — only set this for multi-channel templates.
--version <number>
Pin a specific template version. Omit to let SenderKit pick the current published version for the environment.
--metadata <json>
Free-form metadata as a JSON object of strings, numbers, or booleans — e.g. '{"userId":"usr_123","orderId":"ord_9"}'. Indexed for later filtering in messages list.
--scheduled-at <iso8601>
Defer delivery until a future ISO 8601 timestamp, e.g. "2026-06-01T09:00:00Z". Must be in the future and within 30 days. The response comes back with status: scheduled instead of queued.
--idempotency-key <key>
Idempotency key. A repeat key within your workspace returns the original message instead of duplicating. Auto-generated if omitted — see Sending: Idempotency.
--reply-to <string>
Reply-To address for the message. Email only.
--cc <addresses>
Cc recipients as a comma-separated string (a@x.com,b@x.com) or a JSON array ('["a@x.com","b@x.com"]'). Email only.
--bcc <addresses>
Bcc recipients — same format as --cc. Email only.
--attachments <json>
Attachments as a JSON array, e.g. '[{"filename":"doc.pdf","contentType":"application/pdf","content":"<base64>"}]'. Email only. Total decoded size must not exceed 10 MB. For inline attachments, add "inline": true and a "contentId" value.
--from <string>
From address override (bare address, email only). Defaults to the provider connection’s configured address. On managed sending, honored only on the workspace’s verified sending domain.
--from-name <string>
From display name override (email only), rendered as Name <address>. Max 128 characters; no control characters or angle brackets. Always applies, regardless of sending domain.

Examples

# Simplest send — slug + recipient
senderkit send welcome user@example.com

# With variables
senderkit send welcome user@example.com --vars '{"name":"Ada"}'

# Pin a version and tag with metadata
senderkit send receipt user@example.com \
  --version 7 \
  --vars '{"amount":"$42"}' \
  --metadata '{"orderId":"ord_9"}' \
  --idempotency-key "receipt:ord_9"

# Schedule for later
senderkit send trial-ending user@example.com \
  --scheduled-at 2026-06-01T09:00:00Z

# Email with cc and an attachment
senderkit send receipt user@example.com \
  --vars '{"amount":"$42"}' \
  --cc "accounting@acme.com" \
  --attachments '[{"filename":"receipt.pdf","contentType":"application/pdf","content":"<base64>"}]'
Human-readable output on success:
✓ Queued message msg_01HZ…
id:     msg_01HZ…
status: queued
mode:   test
With --json, the same response as the send endpoint:
{
  "id": "msg_01HZ…",
  "status": "queued",
  "livemode": false
}

senderkit send-raw

Send inline content without a registered template. Useful for one-off messages that don’t warrant a template, or for testing provider configuration before you move copy into the dashboard.
senderkit send-raw <to> --channel <email|sms|push|web-push> [content options]
--channel selects the content shape; the required content options depend on the channel.

Arguments

to
required
Recipient address — email, phone number, push token, or (for web-push) the JSON-encoded browser PushSubscription object (endpoint + p256dh/auth keys).

Required option

--channel <email|sms|push|web-push>
required
Selects the content shape. Required on every call.

Email content (--channel email)

--subject <string>
required
Email subject line.
--html <string>
required
HTML body.
--text <string>
Plain-text fallback body.
--preheader <string>
Email preheader — the snippet shown in inbox previews.
--from <string>
From address override (bare address). Defaults to your workspace’s configured sender. On managed sending, honored only on the workspace’s verified sending domain.
--from-name <string>
From display name override, rendered as Name <address>. Max 128 characters; no control characters or angle brackets. Always applies, regardless of sending domain.
--reply-to <string>
Reply-To address.
--cc <addresses>
Cc recipients as a comma-separated string (a@x.com,b@x.com) or a JSON array ('["a@x.com","b@x.com"]').
--bcc <addresses>
Bcc recipients — same format as --cc.
--attachments <json>
Attachments as a JSON array. Total decoded size must not exceed 10 MB. Each item: { filename, contentType, content (base64), inline?, contentId? }.

SMS content (--channel sms)

--body <string>
required
SMS body.

Push content (--channel push)

--title <string>
required
Notification title.
--body <string>
required
Notification body.
--badge <number>
Badge count.
--sound <string>
Notification sound name.
--push-data <json>
Push data payload as a JSON object of strings, e.g. '{"deeplink":"app://x"}'.

Web Push content (--channel web-push)

--title <string>
required
Notification title.
--body <string>
required
Notification body.
--icon <url>
Icon URL shown in the notification.
--click-url <url>
URL opened when the user clicks the notification.
--badge <number>
Badge count.
--push-data <json>
Data payload as a JSON object of strings — available to the service worker that handles the push event, e.g. '{"deeplink":"app://orders/9"}'.

Shared options

--vars <json>
Variables for interpolation as a JSON object. Only substituted when --interpolate is set.
--metadata <json>
Free-form metadata as a JSON object.
--interpolate
Run server-side variable substitution over the content. Off by default — raw content is otherwise delivered verbatim.
--scheduled-at <iso8601>
Defer delivery until a future ISO 8601 timestamp, e.g. "2026-06-01T09:00:00Z". Must be in the future and within 30 days. The response comes back with status: scheduled instead of queued.
--idempotency-key <key>
Idempotency key.

Examples

# Email
senderkit send-raw user@example.com \
  --channel email \
  --subject "Hello from the CLI" \
  --html "<p>Welcome, {{name}}.</p>" \
  --vars '{"name":"Ada"}' \
  --interpolate

# Email with cc and attachment
senderkit send-raw user@example.com \
  --channel email \
  --subject "Your invoice" \
  --html "<p>Please find your invoice attached.</p>" \
  --cc "finance@acme.com" \
  --attachments '[{"filename":"invoice.pdf","contentType":"application/pdf","content":"<base64>"}]'

# Email with From overrides
senderkit send-raw user@example.com \
  --channel email \
  --subject "Hello from Acme" \
  --html "<p>Hi there.</p>" \
  --from "hello@acme.com" \
  --from-name "Acme"

# SMS
senderkit send-raw +14155551234 \
  --channel sms \
  --body "Your verification code is 042195"

# Push
senderkit send-raw "dev_token_…" \
  --channel push \
  --title "Order shipped" \
  --body "Tracking attached" \
  --badge 1 \
  --push-data '{"deeplink":"app://orders/9"}'

# Web Push (pass the JSON-serialised PushSubscription as the recipient)
senderkit send-raw '{"endpoint":"https://fcm.googleapis.com/…","keys":{"p256dh":"…","auth":"…"}}' \
  --channel web-push \
  --title "New message" \
  --body "You have a new message from Ada." \
  --icon "https://example.com/icon.png" \
  --click-url "https://example.com/messages"

When to reach for the CLI vs the SDK

Use the CLI for ad-hoc work: triggering a real send while building a template, scripting backfills, wiring up cron jobs that pipe through jq. For application code, use the TypeScript SDK — it adds automatic retries, batch helpers, and types.

Sending

What send() accepts now and delivers later.

Variables

How --vars fills the dynamic holes in a template.

Versioning

Why --version is rarely needed.

messages

Watch the message you just queued.