# Einen Newsletter senden

> Bereite einen Newsletter vor, lass die Vorlage genehmigen, sieh dir die Vorschau an, sende einen Test und sende ihn in einem Schritt mit einem Idempotency-Key.

Stand: 2026-10-30. Quelle: https://docs.smartchat.marketing/de/guides/send-a-newsletter/

Du brauchst einen Schlüssel mit diesen Rechten: `newsletters:write` zum Vorbereiten, `templates:submit`, um die Vorlage an WhatsApp zu geben, `newsletters:test` zum Testen und `newsletters:send` zum Senden. Lies zuerst [Sicher senden](https://docs.smartchat.marketing/de/security/).

Ein Newsletter wird als WhatsApp-**Vorlage** gesendet, und WhatsApp muss die Vorlage genehmigen, bevor etwas gesendet wird. Die Reihenfolge ist also: Entwurf, Genehmigung, Vorschau, Test, Senden. Alle Antworten auf dieser Seite gehören zu einer Geschichte: dem Newsletter "Autumn menu".

## 1. Den Entwurf anlegen

Der Text darf den Platzhalter `{{first_name}}` enthalten. Er wird durch den Vornamen jedes Kontakts ersetzt. Es ist der einzige Platzhalter, den ein Newsletter erlaubt. Der Text darf nicht mit einem Platzhalter beginnen oder enden.

**curl**

```bash
curl -X POST "https://api.smartchat.marketing/v1/newsletters" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "audience": {
    "tags": [
      "vip"
    ]
  }
}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/newsletters",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "title": "Autumn menu",
        "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
        "audience": {
            "tags": [
                "vip",
            ],
        },
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/newsletters", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "title": "Autumn menu",
    "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
    "audience": {
      "tags": [
        "vip"
      ]
    }
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (201):


```json
{
  "object": "newsletter",
  "id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "title": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "language": "en",
  "button": {
    "type": "url",
    "text": "See the menu",
    "url": "https://example.com/menu"
  },
  "audience": {
    "tags": [
      "vip"
    ],
    "mode": "any",
    "sources": []
  },
  "status": "draft",
  "template_id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "template_status": "draft",
  "ready_to_send": false,
  "not_ready_reason": "template_not_approved",
  "recipients": 412,
  "scheduled_at": null,
  "sent_at": null,
  "created_at": "2026-10-25T09:41:07Z",
  "updated_at": "2026-10-25T09:41:07Z"
}
```

Der Newsletter ist ein Entwurf. Er hat eine eigene Vorlage (`template_id`) und die Vorlage ist auch noch ein `draft`, deshalb ist `ready_to_send` gleich `false` und `not_ready_reason` gleich `template_not_approved`. Den Newsletter kannst du ändern ([`update_newsletter`](https://docs.smartchat.marketing/en/api/reference/newsletters/update_newsletter/)), bis er geplant ist.

## 2. Die Vorlage genehmigen lassen

WhatsApp entscheidet, ob eine Vorlage genutzt werden darf. Du gibst sie mit [`create_template_submissions`](https://docs.smartchat.marketing/en/api/reference/templates/create_template_submissions/) ab. Das braucht das Recht `templates:submit` und besteht aus zwei Aufrufen mit **verschiedenen** `Idempotency-Key`-Werten.

Erster Aufruf: eine Vorschau. Nichts wird eingereicht. Die Antwort zeigt, was passieren würde, und gibt eine `plan_id`, die 10 Minuten gilt.

**curl**

```bash
curl -X POST "https://api.smartchat.marketing/v1/template-submissions" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "template_ids": [
    "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
  ]
}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/template-submissions",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "template_ids": [
            "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
        ],
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/template-submissions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "template_ids": [
      "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
    ]
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (200):


```json
{
  "object": "template_submission_plan",
  "plan_id": "pln_9a8b7c6d5e4f43a2b1c0d9e8f7a6b5c4",
  "expires_at": "2026-10-25T09:52:00Z",
  "templates": [
    {
      "template_id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
      "name": "Autumn menu",
      "status": "draft",
      "outcome": "would_submit",
      "issues": [],
      "error_code": null
    }
  ],
  "submitted_at": null
}
```

Zweiter Aufruf: Sende dieselben `template_ids` mit der `plan_id`. Jetzt geht die Vorlage an WhatsApp.

**curl**

```bash
curl -X POST "https://api.smartchat.marketing/v1/template-submissions" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "template_ids": [
    "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
  ],
  "plan_id": "pln_9a8b7c6d5e4f43a2b1c0d9e8f7a6b5c4"
}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/template-submissions",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "template_ids": [
            "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
        ],
        "plan_id": "pln_9a8b7c6d5e4f43a2b1c0d9e8f7a6b5c4",
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/template-submissions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "template_ids": [
      "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234"
    ],
    "plan_id": "pln_9a8b7c6d5e4f43a2b1c0d9e8f7a6b5c4"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (200):


```json
{
  "object": "template_submission",
  "plan_id": null,
  "expires_at": null,
  "templates": [
    {
      "template_id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
      "name": "Autumn menu",
      "status": "pending",
      "outcome": "submitted",
      "issues": [],
      "error_code": null
    }
  ],
  "submitted_at": "2026-10-25T09:42:10Z"
}
```

Die Vorlage ist `pending`. Lies den Newsletter ab und zu ([`get_newsletter`](https://docs.smartchat.marketing/en/api/reference/newsletters/get_newsletter/)), bis `template_status` den Wert `approved` und `ready_to_send` den Wert `true` hat. Lehnt WhatsApp die Vorlage ab, ist `template_status` gleich `rejected`; ändere den Text und reiche sie noch einmal ein.

**curl**

```bash
curl "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
    headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
  },
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (200):


