
# Broadcasts API

**Broadcast** (lähetys) on yksi lähtevä viesti: kohderyhmä, aloitusviesti, yksi kanava ja aikataulu. Voit myös valita tekoälyagentin, joka käsittelee siihen tulevat vastaukset. Broadcasts API:n avulla voit luoda, hinnoitella, käynnistää ja seurata näitä lähetyksiä omasta koodistasi käsin kojelaudan sijaan. Itse tuotteesta voit lukea [Broadcasts-oppaasta](../broadcasts/broadcasts.md).

- **Perus-URL** — `https://api.youraiconnector.com/v1`
- **Todennus** — API-avaimesi (katso [Todennus](authentication.md))
- **Virheet ja sivutus** — katso [Virheet ja sivutus](errors-and-pagination.md)

Kaikki alla olevat esimerkit näyttävät `?apiKey=`-kyselymuodon cURL-muodossa ja `X-API-Key`-otsikon JavaScriptissä ja Pythonissa – kumpi tahansa toimii jokaisessa päätepisteessä.

> **API-selaimessa.** Jokainen tämän sivun päätepiste on julkaistussa OpenAPI-määrityksessä, joten voit selata sen tarkkoja kenttiä ja suorittaa live-pyyntöjä [API-selaimessa](reference.md).


---

## Lähetyksen koostaminen

Lähetyksen tekeminen vaatii neljä kutsua, ei yhtä:

1. **Luo** lähetys kohderyhmineen, kanavineen ja aikatauluineen – se alkaa tilassa `Draft`.
2. **Aseta aloitusviesti.** WhatsApp Businessissa tämä tarkoittaa mallin lähettämistä hyväksyttäväksi (tai aiemmin hyväksytyn mallin valitsemista). Kaikissa muissa kanavissa se on tavallista tekstiä.
3. **Arvioi kustannukset**, jos haluat tarkistaa hinnan ennen kuin käytät mitään (valinnainen).
4. **Käynnistä se.** Käynnistys suorittaa täyden tarkistuksen – kohderyhmä, viesti, mallin hyväksyntä, yhdistetty lähettäjä – ja joko aloittaa lähetyksen tai kertoo tarkalleen, mikä puuttuu.

Mitään ei lähetetä ennen kuin kutsut käynnistystä.

---

## Lähetys-objekti

```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
}
```

**Aikaleimat palautetaan epoch-millisekunteina** (`execution_date`, `created_at`, `last_modified_at`, …), ja kaikki yhteystietoviittaukset palautetaan polkumerkkijonoina, kuten `contacts/uid_whatsapp_15551234567`.

### Asettamasi kentät

