
# Broadcasts API

Een **broadcast** is één uitgaande verzending: een doelgroep, een openingsbericht, één kanaal en een planning. Optioneel benoemt het ook de AI-agent die de ontvangen antwoorden afhandelt. Met de Broadcasts API kun je die verzendingen vanuit je eigen code opbouwen, prijzen, lanceren en monitoren in plaats van via het dashboard. Zie voor het product zelf de [Broadcasts-handleiding](../broadcasts/broadcasts.md).

- **Basis-URL** — `https://api.youraiconnector.com/v1`
- **Authenticatie** — uw API-sleutel (zie [Authenticatie](authentication.md))
- **Fouten & paginering** — zie [Fouten & Paginering](errors-and-pagination.md)

Alle onderstaande voorbeelden tonen de `?apiKey=` query-vorm in cURL en de `X-API-Key` header in JavaScript en Python — beide werken op elk eindpunt.

> **In de API-explorer.** Elk eindpunt op deze pagina staat in de gepubliceerde OpenAPI-specificatie, dus je kunt de exacte velden bekijken en live verzoeken uitvoeren in de [API-explorer](reference.md).


---

## Hoe een verzending is opgebouwd

Het versturen van een broadcast bestaat uit vier aanroepen, niet één:

1. **Maak** de broadcast aan met de doelgroep, het kanaal en de planning — deze begint als een `Draft`.
2. **Stel het openingsbericht in.** Bij WhatsApp Business betekent dit het indienen van een sjabloon ter goedkeuring (of het kiezen van een sjabloon dat al is goedgekeurd). Op elk ander kanaal is het platte tekst.
3. **Schat de kosten** als je de prijs wilt controleren voordat je iets uitgeeft (optioneel).
4. **Lanceer het.** Bij het lanceren wordt een volledige controle uitgevoerd — doelgroep, bericht, sjabloongoedkeuring, verbonden afzender — en wordt de verzending gestart of krijg je precies te horen wat er ontbreekt.

Er wordt niets verzonden totdat je de lancering aanroept.

---

## Het broadcast-object

```json
{
  "id": "bcd123abc456",
  "name": "June promo",
  "status": "Draft",
  "channel": "whatsapp",
  "agent_id": "agt_789",
  "list_id": "lst_456",
  "list_name": "Newsletter subscribers",
  "total_contacts": 240,
  "send_to_new_list_members": false,
  "whats_app_template": {
    "body": "Hi {{first_name}}, our June offer is live.",
    "status": "approved",
    "sid": "HX0123...",
    "language": "en",
    "category": "marketing",
    "variables": ["first_name"]
  },
  "execution_date": 1781000000000,
  "drip_mode": true,
  "time_critical": false,
  "total_contacts_sent": 0,
  "credits_used": 0,
  "created_at": 1780900000000,
  "last_modified_at": 1780900000000
}
```

**Tijdstempels worden geretourneerd als epoch-milliseconden** (`execution_date`, `created_at`, `last_modified_at`, …), en elke contactverwijzing wordt geretourneerd als een pad-string zoals `contacts/uid_whatsapp_15551234567`.

### Velden die je zelf instelt