```json
{
  "object": "newsletter",
  "id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "title": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "language": "en",
  "button": {
    "type": "url",
    "text": "See the menu",
    "url": "https://example.com/menu"
  },
  "audience": {
    "tags": [
      "vip"
    ],
    "mode": "any",
    "sources": []
  },
  "status": "draft",
  "template_id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "template_status": "approved",
  "ready_to_send": true,
  "not_ready_reason": null,
  "recipients": 412,
  "scheduled_at": null,
  "sent_at": null,
  "created_at": "2026-10-25T09:41:07Z",
  "updated_at": "2026-10-25T10:05:00Z"
}
```

## 3. Die Vorschau ansehen

Die Vorschau liest und rechnet. Sie sendet nichts.

**curl**

```bash
curl "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview?when=now" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview",
    headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
    params={
        "when": "now",
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview?when=now", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
  },
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (200):


```json
{
  "object": "newsletter_send_preview",
  "newsletter_id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "when": "now",
  "can_send": true,
  "blocked_by": [],
  "recipients": 412,
  "audience_total": 938,
  "excluded": {
    "opted_out": 12,
    "not_confirmed": 30,
    "suppressed": 2,
    "no_phone": 3,
    "outside_audience": 524
  },
  "estimated_days": 1,
  "daily_limit": 1000,
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week."
}
```

Prüfe die Zahl der Empfänger, die ausgeschlossenen Kontakte und den Beispieltext. Nur Kontakte mit bestätigtem Opt-in sind dabei. `daily_limit` ist das Tageslimit deiner WhatsApp-Nummer (wie vielen neuen Personen WhatsApp pro Tag schreiben lässt, oder `null`, wenn es keines gibt) und `estimated_days` ist die Zahl der Tage, die der Versand deshalb dauert. Hier passen die 412 Empfänger in einen Tag.

## 4. Einen Test senden

Ein Test geht an die Telefonnummer, die du nennst. Er nutzt nur genehmigte Vorlagen und geht nie an einen Kontakt, der sich abgemeldet hat. Er braucht einen `Idempotency-Key`.

**curl**

```bash
curl -X POST "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/test-send" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+4915112345678"
}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/test-send",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "to": "+4915112345678",
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/test-send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "to": "+4915112345678"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (202):


```json
{
  "object": "newsletter_test_send",
  "newsletter_id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "to": "+4915112345678",
  "status": "handed_to_whatsapp"
}
```

## 5. Senden

Das Senden ist **ein Schritt**. Es braucht das Recht `newsletters:send` und einen `Idempotency-Key`. Fällt das Netz aus, wiederhole den Aufruf mit **demselben** Key: Der Newsletter wird nicht doppelt gesendet.

**curl**

```bash
curl -X POST "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "when": "now"
}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "when": "now",
    },
)
response.raise_for_status()
print(response.json())
```

**TypeScript**

```typescript
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "when": "now"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

Response (202):


```json
{
  "object": "newsletter_send",
  "id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "newsletter_id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "status": "sending",
  "recipients": 412,
  "scheduled_at": null
}
```

Die Antwort ist 202: Der Newsletter steht in der Warteschlange. Prüfe den Fortschritt mit [`get_newsletter`](https://docs.smartchat.marketing/en/api/reference/newsletters/get_newsletter/). Die [Ereignisseite](https://docs.smartchat.marketing/de/webhooks/events/) zeigt, welche Ereignisse es für Newsletter gibt und ob sie schon verfügbar sind.

## Wenn etwas schiefgeht

| Code | Bedeutung |
|---|---|
| [`template_not_approved`](https://docs.smartchat.marketing/de/errors/#template_not_approved) | Die Vorlage ist noch nicht genehmigt. Geh zurück zu Schritt 2 und warte auf die Genehmigung. |
| [`audience_empty`](https://docs.smartchat.marketing/de/errors/#audience_empty) | Die Zielgruppe hat keine erreichbaren Kontakte. |
| [`newsletter_locked`](https://docs.smartchat.marketing/de/errors/#newsletter_locked) | Der Newsletter ist schon geplant oder gesendet. |
| [`idempotency_key_required`](https://docs.smartchat.marketing/de/errors/#idempotency_key_required) | Du hast den Header `Idempotency-Key` nicht gesendet. |
| [`plan_expired`](https://docs.smartchat.marketing/de/errors/#plan_expired) | Die `plan_id` aus Schritt 2 ist älter als 10 Minuten. Rufe die Vorschau noch einmal auf. |

Um einen laufenden Newsletter anzuhalten oder abzubrechen, nutze [`control_newsletter`](https://docs.smartchat.marketing/en/api/reference/newsletters/control_newsletter/).