| Kenttä | Kuvaus |
|---|---|
| `name` | Mikä lähetyksen nimi on kojelaudassa. |
| `channel` | Se yksi kanava, jota pitkin lähetys lähetetään: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `facebook`, `telegram`, `instagram_private`, `line`, `viber`, `imessage`, `email`, `chat_widget`, `custom_channel`. Lähetyksellä on tasan yksi kanava – jos haluat lähettää saman asian muualle, [kopioi se toiselle kanavalle](#duplicate-a-broadcast). `tiktok` ja `skool` ovat vain vastauskanavia, eikä niitä voi käyttää lähetyksiin. |
| `agent_id` | Tekoälyagentti, joka vastaa vastauksiin. Jätä se arvoon `null`, niin vastaukset päätyvät tiimisi postilaatikkoon. |
| `list_id` | Yhteystietoluettelo, johon lähetys kohdistetaan. Näin määrität kohderyhmän API:n kautta – katso [Yhteystiedot](contacts.md) luetteloiden luomista ja täyttämistä varten. |
| `list_name` | Lähetyksen vieressä näkyvä näyttönimi. Kosmeettinen. |
| `send_to_new_list_members` | `true` pitää lähetyksen aktiivisena, jotta kaikki myöhemmin luetteloon lisätyt saavat myös aloitusviestin. |
| `whats_app_template` | Aloitusviesti. WhatsApp Businessissa se on oikea hyväksytty malli; kaikissa muissa kanavissa sen `body` käytetään tavallisena aloitusviestinä. Aseta se [mallien päätepisteiden](#the-opening-message) kautta, älä käsin. |
| `opener_media` | Yksi kuva tai video, joka lähetetään aloitusviestin mukana. Lähetä aina koko objekti (tai `null` poistaaksesi sen) – yksittäisten avainten kirjoittaminen sen sisään hylätään. Ei tuettu SMS-viesteissä. |
| `execution_date` | Milloin lähetetään. Lähetä ISO 8601 -aikaleima tai epoch-millisekunnit. Tuleva päivämäärä ajastaa lähetyksen; jätä pois (tai käytä mennyttä päivämäärää) lähettääksesi heti, kun käynnistät. |
| `drip_mode` | `true` jaksottaa lähetyksen eriin ajan myötä sen sijaan, että kaikki lähetettäisiin kerralla. |
| `time_critical` | `true` kieltäytyy automaattisesta jaksotuksesta, joka käynnistyy yli 50 yhteystiedon kohdalla – lämpimälle yleisölle, joka tarvitsee viestin heti. Se ei poista kanavan omaa päivittäistä lähetysrajaa. |
| `batch_size` | Kuinka monta yhteystietoa per erä, kun käytetään jaksotusta. |
| `follow_up_config` | Seurantaketju yhteystiedoille, jotka eivät koskaan vastaa. |

Kaikki, mitä lähetät arvoina `user_id`, `id`, `status` tai `source_campaign_id`, jätetään huomiotta luotaessa ja poistetaan päivitettäessä – tila muuttuu vain alla olevien käynnistys-, tauko- ja jatkamispäätepisteiden kautta.

### Alustan ylläpitämät kentät

`status`, `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate`, `credits_used`, `paused_reason`, `completion_summary`, erälaskurit ja `contacts` (kojelaudasta liitetyt yksittäiset yhteystiedot, luetaan takaisin polkumerkkijonoina). Lue näitä, älä kirjoita niihin.

### Tilat

| Tila | Merkitys |
|---|---|
| `Draft` | Rakenteilla. Mitään ei ole ajastettu. |
| `Pending Approval` | Käynnistetty, mutta sen WhatsApp-malli odottaa vielä päätöstä. Se alkaa lähettää automaattisesti, kun malli on hyväksytty – sinun ei tarvitse käynnistää sitä uudelleen. |
| `Scheduled` | Käynnistetty tulevalla `execution_date`-ajankohdalla. |
| `Sending` | Lähettää aktiivisesti (uusille listan jäsenille varattu lähetys pysyy tässä tilassa odottaessaan heitä). |
| `Paused` | Pysäytetty – joko sinun toimestasi tai automaattisesti turvatarkistuksen vuoksi. |
| `Sent` | Valmis. |
| `Failed` | Valmis, mutta yli puolet lähetyksistä epäonnistui. |

---

## Luo lähetys

`POST /broadcasts` – luo `Draft`-kohteen. |

**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"])
```

**Vastaus** (`201`)

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

---

## Listaa lähetykset

`GET /broadcasts` – jokainen tilin lähetys, uusimmasta alkaen. |

**Kyselyparametrit**

| Parametri | Pakollinen | Kuvaus |
|---|---|---|
| `status` | Ei | Palauta vain tietyn tilan lähetykset, esim. `Sending`. Kirjoita tila täsmälleen samalla tavalla kuin [tilataulukossa](#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"]
```

**Vastaus** (`200`)

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

---

## Hae lähetys

`GET /broadcasts/{broadcastId}` – palauttaa `{ "success": true, "broadcast": { ... } }`-kohteen. Käytä tätä käynnissä olevan lähetyksen seuraamiseen: `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate` ja `credits_used` päivittyvät lähetyksen edetessä. |

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

Lähetys, jota ei ole tililläsi, palauttaa `404`-virheen. |

---

## Päivitä lähetys

`PUT /broadcasts/{broadcastId}` – lähetä vain ne kentät, jotka haluat muuttaa. Voit myös viitata sisäkkäisen objektin yksittäiseen avaimeen pistepolulla, esim. `"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" }),
});
```

Tyhjä runko palauttaa `400`-virheen. Kaksi huomioitavaa sääntöä:

- **`opener_media` on kaikki tai ei mitään.** Lähetä koko objekti tai `null` poistaaksesi liitteen. Pistepolku sen sisään (`opener_media.name`) hylätään `400`-virheellä, koska osittain päivitetty liite kuvaisi tiedostoa, jota ei ole olemassa.
- **Tilaa ei voi muokata.** Käytä [käynnistystä](#launch-a-broadcast), [tauotusta](#pause-and-resume) ja [jatkamista](#pause-and-resume).

---

## Aloitusviesti

Jokainen lähetys sisältää aloitusviestinsä kohdassa `whats_app_template`. Sen merkitys riippuu kanavasta:

- **WhatsApp Business** — sen on oltava WhatsAppin hyväksymä mallipohja. Käytä jotakin alla olevista kahdesta päätepisteestä.
- **Kaikki muut kanavat** (WhatsApp Web, SMS, Instagram, Messenger, Telegram, …) — saman kentän `body` on yksinkertaisesti lähetettävä teksti. Sen lähettäminen alla olevan päätepisteen kautta tallentaa sen ja merkitsee sen valmiiksi ilman, että WhatsApp on osallisena.

### Lähetä mallipohja hyväksyttäväksi

`POST /broadcasts/{broadcastId}/template`

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `body` | Kyllä | Viestin teksti, enintään 1024 merkkiä. Käytä `{{variable}}`-paikkamerkkejä personointiin. |
| `name` | Ei | Mallipohjan nimi. Oletusarvona on lähetyksen nimi. |
| `language` | Ei | Kielikoodi. Oletusarvona on `en`. |
| `category` | Ei | `marketing` (oletus), `utility`, `authentication` tai `authentication-international`. Tämän perusteella määräytyy lähetyksen hinta, joten käytä oikeaa luokitusta. |
| `variables` | Ei | Paikkamerkkien nimet siinä järjestyksessä kuin ne esiintyvät. Jätä pois, niin ne luetaan tekstirungosta – mikä on yleensä suositeltavaa, koska lähetys täyttää ne jokaisen yhteystiedon kohdalla. |

```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"
  }'
```

**Vastaus** (`200`)

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

`template_status` on se, mitä WhatsApp ilmoittaa: `pending` tarkistuksen aikana, `approved` kun se on käyttökelpoinen, `rejected` jos se hylättiin. Muilla kuin WhatsApp-kanavilla vastaus tulee suoraan muodossa `approved` ja `template_sid: null` – tarkistettavaa ei ole.

Asiat, jotka estävät toiminnon:

- Lähettäminen samalla kun edellinen mallipohja on vielä tarkistettavana palauttaa virheen `400`. Odota ensin päätöstä.
- Parhaillaan hyväksytyn mallipohjan muokkaaminen pitää hyväksytyn version aktiivisena, kunnes uusi on hyväksytty, joten käynnissä oleva lähetys ei koskaan menetä aloitusviestiään.
- WhatsApp-numerossa, joka on yhdistetty suoraan Metan kautta, lähetystä, johon on liitetty kuva tai video, ei voi lähettää (`400`) – liitteitä tuetaan hallinnoidussa WhatsApp Business -kanavassa ja WhatsApp Webissä.

### Käytä jo hyväksyttyä mallipohjaa

`POST /broadcasts/{broadcastId}/template/select` — kopioi jo hyväksytyn mallipohjan [mallipohjakirjastostasi](templates.md) lähetykseen, joten odotettavaa ei ole.

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `template_id` | Kyllä | Tililläsi olevan hyväksytyn mallipohjan tunniste (id). |

```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" }'
```

**Vastaus** (`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"
}
```

Hyväksyntä varmistetaan meidän puoleltamme kirjastotietueesta – lähetät aina vain tunnisteen. Saat virheen `400`, jos lähetys ei ole WhatsApp-luonnos, jos mallipohjaa ei ole hyväksytty, jos kyseessä on jatkoviestimallipohja eikä aloitusviesti, tai jos lähetyksessä on liite (kirjastomallipohjat ovat vain tekstiä). Mallipohjan tunniste, jota ei löydy tililtäsi, palauttaa virheen `404`.

---

## Arvioi kustannukset

`POST /broadcasts/{broadcastId}/estimate-cost` — hinnoittelee lähetyksen ennen kuin vahvistat sen. Saatavilla `whatsapp`- ja `sms`-lähetyksissä; kaikki muut kanavat palauttavat virheen `400`. Lähetys tarvitsee `list_id`, koska arvio lasketaan kohderyhmän perusteella.

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

**WhatsApp-vastaus** (`200`) — krediitit jaoteltuna kohdemaittain:

```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-vastaus** (`200`) — Yhdysvaltain dollareina, perustuen Twilio-tilisi reaaliaikaiseen Twilio-hinnoitteluun:

```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
  }
}
```

**Lue `billing_mode` ennen kuin näytät numeron.** Se kertoo, ketä laskutetaan:

| `billing_mode` | Kuka maksaa | Mitä luvut tarkoittavat |
|---|---|---|
| `credits` | <span data-t="appName">Your AI Connector</span>-tilisi | `totalTemplateCost` ja maakohtaiset luvut ovat krediittejä. |
| `twilio_direct` | Oma Twilio-tilisi | `estimatedCostUsd` on summa, jonka Twilio veloittaa sinulta. |
| `meta_waba_direct` | Oma WhatsApp Business -tilisi, laskuttajana Meta | Jokainen krediittiluku palautuu muodossa `null` — tarkoituksella, jotta sitä ei koskaan sekoiteta "ilmaiseen". Maa- ja yhteystietomäärät ovat silti tarkkoja. |

SMS ilman yhdistettyjä Twilio-tunnistetietoja palauttaa silti segmenttimäärät muodossa `estimatedCostUsd: 0` — hinnoittelua ei ole haettavissa.

---

## Käynnistä lähetys

`POST /broadcasts/{broadcastId}/launch`

Käynnistys tarkistaa ensin kaiken ja etenee vasta sitten lähetyksen kanssa. Osittaista käynnistystä ei ole: joko se alkaa tai mikään ei muutu ja saat virheilmoituksen, joka kertoo syyn.

**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())
```

**Vastaus** (`200`)

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

`status` on paikka, johon lähetys päätyi:

- `Scheduled` — `execution_date` on tulevaisuudessa.
- `Sending` — se alkoi nyt.
- `Pending Approval` — WhatsApp-malli on vielä tarkistettavana. Se lähettää itsensä heti, kun malli on hyväksytty; älä kutsu käynnistystä uudelleen.

Vain `Draft` (tai `Pending Approval`-lähetys, jonka malli on sittemmin hyväksytty) voidaan käynnistää — kaikki muu palauttaa `400`.

### Miksi käynnistys evätään

Jokainen näistä palautuu muodossa `400` ja sisältää selkokielisen `error`-viestin:

| Ongelma | Mitä korjata |
|---|---|
| Ei yleisöä | Määritä `list_id` (tai liitä yhteystiedot) ennen käynnistämistä. |
| Ei aloitusviestiä | Määritä aloitusviesti — katso [Aloitusviesti](#the-opening-message). |
| Liite SMS-viestissä | SMS ei voi sisältää kuvaa tai videota. Poista liite tai siirrä lähetys WhatsAppiin. |
| Liite ei vastaa hyväksyttyä mallia | WhatsAppissa media sijaitsee hyväksytyn mallin sisällä, joten liitteen vaihtaminen jälkikäteen tarkoittaa mallin lähettämistä uudelleen. |
| Malli hylätty | Kirjoita viesti uudelleen ja lähetä se uudelleen. |
| Mallia ei ole koskaan lähetetty | Lähetä se (tai valitse hyväksytty malli) ensin. |
| Malli hyväksytty, mutta puuttuu WhatsApp-tililtäsi | Yleensä malli on hyväksytty ennen kuin numero on yhdistetty. Lähetä se uudelleen. |
| Kanavalle ei ole yhdistettyä lähettäjää | Yhdistä kanava ensin — katso [Kanavat](channels.md). |
| Vain vastauskanava | TikTok ja Skool eivät salli yrityksen aloittaa keskustelua, joten niitä ei voi käyttää lähetyksiin. |
| Jo valmiustilassa | Lähetyksellä on jo ajoitettu lähetys. Keskeytä se ennen kuin käynnistät uudelleen. |
| Odottaa yhä hyväksyntää | Se lähettää itsensä, kun malli on hyväksytty. |
| Meta on estänyt WhatsApp Business -tilin | Meta on estänyt yrityksen aloittamat keskustelut omalla WhatsApp Business -tililläsi — yleensä kyseessä on maksutapaongelma. Korjaa se Metan Business Managerissa. |
| Aloitettu klassisesta kampanjasta | Käynnistä se kampanjaeditorista. Katso [klassiset kampanjat lähetyksissä](#broadcasts-that-mirror-a-classic-campaign). |

---

## Keskeytä ja jatka

`POST /broadcasts/{broadcastId}/pause` pysäyttää `Sending`- tai `Scheduled`-lähetyksen ja poistaa kaiken jonossa olevan.

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

`Pending Approval`-lähetyksen keskeyttäminen palauttaa sen takaisin tilaan `Draft` – mitään ei ollut vielä ajoitettu, joten ei ole mitään, mihin jatkaa. Mikä tahansa muu tila palauttaa arvon `400`.

`POST /broadcasts/{broadcastId}/resume` käynnistää `Paused`-lähetyksen uudelleen:

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

**Vastaus** (`200`)

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

Se jatkuu tilaan `Sending` tai takaisin tilaan `Scheduled`, jos sen `execution_date` on yhä tulevaisuudessa. Vain `Paused`-lähetyksen voi jatkaa.

---

## Jatka lähettämistä alhaisen sitoutumisen aiheuttaman keskeytyksen jälkeen

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

Kun lähetys tapahtuu erissä, mittaamme, kuinka moni vastasi kuhunkin erään ennen seuraavan aloittamista. Jos lähes kukaan ei vastaa, lähetys keskeytyy automaattisesti – hiljaisuuteen jatkuva lähetys on nopein tapa saada numero suodatetuksi tai estetyksi. Tämä on hallintapaneelin **Jatka silti** -painike.

Koska keskeytyksen aiheuttanut vastausprosentti ei voi muuttua lähetyksen ollessa pysäytettynä, tavallinen [jatkaminen](#pause-and-resume) johtaisi vain uuteen keskeytykseen seuraavassa tarkistuksessa. Tämä päätepiste on päätös jatkaa silti: se tallentaa ohituksen kyseiselle lähetykselle ja poistaa keskeytyksen samalla kutsulla, jos lähetys oli keskeytetty alhaisen sitoutumisen vuoksi.

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

**Vastaus** (`200`)

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

- `resumed: true` – lähetys oli keskeytetty alhaisen sitoutumisen vuoksi ja on nyt taas käynnissä; `status` on tila, johon se jatkui.
- `resumed: false` – mitään ei poistettu, ohitus tallennetaan vain tulevia tarkistuksia varten. Tämän saat, jos lähetystä ei ollut koskaan keskeytetty tai se oli keskeytetty muusta syystä (keskeytit sen käsin, lähetysraja tuli vastaan tai liian moni lähetys epäonnistui). Näitä keskeytyksiä ei poisteta tässä – jatka lähetystä itse, kun olet käsitellyt syyn.

Ohitus koskee vain tätä lähetystä. Se ei ole tilin asetus, ja sen kutsuminen kahdesti on turvallista.

---

## Kopioi lähetys

`POST /broadcasts/{broadcastId}/duplicate` – kopioi yleisön, viestin ja asetukset uuteen `Draft`-kohteeseen. Kaikki edelliseen ajoon liittyvä (laskurit, erät, aikataulu, vastaustilastot) alkaa alusta.

| Kenttä | Pakollinen | Kuvaus |
|---|---|---|
| `to_channel` | Ei | Luo kopio eri kanavalle. Näin lähetät saman asian kahdella kanavalla – lähetyksellä on aina vain yksi kanava. |

```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" }'
```

**Vastaus** (`201`)

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

Kopio ei koskaan peri aktiivista WhatsApp-hyväksyntää: WhatsApp-kopiossa mallipohja vaatii vahvistuksesi, ja kopioitaessa toiselle kanavalle se poistetaan ja tekstistä tulee tavallinen aloitusviesti. Kopiointi tekstiviestiksi (SMS) poistaa myös mahdolliset liitteet, koska tekstiviestit eivät tue niitä.

---

## Poista lähetys

`DELETE /broadcasts/{broadcastId}`

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

`Sending`- tai `Scheduled`-lähetys hylätään virheellä `400` — keskeytä se ensin.

---

## Klassisia kampanjoita peilaavat lähetykset

Klassiset kampanjat, jotka lähettävät viestejä, näkyvät myös Lähetyksissä, ja API palauttaa ne natiivien lähetysten ohella (niissä on `source_campaign_id`). Ne toimivat hieman eri tavalla, koska kampanja pysyy hallinnassa:

- **Yleisön, viestin tai aikataulun muokkaaminen** toimii ja muutokset tallentuvat kampanjaan.
- **Kanava, vastausagentti, liite ja kaikki suorituslaskurit ovat täällä vain luku -muodossa** — saat virheen `400`, jos yrität muuttaa niitä. Muuta ne kampanjassa.
- **Käynnistys (Launch)** palauttaa virheen `400`, joka ohjaa sinut kampanjaeditoriin.
- **Keskeytys ja jatkaminen (Pause and resume)** toimivat ja vaikuttavat kampanjaan.
- **Poisto (Delete)** palauttaa virheen `400` — poista sen sijaan kampanja, jolloin myös sen lähetysmerkintä poistuu.
- **Duplikointi (Duplicate)** luo itsenäisen natiivin lähetyksen, mikä on tuettu tapa siirtää toimivaksi todettu kampanja.

---

## Virheet

Epäonnistuneet pyynnöt palauttavat virheen `{"success": false, "error": "<message>"}` seuraavilla tiloilla:

| Tila | Merkitys |
|---|---|
| `400` | Pyynnössä tai lähetyksen tilassa on jotain vialla — puuttuva kenttä, virheellinen liite tai käynnistys/keskeytys/jatkaminen/poisto, joka ei ole sallittu lähetyksen nykyisessä tilassa. `error`-viesti kertoo syyn. |
| `401` | Puuttuva tai virheellinen API-avain. |
| `403` | Tilauksesi ei sisällä API-käyttöoikeutta. |
| `404` | Tiliäsi vastaavaa lähetystä ei löydy (tai mallin valinnan kohdalla: mallia ei löydy). |
| `429` | Nopeusrajoitus ylittynyt. Odota hetki ja yritä uudelleen. |
| `500` | Jokin meni vikaan meidän puolellamme. Yritä uudelleen lyhyen odotuksen jälkeen. |

---

## Seuraavat vaiheet

- [Lähetysten opas](../broadcasts/broadcasts.md) — näiden päätepisteiden taustalla oleva tuote, mukaan lukien tahdistus ja turvallisuuskäyttäytyminen
- [Yhteystieto-API](contacts.md) — rakenna lista, johon lähetys lähetetään
- [Malli-API](templates.md) — hallitse hyväksyttyjä WhatsApp-malleja, joista voit valita
- [Webhook-API](webhooks.md) — tilaa `Broadcast Started` ja `Broadcast Completed` kyselyn (polling) sijaan