| Veld | Beschrijving |
|---|---|
| `name` | Hoe de broadcast wordt genoemd in het dashboard. |
| `channel` | Het enige kanaal waarop deze broadcast verzendt: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `facebook`, `telegram`, `instagram_private`, `line`, `viber`, `imessage`, `email`, `chat_widget`, `custom_channel`. Een broadcast heeft precies één kanaal — om hetzelfde ergens anders te verzenden, [dupliceer je het naar een ander kanaal](#duplicate-a-broadcast). `tiktok` en `skool` zijn alleen voor antwoorden en kunnen nooit worden gebruikt voor broadcasts. |
| `agent_id` | De AI-agent die antwoorden beantwoordt. Laat dit `null` en antwoorden komen in plaats daarvan in je team-inbox terecht. |
| `list_id` | De contactenlijst waarnaar verzonden moet worden. Dit is hoe je de doelgroep instelt vanuit de API — zie [Contacten](contacts.md) voor het maken en vullen van lijsten. |
| `list_name` | Weergavenaam die naast de broadcast wordt getoond. Cosmetisch. |
| `send_to_new_list_members` | `true` houdt de broadcast actief zodat iedereen die later aan de lijst wordt toegevoegd ook de opener ontvangt. |
| `whats_app_template` | Het openingsbericht. Op WhatsApp Business is dit een echt goedgekeurd sjabloon; op elk ander kanaal wordt de `body` gebruikt als de platte openingstekst. Stel dit in via de [sjabloon-eindpunten](#the-opening-message), niet handmatig. |
| `opener_media` | Eén afbeelding of video die met de opener wordt meegestuurd. Verstuur altijd het volledige object (of `null` om het te verwijderen) — het schrijven van individuele velden daarbinnen wordt geweigerd. Niet ondersteund op SMS. |
| `execution_date` | Wanneer te verzenden. Stuur een ISO 8601-tijdstempel of epoch-milliseconden. Een toekomstige datum plant de verzending; laat dit weg (of gebruik een datum in het verleden) om direct bij lancering te verzenden. |
| `drip_mode` | `true` doseert de verzending in batches over de tijd in plaats van alles tegelijk. |
| `time_critical` | `true` kiest zich af voor de automatische dosering die boven de 50 contacten in werking treedt — voor een warm publiek dat het bericht nu nodig heeft. Dit heft de dagelijkse verzendlimiet van het kanaal zelf niet op. |
| `batch_size` | Hoeveel contacten per batch bij het druppelsgewijs verzenden. |
| `follow_up_config` | De vervolgketen voor contacten die nooit antwoorden. |

Alles wat je verstuurt als `user_id`, `id`, `status` of `source_campaign_id` wordt genegeerd bij het aanmaken en verwijderd bij het bijwerken — de status verandert alleen via de onderstaande eindpunten voor lanceren, pauzeren en hervatten.

### Velden die het platform beheert

`status`, `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate`, `credits_used`, `paused_reason`, `completion_summary`, de batchtellers en `contacts` (de individuele contacten die vanuit het dashboard zijn toegevoegd, teruggelezen als pad-strings). Lees deze, schrijf ze niet.

### Statussen

| Status | Betekenis |
|---|---|
| `Draft` | Wordt gebouwd. Er is niets gepland. |
| `Pending Approval` | Gelanceerd, maar het WhatsApp-sjabloon wacht nog op een beslissing. Het begint automatisch met verzenden zodra het sjabloon is goedgekeurd — u hoeft niet opnieuw te lanceren. |
| `Scheduled` | Gelanceerd met een toekomstige `execution_date`. |
| `Sending` | Actief aan het verzenden (een broadcast die klaarstaat voor nieuwe lijstleden blijft hier staan terwijl deze op hen wacht). |
| `Paused` | In de wacht — door u, of automatisch door een veiligheidscontrole. |
| `Sent` | Voltooid. |
| `Failed` | Voltooid, waarbij meer dan de helft van de verzendingen is mislukt. |

---

## Een broadcast aanmaken

`POST /broadcasts` — maakt een `Draft` aan.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "June promo",
    "channel": "whatsapp",
    "list_id": "lst_456",
    "agent_id": "agt_789",
    "drip_mode": true,
    "execution_date": "2026-06-15T09:00:00.000Z"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/broadcasts", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "June promo",
    channel: "whatsapp",
    list_id: "lst_456",
    agent_id: "agt_789",
    drip_mode: true,
    execution_date: "2026-06-15T09:00:00.000Z",
  }),
});
const { broadcast_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/broadcasts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "June promo",
        "channel": "whatsapp",
        "list_id": "lst_456",
        "agent_id": "agt_789",
        "drip_mode": True,
        "execution_date": "2026-06-15T09:00:00.000Z",
    },
)
print(res.json()["broadcast_id"])
```

**Antwoord** (`201`)

```json
{ "success": true, "broadcast_id": "bcd123abc456" }
```

---

## Broadcasts weergeven

`GET /broadcasts` — elke broadcast in het account, nieuwste eerst.

**Queryparameters**

| Parameter | Vereist | Beschrijving |
|---|---|---|
| `status` | Nee | Retourneer alleen broadcasts met één status, bijv. `Sending`. Kom exact overeen met de spelling in de [statustabel](#statuses). |

```bash
curl "https://api.youraiconnector.com/v1/broadcasts?apiKey=YOUR_API_KEY&status=Sending"
```

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/broadcasts?status=Sending", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { broadcasts } = await res.json();
```

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/broadcasts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"status": "Sending"},
)
broadcasts = res.json()["broadcasts"]
```

**Antwoord** (`200`)

```json
{ "success": true, "broadcasts": [{ "id": "bcd123abc456", "name": "June promo", "status": "Sending", "...": "..." }] }
```

---

## Een broadcast ophalen

`GET /broadcasts/{broadcastId}` — retourneert `{ "success": true, "broadcast": { ... } }`. Gebruik dit om een lopende verzending te pollen: `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate` en `credits_used` worden bijgewerkt naarmate het proces vordert.

```bash
curl "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456?apiKey=YOUR_API_KEY"
```

Een broadcast die niet bestaat in uw account retourneert `404`.

---

## Een broadcast bijwerken

`PUT /broadcasts/{broadcastId}` — stuur alleen de velden die u wilt wijzigen. U kunt ook een enkele sleutel binnen een genest object adresseren met een puntnotatie, bijv. `"whats_app_template.body"`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "June promo (v2)", "execution_date": "2026-06-16T09:00:00.000Z" }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/broadcasts/bcd123abc456", {
  method: "PUT",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ name: "June promo (v2)", execution_date: "2026-06-16T09:00:00.000Z" }),
});
```

