Everything smashsend.com publishes
S

smashsend.com

SMASHSEND Broadcasts API Reference

/docs/api/broadcasts

docs
Words
844
Reading time
4 min
Last crawled
2026-09-27
Language
EN
SMASHSEND Broadcasts API Reference
smashsend.com
  1. [

    Home

    ](https://smashsend.com/)

/

  1. [

    Docs

    ](https://smashsend.com/docs)

/

  1. [

    API Reference

    ](https://smashsend.com/docs/api)

/

  1. [

    Broadcasts

    ](https://smashsend.com/docs/api/broadcasts)

The Broadcasts API lets you create and schedule marketing broadcasts programmatically — perfect for automating a weekly newsletter from your own pipeline. You send us tested, raw HTML with merge variables; we handle audience resolution, link and open tracking, unsubscribe compliance, and delivery pacing.

Early access. The Broadcasts API is currently in early access. It requires the Email API add-on, a verified workspace, and the early-access flag enabled for your workspace — contact support to join.

Authentication

All endpoints authenticate with your API key as a Bearer token, exactly like the Emails API. Your workspace is derived from the key — no workspace ID in the URL.

Authorization: Bearer YOUR_API_KEY

Create a broadcast

POST/v1/broadcasts

Creates a draft broadcast from raw HTML. The HTML is stored exactly as you send it; tracking links and required footers are applied when the broadcast is scheduled.

curl -X POST https://api.smashsend.com/v1/broadcasts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly newsletter #42",
    "subject": "This week: {{firstName}}, the new roadmap is live",
    "previewText": "Fresh updates from the team",
    "fromEmail": "news@yourdomain.com",
    "fromName": "Dale from Acme",
    "html": "<html><body><h1 style=\"background:#0b1f3a;color:#fff\">Hello {{firstName}}</h1><p>...</p><a href=\"{{unsubscribeUrl}}\">Unsubscribe</a></body></html>",
    "audience": { "all": true },
    "settings": { "trackOpens": true, "trackClicks": true }
  }'

Response (201): the draft broadcast plus every merge variable we detected in your HTML, subject and preview text.

{
  "broadcast": {
    "id": "cmp_a1b2c3d4e5f6g7h8i9j0k",
    "name": "Weekly newsletter #42",
    "status": "DRAFT",
    "subject": "This week: {{firstName}}, the new roadmap is live",
    "audience": { "all": true },
    "scheduledAt": null,
    "sentAt": null
  },
  "variables": {
    "detected": ["firstName", "unsubscribeUrl"],
    "unknown": []
  }
}

Raw HTML rules

• Unsubscribe link is mandatory. If your HTML references {{unsubscribeUrl}} we leave your design untouched. If it doesn't, we append a standard unsubscribe footer — every marketing email must let recipients opt out. One-click unsubscribe headers are always added at the message level.

• Link tracking. When trackClicks is on (default), every http(s) link is rewritten through your tracking domain at schedule time. mailto:, tel: and anchor links are never rewritten, and neither is the unsubscribe link.

• Plain text. If you don't provide a text version we generate one from your HTML.

• Size limit. The HTML body can be up to 500 KB. For best deliverability keep it under 102 KB (Gmail clips larger messages).

Merge variables

Use {{variableName}} anywhere in the HTML, subject or preview text. Variables resolve per recipient from their contact properties — built-ins like {{firstName}}, {{lastName}} and {{email}}, any custom property by its API slug, plus system URLs: {{unsubscribeUrl}}, {{manageUrl}} (manage preferences) and {{contactId}}.

Unknown variables are rejected by default. A variable that doesn't exist as a contact property renders as empty text in the recipient's inbox ("Hi ,"), so the create request fails with

broadcast_unknown_variables listing the offending names. If you know what you're doing, pass

"allowUnknownVariables": true.

Missing values (a contact without firstName) always render as empty text — write copy that degrades gracefully, or test with the test endpoint below.

Send a test

POST/v1/broadcasts/:broadcastId/test

Sends the broadcast to up to 10 workspace members with a [TEST] subject prefix. Merge variables are rendered so the email looks exactly like the real send. Always test before scheduling.

curl -X POST https://api.smashsend.com/v1/broadcasts/cmp_a1b2.../test \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emails": ["you@yourdomain.com"] }'

Schedule (or send now)

POST/v1/broadcasts/:broadcastId/schedule

Locks the content, resolves the audience and queues the send. Omit sendAt to send immediately, or pass an ISO timestamp up to 90 days out. deliveryMethod controls pacing: ASAP, PROGRESSIVE, SMART (contact-timezone aware) or WARMUP. If your sending account is new we enforce WARMUP automatically — omit deliveryMethod and we always pick the safest available option.

curl -X POST https://api.smashsend.com/v1/broadcasts/cmp_a1b2.../schedule \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sendAt": "2026-07-08T15:00:00Z" }'

Scheduled broadcasts can be stopped with POST /v1/broadcasts/:broadcastId/cancel any time before sending starts (the broadcast returns to draft).

Read broadcasts

GET/v1/broadcasts

Lists broadcasts (cursor-paginated, filter with ?status=DRAFT). Fetch one with GET /v1/broadcasts/:broadcastId — poll status to follow the lifecycle: DRAFT → SCHEDULED → IN_PROGRESS → COMPLETED.

Full example: automated weekly newsletter (Python)

import requests

API = "https://api.smashsend.com"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

# 1. Create the draft from your generated, client-safe HTML
create = requests.post(f"{API}/v1/broadcasts", headers=HEADERS, json={
    "name": "Weekly newsletter",
    "subject": "{{firstName}}, this week's update",
    "fromEmail": "news@yourdomain.com",
    "fromName": "Dale from Acme",
    "html": open("newsletter.html").read(),
    "audience": {"all": True},
}).json()

broadcast_id = create["broadcast"]["id"]
assert not create["variables"]["unknown"], create["variables"]

# 2. Send yourself a test
requests.post(f"{API}/v1/broadcasts/{broadcast_id}/test",
              headers=HEADERS, json={"emails": ["you@yourdomain.com"]})

# 3. Schedule for tomorrow 9am UTC (after you've checked the test!)
requests.post(f"{API}/v1/broadcasts/{broadcast_id}/schedule",
              headers=HEADERS, json={"sendAt": "2026-07-08T09:00:00Z"})

Errors

• broadcast_api_not_enabled (403) — your workspace isn't in the early-access program yet.
• broadcast_api_addon_required (402) — enable the Email API add-on in billing settings.
• broadcast_api_workspace_not_verified (403) — your workspace must be verified before sending.
• broadcast_unknown_variables (400) — fix the listed variables or pass allowUnknownVariables.
• campaigns/invalid_from_email (400) — the from address isn't verified; the response lists your allowed emails and domains.
• campaigns/delivery_method_not_available (400) — usually means WARMUP is required for a new sending account.

37%873 words