# Create broadcast

> Create a draft broadcast.

Source: https://sndr.sh/docs/cranl/broadcasts/create-broadcast

`POST https://api.sndr.sh/api/cranl/v1/broadcasts`

Create a draft broadcast. Returns 201 with the broadcast. The from domain is not checked here; if it is not verified, every recipient fails at send time.

Scope: `send`

**Body** (JSON)

- `name` (string, required): Internal campaign name, 1–120 characters.
- `group_id` (string, required): Contact group to send to (grp_...). Must belong to the connected account.
- `from_email` (string, required): Sender, as an address or "Name <address>", on a verified domain.
- `subject` (string, required): Subject line, 1–500 characters.
- `html` (string): HTML body. Required unless text or template_id is set. {{email}}, {{first_name}}, {{last_name}} and any contact attribute (e.g. {{plan}}) are filled in per recipient.
- `text` (string): Plain-text body.
- `template_id` (string): Saved template (tpl_...) whose html and text are used when the broadcast has no body.

**Request**

```bash
curl -X POST 'https://api.sndr.sh/api/cranl/v1/broadcasts' \
  -H 'Authorization: Bearer sndr_your_access_token' \
  -H 'Content-Type: application/json' \
  -d '{
    "name":       "June newsletter",
    "group_id":   "grp_4d8a0c5e-1f7",
    "from_email": "Acme <hello@acme.com>",
    "subject":    "June product update",
    "html":       "<h1>June update</h1><p>Here is what is new.</p>"
  }'
```

**Response** (201)

```json
{
  "id":               "bca_9b3e6d12-a40",
  "organization_id":  "org_8d41c7a2-3f6",
  "name":             "June newsletter",
  "group_id":         "grp_4d8a0c5e-1f7",
  "from_email":       "\"Acme\" <hello@acme.com>",
  "subject":          "June product update",
  "html":             "<h1>June update</h1><p>Here is what is new.</p>",
  "status":           "draft",
  "total_recipients": 0,
  "sent_count":       0,
  "failed_count":     0,
  "created_at":       "2026-06-01T12:00:00Z"
}
```

**Errors**

- `unauthenticated` (401): Missing or invalid Bearer token.
- `token_expired` (401): Access token expired — exchange the refresh token for a new pair.
- `token_revoked` (401): Token was explicitly revoked.
- `invalid_request` (400): Body is not valid JSON, has an unknown field, or a field has the wrong type.
- `insufficient_scope` (403): Token is missing the send scope.
- `validation_failed` (422): A required field is missing or too long, from_email is invalid, there is no body or template, or group_id is not in this account.