Een lege body retourneert `400`. Twee regels die het weten waard zijn:

- **`opener_media` is alles-of-niets.** Stuur het volledige object, of `null` om de bijlage te verwijderen. Een puntnotatie hierin (`opener_media.name`) wordt geweigerd met `400`, omdat een gedeeltelijk bijgewerkte bijlage een bestand zou beschrijven dat er niet is.
- **Status is niet bewerkbaar.** Gebruik [lanceren](#launch-a-broadcast), [pauzeren](#pause-and-resume) en [hervatten](#pause-and-resume).

---

## Het openingsbericht

Elke uitzending bevat zijn opener in `whats_app_template`. Wat dat betekent, hangt af van het kanaal:

- **WhatsApp Business** — dit moet een sjabloon zijn dat door WhatsApp is goedgekeurd. Gebruik een van de twee onderstaande eindpunten.
- **Elk ander kanaal** (WhatsApp Web, SMS, Instagram, Messenger, Telegram, …) — de `body` van hetzelfde veld is simpelweg de tekst die wordt verzonden. Het indienen via het onderstaande eindpunt slaat het op en markeert het als gereed, zonder dat WhatsApp hierbij betrokken is.

### Een sjabloon ter goedkeuring indienen

`POST /broadcasts/{broadcastId}/template`

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `body` | Ja | De berichttekst, tot 1024 tekens. Gebruik `{{variable}}` tijdelijke aanduidingen voor personalisatie. |
| `name` | Nee | Sjabloonnaam. Standaard is dit de naam van de uitzending. |
| `language` | Nee | Taalcode. Standaard is dit `en`. |
| `category` | Nee | `marketing` (standaard), `utility`, `authentication` of `authentication-international`. Dit bepaalt de prijs van de verzending, dus wees hier eerlijk in. |
| `variables` | Nee | De namen van de tijdelijke aanduidingen, in de volgorde waarin ze verschijnen. Laat dit weg en ze worden uit de hoofdtekst gelezen — wat meestal is wat je wilt, omdat de verzending ze per contactpersoon invult. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/template?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi {{first_name}}, our June offer is live until Friday.",
    "language": "en",
    "category": "marketing"
  }'
