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
cat smashsend.com/docs/api/broadcasts.md
1.  [        Home        ](https://smashsend.com/) / 3.  [        Docs        ](https://smashsend.com/docs) / 5.  [        API Reference        ](https://smashsend.com/docs/api) / 7.  [        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 HTMLcreate = 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 testrequests.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.