```

**Antwoord** (`200`)

```json
{ "success": true, "broadcast_id": "bcd123abc456", "template_status": "pending", "template_sid": "HX0123..." }
```

`template_status` is wat WhatsApp zegt: `pending` terwijl het wordt beoordeeld, `approved` wanneer het bruikbaar is, `rejected` als het is geweigerd. Op een niet-WhatsApp-kanaal komt het direct terug als `approved` met `template_sid: null` — er is niets om te beoordelen.

Zaken die je zullen tegenhouden:

- Indienen terwijl een vorig sjabloon nog in behandeling is, geeft `400` terug. Wacht eerst op de beslissing.
- Het bewerken van een sjabloon dat momenteel is goedgekeurd, houdt het goedgekeurde sjabloon actief totdat het nieuwe terugkomt, zodat een lopende uitzending nooit zijn opener verliest.
- Op een WhatsApp-nummer dat rechtstreeks via Meta is verbonden, kan een uitzending met een bijgevoegde afbeelding of video niet worden ingediend (`400`) — bijlagen worden ondersteund op het beheerde WhatsApp Business-kanaal en op WhatsApp Web.

### Een sjabloon gebruiken dat je al hebt laten goedkeuren

`POST /broadcasts/{broadcastId}/template/select` — kopieert een reeds goedgekeurd sjabloon uit je [sjabloonbibliotheek](templates.md) naar de uitzending, dus er is niets om op te wachten.

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `template_id` | Ja | De id van een goedgekeurd sjabloon in je account. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/template/select?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template_id": "tpl_abc123" }'
```

**Antwoord** (`200`)

```json
{
  "success": true,
  "broadcast_id": "bcd123abc456",
  "template_status": "approved",
  "template_sid": "HX0123...",
  "body": "Hi {{first_name}}, our June offer is live until Friday.",
  "name": "june_promo",
  "language": "en",
  "variables": ["first_name"],
  "category": "marketing"
}
```

De goedkeuring wordt aan onze kant geverifieerd op basis van het bibliotheekrecord — je verstuurt alleen de id. Je krijgt een `400` als de uitzending geen WhatsApp-concept is, als het sjabloon niet is goedgekeurd, als het een vervolgsjabloon is in plaats van een opener, of als de uitzending een bijlage heeft (bibliotheeksjablonen zijn alleen tekst). Een sjabloon-id die niet in je account staat, geeft `404` terug.

---

## De kosten schatten

`POST /broadcasts/{broadcastId}/estimate-cost` — berekent de prijs van de verzending voordat je deze bevestigt. Beschikbaar voor `whatsapp` en `sms` uitzendingen; elk ander kanaal geeft `400` terug. De uitzending heeft een `list_id` nodig, aangezien de schatting het aantal ontvangers telt.

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/estimate-cost?apiKey=YOUR_API_KEY"
```

**WhatsApp-reactie** (`200`) — tegoeden, uitgesplitst per land van bestemming:

```json
{
  "success": true,
  "channel": "whatsapp",
  "billing_mode": "credits",
  "data": {
    "countries": [
      { "countryCode": "31", "name": "Netherlands", "iso": "NL", "flag": "🇳🇱", "contactCount": 180, "costPerContact": 1.2, "subtotal": 216 },
      { "countryCode": "1", "name": "United States", "iso": "US", "flag": "🇺🇸", "contactCount": 60, "costPerContact": 0.9, "subtotal": 54 }
    ],
    "totalContacts": 240,
    "totalTemplateCost": 270,
    "templateCategory": "marketing",
    "billing_mode": "credits",
    "service_messages_billable_soon": false
  }
}
```

**SMS-antwoord** (`200`) — Amerikaanse dollars, gebaseerd op actuele Twilio-prijzen voor uw eigen Twilio-account:

```json
{
  "success": true,
  "channel": "sms",
  "billing_mode": "twilio_direct",
  "data": {
    "totalContacts": 240,
    "messageLength": 118,
    "segmentsPerMessage": 1,
    "totalSegments": 240,
    "estimatedCostUsd": 1.788,
    "priceUnit": "USD",
    "billedByTwilio": true,
    "billing_mode": "twilio_direct",
    "service_messages_billable_soon": false
  }
}
```

**Lees `billing_mode` voordat u een nummer toont.** Hierin staat wie er wordt gefactureerd:

| `billing_mode` | Wie betaalt | Wat de cijfers betekenen |
|---|---|---|
| `credits` | Uw <span data-t="appName">Your AI Connector</span>-account | `totalTemplateCost` en de cijfers per land zijn credits. |
| `twilio_direct` | Uw eigen Twilio-account | `estimatedCostUsd` is wat Twilio u in rekening brengt. |
| `meta_waba_direct` | Uw eigen WhatsApp Business-account, gefactureerd door Meta | Elk creditcijfer wordt `null` weergegeven — bewust, zodat het nooit wordt aangezien voor "gratis". De aantallen per land en contactpersoon zijn nog steeds accuraat. |

Bij sms-berichten zonder gekoppelde Twilio-inloggegevens worden nog steeds de segmentaantallen geretourneerd, met `estimatedCostUsd: 0` — er is geen prijs om op te zoeken.

---

## Een broadcast starten

`POST /broadcasts/{broadcastId}/launch`

Bij het starten wordt eerst alles gecontroleerd en pas daarna wordt de broadcast voortgezet. Er is geen gedeeltelijke start: of het start, of er verandert niets en u krijgt een foutmelding met de reden.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/launch?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/launch", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
if (!data.success) console.error(data.error);
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/launch",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json())
```

**Antwoord** (`200`)

```json
{ "success": true, "broadcast_id": "bcd123abc456", "status": "Scheduled" }
```

`status` is waar de broadcast is terechtgekomen:

- `Scheduled` — `execution_date` ligt in de toekomst.
- `Sending` — het is nu gestart.
- `Pending Approval` — de WhatsApp-template is nog in afwachting van goedkeuring. Het wordt automatisch verzonden zodra de template is goedgekeurd; roep de startfunctie niet opnieuw aan.

Alleen een `Draft` (of een `Pending Approval`-broadcast waarvan de template in de tussentijd is goedgekeurd) kan worden gestart — al het andere retourneert `400`.

### Waarom een start wordt geweigerd

Elk van deze wordt geretourneerd als `400` met een `error`-bericht in begrijpelijke taal:

| Probleem | Wat te herstellen |
|---|---|
| Geen doelgroep | Stel `list_id` in (of voeg contacten toe) voordat u start. |
| Geen openingsbericht | Stel de opener in — zie [Het openingsbericht](#the-opening-message). |
| Bijlage bij sms | Sms kan geen afbeelding of video bevatten. Verwijder de bijlage of verplaats de broadcast naar WhatsApp. |
| Bijlage komt niet overeen met de goedgekeurde template | Op WhatsApp bevindt de media zich in de goedgekeurde template, dus het achteraf verwisselen van de bijlage betekent dat de template opnieuw moet worden ingediend. |
| Template afgewezen | Herschrijf het bericht en dien het opnieuw in. |
| Template nooit ingediend | Dien deze eerst in (of selecteer een goedgekeurde). |
| Template goedgekeurd maar ontbreekt in uw WhatsApp-account | Meestal een template die is goedgekeurd voordat de koppeling van het nummer was voltooid. Dien deze opnieuw in. |
| Geen gekoppelde afzender voor het kanaal | Koppel eerst het kanaal — zie [Kanalen](channels.md). |
| Alleen-antwoorden-kanaal | TikTok en Skool staan niet toe dat een bedrijf een gesprek start, dus ze kunnen niet worden gebruikt voor broadcasts. |
| Al reeds ingepland | De broadcast heeft al een verzending gepland staan. Pauzeer deze voordat u opnieuw start. |
| Nog in afwachting van goedkeuring | Het wordt vanzelf verzonden wanneer de template is goedgekeurd. |
| WhatsApp Business-account geblokkeerd door Meta | Meta heeft door bedrijven geïnitieerde gesprekken op uw eigen WhatsApp Business-account stopgezet — meestal een probleem met de betaalmethode. Los dit op in Meta's Business Manager. |
| Gestart vanuit een klassieke campagne | Start deze in plaats daarvan vanuit de campagne-editor. Zie [klassieke campagnes in Broadcasts](#broadcasts-that-mirror-a-classic-campaign). |

---

## Pauzeren en hervatten

`POST /broadcasts/{broadcastId}/pause` stopt een `Sending`- of `Scheduled`-broadcast en verwijdert alles wat in de wachtrij staat.

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/pause?apiKey=YOUR_API_KEY"
```

Het pauzeren van een `Pending Approval`-uitzending zet deze terug naar `Draft` — er was nog niets gepland, dus er is niets om naar te hervatten. Elke andere status keert terug naar `400`.

`POST /broadcasts/{broadcastId}/resume` herstart een `Paused`-uitzending:

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/resume?apiKey=YOUR_API_KEY"
```

**Antwoord** (`200`)

```json
{ "success": true, "broadcast_id": "bcd123abc456" }
```

Het hervat naar `Sending`, of terug naar `Scheduled` als de `execution_date` nog in de toekomst ligt. Alleen een `Paused`-uitzending kan worden hervat.

---

## Blijven verzenden na een pauze vanwege lage betrokkenheid

`POST /broadcasts/{broadcastId}/override-engagement-guard`

Terwijl een uitzending in batches wordt verzonden, meten we hoeveel mensen op elke batch hebben gereageerd voordat de volgende wordt gestart. Als bijna niemand reageert, pauzeert de uitzending zichzelf — een verzending die blijft pushen in stilte is de snelste manier om een nummer gefilterd of geblokkeerd te krijgen. Dit is de knop **Toch doorgaan** in het dashboard.

Omdat het antwoordpercentage dat de pauze veroorzaakte niet kan veranderen terwijl de uitzending is gestopt, zou een gewone [hervatting](#pause-and-resume) bij de volgende controle gewoon weer worden gepauzeerd. Dit eindpunt is de beslissing om toch door te gaan: het registreert de overschrijving op die ene uitzending en heft de pauze op in dezelfde aanroep als de uitzending was gepauzeerd vanwege lage betrokkenheid.

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/override-engagement-guard?apiKey=YOUR_API_KEY"
```

**Antwoord** (`200`)

```json
{ "success": true, "broadcast_id": "bcd123abc456", "status": "Sending", "resumed": true }
```

- `resumed: true` — de uitzending was gepauzeerd vanwege lage betrokkenheid en draait nu weer; `status` is waar deze naar is hervat.
- `resumed: false` — er is niets opgeheven, de overschrijving wordt simpelweg geregistreerd voor toekomstige controles. Dat is wat je krijgt als de uitzending nooit was gepauzeerd, of was gepauzeerd om een andere reden (je hebt het handmatig gepauzeerd, een verzendlimiet is bereikt, of er zijn te veel verzendfouten opgetreden). Die pauzes worden hier niet opgeheven — hervat het zelf zodra je de oorzaak hebt aangepakt.

De overschrijving is alleen van toepassing op deze uitzending. Het is geen accountinstelling en het is veilig om deze twee keer aan te roepen.

---

## Een uitzending dupliceren

`POST /broadcasts/{broadcastId}/duplicate` — kopieert het publiek, het bericht en de instellingen naar een nieuwe `Draft`. Alles van de vorige run (tellers, batches, planning, antwoordstatistieken) begint opnieuw.

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `to_channel` | Nee | Maak de kopie op een ander kanaal. Dit is hoe je hetzelfde verstuurt op twee kanalen — een uitzending heeft er altijd maar één. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456/duplicate?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to_channel": "sms" }'
```

**Antwoord** (`201`)

```json
{ "success": true, "broadcast_id": "bcd999new111", "source_broadcast_id": "bcd123abc456" }
```

Een kopie neemt nooit een live WhatsApp-goedkeuring over: bij een WhatsApp-kopie moet de sjabloon door jou worden bevestigd, en bij een kopie naar een ander kanaal wordt deze verwijderd en wordt de tekst de gewone opener. Kopiëren naar sms verwijdert ook eventuele bijlagen, aangezien sms deze niet kan verzenden.

---

## Een uitzending verwijderen

`DELETE /broadcasts/{broadcastId}`

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/broadcasts/bcd123abc456?apiKey=YOUR_API_KEY"
```

Een `Sending` of `Scheduled` uitzending wordt geweigerd met `400` — pauzeer deze eerst.

---

## Uitzendingen die een klassieke campagne spiegelen

Klassieke campagnes die berichten versturen verschijnen ook in Uitzendingen, en de API retourneert ze naast native uitzendingen (ze bevatten een `source_campaign_id`). Ze gedragen zich iets anders, omdat de campagne de leiding behoudt:

- **Het bewerken** van het publiek, bericht of schema werkt en wordt doorgevoerd naar de campagne.
- **Kanaal, antwoord-Agent, bijlage en alle run-tellers zijn hier alleen-lezen** — `400` als u probeert deze te wijzigen. Wijzig deze in de campagne.
- **Starten** retourneert `400` die u naar de campagne-editor verwijst.
- **Pauzeren en hervatten** werken en zijn van invloed op de campagne.
- **Verwijderen** retourneert `400` — verwijder in plaats daarvan de campagne, dan verdwijnt het bijbehorende item in Uitzendingen ook.
- **Dupliceren** geeft u een onafhankelijke native uitzending, wat de ondersteunde manier is om een bewezen campagne over te zetten.

---

## Fouten

Mislukte verzoeken retourneren `{"success": false, "error": "<message>"}` met deze statussen:

| Status | Betekenis |
|---|---|
| `400` | Er is iets mis met het verzoek of de status van de uitzending — een ontbrekend veld, een ongeldige bijlage, of een actie (starten/pauzeren/hervatten/verwijderen) die niet is toegestaan in de huidige status van de uitzending. Het `error` bericht benoemt de reden. |
| `401` | Ontbrekende of ongeldige API-sleutel. |
| `403` | Uw abonnement bevat geen API-toegang. |
| `404` | Geen dergelijke uitzending op uw account (of, bij sjabloonselectie, geen dergelijk sjabloon). |
| `429` | Snelheidslimiet bereikt. Wacht even en probeer het opnieuw. |
| `500` | Er is iets misgegaan aan onze kant. Probeer het na een korte wachttijd opnieuw. |

---

## Volgende stappen

- [Uitzendingen-gids](../broadcasts/broadcasts.md) — het product achter deze endpoints, inclusief tempo en veiligheidsgedrag
- [Contacten-API](contacts.md) — bouw de lijst waarnaar een uitzending verzendt
- [Sjablonen-API](templates.md) — beheer de goedgekeurde WhatsApp-sjablonen waaruit u kunt kiezen
- [Webhooks-API](webhooks.md) — abonneer u op `Broadcast Started` en `Broadcast Completed` in plaats van te pollen
