
# API pentru difuzări

O **difuzare** reprezintă o trimitere externă: un public, un mesaj de deschidere, un canal și o programare. Opțional, aceasta numește și agentul AI care gestionează răspunsurile primite. API-ul pentru difuzări vă permite să creați, să stabiliți prețul, să lansați și să monitorizați acele trimiteri din propriul cod, în loc să folosiți tabloul de bord. Pentru produsul în sine, consultați [ghidul pentru difuzări](../broadcasts/broadcasts.md).

- **URL de bază** — `https://api.youraiconnector.com/v1`
- **Autentificare** — cheia ta API (vezi [Autentificare](authentication.md))
- **Erori și paginare** — vezi [Erori și paginare](errors-and-pagination.md)

Toate exemplele de mai jos arată forma de interogare `?apiKey=` în cURL și antetul `X-API-Key` în JavaScript și Python — oricare dintre ele funcționează pe fiecare endpoint.

> **În exploratorul API.** Fiecare endpoint de pe această pagină se află în specificația OpenAPI publicată, astfel încât puteți naviga prin câmpurile sale exacte și puteți rula cereri live în [exploratorul API](reference.md).


---

## Cum este structurată o trimitere

Trimiterea unei difuzări presupune patru apeluri, nu unul:

1. **Creați** difuzarea cu publicul, canalul și programarea sa — aceasta începe ca un `Draft`.
2. **Setați mesajul de deschidere.** Pe WhatsApp Business, aceasta înseamnă trimiterea unui șablon spre aprobare (sau alegerea unuia deja aprobat). Pe orice alt canal, acesta este text simplu.
3. **Estimați costul** dacă doriți să verificați prețul înainte de a cheltui ceva (opțional).
4. **Lansați-o.** Lansarea efectuează o verificare completă — public, mesaj, aprobarea șablonului, expeditor conectat — și fie începe trimiterea, fie vă spune exact ce lipsește.

Nimic nu este trimis până când nu apelați funcția de lansare.

---

## Obiectul de difuzare

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

**Marcajele temporale sunt returnate sub formă de milisecunde epoch** (`execution_date`, `created_at`, `last_modified_at`, …), iar orice referință la contact este returnată ca un șir de cale, cum ar fi `contacts/uid_whatsapp_15551234567`.

### Câmpuri pe care le setați

| Câmp | Descriere |
|---|---|
| `name` | Cum este numită difuzarea în tabloul de bord. |
| `channel` | Singurul canal pe care se trimite această difuzare: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `facebook`, `telegram`, `instagram_private`, `line`, `viber`, `imessage`, `email`, `chat_widget`, `custom_channel`. O difuzare are exact un canal — pentru a trimite același lucru în altă parte, [duplicați-o pe un alt canal](#duplicate-a-broadcast). `tiktok` și `skool` sunt doar pentru răspunsuri și nu pot fi folosite niciodată pentru difuzare. |
| `agent_id` | Agentul AI care răspunde la mesaje. Lăsați-l `null` și răspunsurile vor ajunge în căsuța de primire a echipei dumneavoastră. |
| `list_id` | Lista de contacte către care se trimite. Acesta este modul în care setați publicul din API — consultați [Contacte](contacts.md) pentru crearea și completarea listelor. |
| `list_name` | Numele afișat lângă difuzare. Cosmetic. |
| `send_to_new_list_members` | `true` menține difuzarea activă, astfel încât oricine este adăugat ulterior în listă să primească și el mesajul de deschidere. |
| `whats_app_template` | Mesajul de deschidere. Pe WhatsApp Business este un șablon real aprobat; pe orice alt canal, `body` al acestuia este folosit ca text de deschidere simplu. Setați-l prin [endpoint-urile de șabloane](#the-opening-message), nu manual. |
| `opener_media` | O imagine sau un videoclip trimis cu mesajul de deschidere. Trimiteți întotdeauna întregul obiect (sau `null` pentru a-l elimina) — scrierea de chei individuale în interiorul acestuia va fi respinsă. Nu este acceptat pe SMS. |
| `execution_date` | Când să se trimită. Trimiteți un marcaj temporal ISO 8601 sau milisecunde epoch. O dată viitoare programează trimiterea; omiteți-o (sau folosiți una din trecut) pentru a trimite imediat ce lansați. |
| `drip_mode` | `true` distribuie trimiterea în loturi în timp, în loc de toate odată. |
| `time_critical` | `true` renunță la distribuirea automată care se activează peste 50 de contacte — pentru un public cald care are nevoie de mesaj acum. Nu ridică limita zilnică de trimitere a canalului. |
| `batch_size` | Câte contacte per lot atunci când se folosește distribuirea treptată. |
| `follow_up_config` | Lanțul de mesaje de follow-up pentru contactele care nu răspund niciodată. |

Orice trimiteți ca `user_id`, `id`, `status` sau `source_campaign_id` este ignorat la creare și eliminat la actualizare — starea se modifică doar prin endpoint-urile de lansare, pauză și reluare de mai jos.

### Câmpuri menținute de platformă

`status`, `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate`, `credits_used`, `paused_reason`, `completion_summary`, contoarele de lot și `contacts` (contactele individuale atașate din tabloul de bord, citite ca șiruri de cale). Citiți-le, nu le scrieți.

### Stări

| Status | Semnificație |
|---|---|
| `Draft` | În curs de construire. Nu este programat nimic. |
| `Pending Approval` | Lansat, dar șablonul său WhatsApp încă așteaptă o decizie. Începe să trimită automat odată ce șablonul este aprobat — nu trebuie să îl lansați din nou. |
| `Scheduled` | Lansat cu o `execution_date` viitoare. |
| `Sending` | Se trimite activ (o difuzare pregătită pentru membrii noi ai listei rămâne aici în timp ce îi așteaptă). |
| `Paused` | Suspendat — de către dumneavoastră sau automat printr-o verificare de siguranță. |
| `Sent` | Finalizat. |
| `Failed` | Finalizat cu mai mult de jumătate din trimiteri eșuate. |

---

## Crearea unei difuzări

`POST /broadcasts` — creează o `Draft`.

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

**Răspuns** (`201`)

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

---

## Listarea difuzărilor

`GET /broadcasts` — fiecare difuzare din cont, cele mai noi primele.

**Parametri de interogare**

| Parametru | Obligatoriu | Descriere |
|---|---|---|
| `status` | Nu | Returnează doar difuzările cu o anumită stare, de ex. `Sending`. Respectați exact ortografia din [tabelul de stări](#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"]
```

**Răspuns** (`200`)

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

---

## Obținerea unei difuzări

`GET /broadcasts/{broadcastId}` — returnează `{ "success": true, "broadcast": { ... } }`. Folosiți-l pentru a interoga o trimitere în curs: `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate` și `credits_used` se actualizează pe măsură ce procesul avansează.

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

O difuzare care nu există în contul dvs. returnează `404`.

---

## Actualizarea unei difuzări

`PUT /broadcasts/{broadcastId}` — trimiteți doar câmpurile pe care doriți să le modificați. De asemenea, puteți adresa o singură cheie dintr-un obiect imbricat folosind o cale cu punct, de ex. `"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" }),
});
```

Un corp gol returnează `400`. Două reguli care merită cunoscute:

- **`opener_media` este de tip totul sau nimic.** Trimiteți obiectul complet sau `null` pentru a elimina atașamentul. O cale cu punct către acesta (`opener_media.name`) este respinsă cu `400`, deoarece un atașament actualizat parțial ar descrie un fișier care nu există.
- **Starea nu poate fi editată.** Folosiți [lansare](#launch-a-broadcast), [pauză](#pause-and-resume) și [reluare](#pause-and-resume).

---

## Mesajul de deschidere

Fiecare difuzare își poartă mesajul de deschidere în `whats_app_template`. Ce înseamnă acest lucru depinde de canal:

- **WhatsApp Business** — trebuie să fie un șablon aprobat de WhatsApp. Folosiți unul dintre cele două endpoint-uri de mai jos.
- **Orice alt canal** (WhatsApp Web, SMS, Instagram, Messenger, Telegram, …) — câmpul `body` al aceluiași element este pur și simplu textul care este trimis. Trimiterea acestuia prin endpoint-ul de mai jos îl stochează și îl marchează ca fiind gata, fără a implica WhatsApp deloc.

### Trimiteți un șablon pentru aprobare

`POST /broadcasts/{broadcastId}/template`

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `body` | Da | Textul mesajului, până la 1024 de caractere. Folosiți substituenți `{{variable}}` pentru personalizare. |
| `name` | Nu | Numele șablonului. Implicit este numele difuzării. |
| `language` | Nu | Codul limbii. Implicit este `en`. |
| `category` | Nu | `marketing` (implicit), `utility`, `authentication` sau `authentication-international`. Acesta este prețul la care se face trimiterea, așa că fiți corecți. |
| `variables` | Nu | Numele substituenților, în ordinea în care apar. Omiteți-l și vor fi citiți din corp — ceea ce este de obicei ceea ce doriți, deoarece trimiterea îi completează din fiecare contact. |

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

**Răspuns** (`200`)

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

`template_status` este ceea ce spune WhatsApp: `pending` în timp ce este revizuit, `approved` când este utilizabil, `rejected` dacă a fost refuzat. Pe un canal care nu este WhatsApp, acesta revine direct ca `approved` cu `template_sid: null` — nimic de revizuit.

Lucruri care vă vor opri:

- Trimiterea în timp ce un șablon anterior este încă în curs de revizuire returnează `400`. Așteptați mai întâi decizia.
- Editarea unui șablon care este deja aprobat menține versiunea aprobată activă până când cea nouă revine, astfel încât o difuzare în curs nu își pierde niciodată mesajul de deschidere.
- Pe un număr WhatsApp conectat direct prin Meta, o difuzare cu o imagine sau un videoclip atașat nu poate fi trimisă (`400`) — atașamentele sunt acceptate pe canalul gestionat WhatsApp Business și pe WhatsApp Web.

### Folosiți un șablon pe care l-ați aprobat deja

`POST /broadcasts/{broadcastId}/template/select` — copiază un șablon deja aprobat din [biblioteca de șabloane](templates.md) pe difuzare, deci nu este nimic de așteptat.

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `template_id` | Da | ID-ul unui șablon aprobat din contul dumneavoastră. |

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

**Răspuns** (`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"
}
```

Aprobarea este verificată de partea noastră din înregistrarea din bibliotecă — trimiteți întotdeauna doar ID-ul. Primiți un `400` dacă difuzarea nu este o ciornă WhatsApp, dacă șablonul nu este aprobat, dacă este un șablon de continuare în loc de unul de deschidere sau dacă difuzarea are un atașament (șabloanele din bibliotecă sunt doar text). Un ID de șablon care nu se află în contul dumneavoastră returnează `404`.

---

## Estimați costul

`POST /broadcasts/{broadcastId}/estimate-cost` — calculează prețul trimiterii înainte de a vă angaja la aceasta. Disponibil pentru difuzările `whatsapp` și `sms`; orice alt canal returnează `400`. Difuzarea are nevoie de un `list_id`, deoarece estimarea numără audiența.

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

**Răspuns WhatsApp** (`200`) — credite, defalcate pe țara de destinație:

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

**Răspuns prin SMS** (`200`) — dolari americani, pe baza prețurilor live Twilio pentru propriul tău cont Twilio:

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

**Citește `billing_mode` înainte de a afișa un număr.** Îți indică cine este facturat:

| `billing_mode` | Cine plătește | Ce înseamnă cifrele |
|---|---|---|
| `credits` | Contul tău <span data-t="appName">Your AI Connector</span> | `totalTemplateCost` și cifrele pe țară reprezintă credite. |
| `twilio_direct` | Propriul tău cont Twilio | `estimatedCostUsd` este ceea ce te va taxa Twilio. |
| `meta_waba_direct` | Propriul tău cont WhatsApp Business, facturat de Meta | Fiecare cifră de credit revine `null` — în mod deliberat, pentru a nu fi confundată niciodată cu „gratuit”. Numărul de țări și contacte rămâne exact. |

SMS-urile fără credențiale Twilio conectate returnează în continuare numărul de segmente, cu `estimatedCostUsd: 0` — nu există prețuri de consultat.

---

## Lansează o difuzare

`POST /broadcasts/{broadcastId}/launch`

Lansarea verifică totul mai întâi și abia apoi trece la difuzare. Nu există lansare parțială: fie pornește, fie nu se schimbă nimic și primești o eroare care explică motivul.

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

**Răspuns** (`200`)

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

`status` este locul unde a ajuns difuzarea:

- `Scheduled` — `execution_date` este în viitor.
- `Sending` — a început acum.
- `Pending Approval` — șablonul WhatsApp este încă în curs de examinare. Se va trimite automat imediat ce șablonul este aprobat; nu apelați din nou lansarea.

Doar o difuzare `Draft` (sau o difuzare `Pending Approval` al cărei șablon a fost aprobat între timp) poate fi lansată — orice altceva returnează `400`.

### De ce este refuzată o lansare

Fiecare dintre acestea revine ca `400` cu un mesaj `error` în limbaj simplu:

| Problemă | Ce trebuie remediat |
|---|---|
| Fără audiență | Setați `list_id` (sau atașați contacte) înainte de lansare. |
| Fără mesaj de deschidere | Setați mesajul de deschidere — consultați [Mesajul de deschidere](#the-opening-message). |
| Atașament în SMS | SMS-urile nu pot conține imagini sau videoclipuri. Eliminați atașamentul sau mutați difuzarea pe WhatsApp. |
| Atașamentul nu corespunde șablonului aprobat | Pe WhatsApp, conținutul media se află în interiorul șablonului aprobat, deci înlocuirea atașamentului ulterior înseamnă retrimiterea șablonului. |
| Șablon respins | Rescrieți mesajul și trimiteți-l din nou. |
| Șablon netrimis | Trimiteți-l (sau selectați unul aprobat) mai întâi. |
| Șablon aprobat, dar care lipsește din contul dvs. WhatsApp | De obicei, este un șablon aprobat înainte ca numărul să finalizeze conectarea. Trimiteți-l din nou. |
| Niciun expeditor conectat pentru canal | Conectați canalul mai întâi — consultați [Canale](channels.md). |
| Canal doar pentru răspunsuri | TikTok și Skool nu permit unei companii să inițieze o conversație, deci nu pot fi utilizate pentru difuzări. |
| Deja armat | Difuzarea are deja o trimitere programată. Întrerupeți-o înainte de a lansa din nou. |
| Încă în așteptarea aprobării | Se va trimite automat când șablonul va fi aprobat. |
| Cont WhatsApp Business blocat de Meta | Meta a oprit conversațiile inițiate de companii pe propriul dvs. cont WhatsApp Business — de obicei este o problemă legată de metoda de plată. Remediați-o în Meta Business Manager. |
| Început dintr-o campanie clasică | Lansați-o din editorul de campanii. Consultați [campaniile clasice în Difuzări](#broadcasts-that-mirror-a-classic-campaign). |

---

## Întrerupere și reluare

`POST /broadcasts/{broadcastId}/pause` oprește o difuzare `Sending` sau `Scheduled` și anulează tot ce se află în coadă.

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

Întreruperea unei difuzări `Pending Approval` o readuce în starea `Draft` — nu era nimic programat încă, deci nu există nimic la care să se revină. Orice altă stare returnează `400`.

`POST /broadcasts/{broadcastId}/resume` repornește o difuzare `Paused`:

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

**Răspuns** (`200`)

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

Aceasta revine la `Sending` sau înapoi la `Scheduled` dacă `execution_date` sa este încă în viitor. Doar o difuzare `Paused` poate fi reluată.

---

## Continuă trimiterea după o pauză cauzată de implicare scăzută

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

În timp ce o difuzare se trimite în loturi, măsurăm câți oameni au răspuns la fiecare lot înainte de a-l începe pe următorul. Dacă aproape nimeni nu răspunde, difuzarea se întrerupe automat — o trimitere care continuă să insiste în tăcere este cea mai rapidă cale de a obține filtrarea sau blocarea unui număr. Acesta este butonul **Continuă oricum** din tabloul de bord.

Deoarece rata de răspuns care a cauzat pauza nu se poate schimba în timp ce difuzarea este oprită, o simplă [reluare](#pause-and-resume) ar fi întreruptă din nou la următoarea verificare. Acest endpoint reprezintă decizia de a continua oricum: înregistrează suprascrierea pentru acea difuzare și elimină pauza în același apel, dacă difuzarea a fost întreruptă din cauza implicării scăzute.

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

**Răspuns** (`200`)

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

- `resumed: true` — difuzarea a fost întreruptă din cauza implicării scăzute și rulează din nou acum; `status` este starea la care a revenit.
- `resumed: false` — nu a fost eliminată nicio restricție, suprascrierea este pur și simplu înregistrată pentru verificări viitoare. Aceasta este ceea ce primești dacă difuzarea nu a fost niciodată întreruptă sau a fost întreruptă dintr-un alt motiv (ai întrerupt-o manual, a fost atinsă o limită de trimitere sau prea multe trimiteri au generat erori). Acele pauze nu sunt eliminate aici — reia difuzarea singur după ce ai rezolvat cauza.

Suprascrierea se aplică doar acestei difuzări. Nu este o setare a contului și este sigur să fie apelată de două ori.

---

## Duplică o difuzare

`POST /broadcasts/{broadcastId}/duplicate` — copiază audiența, mesajul și setările într-o nouă `Draft`. Tot ce ține de rularea anterioară (contori, loturi, programare, statistici de răspuns) pornește de la zero.

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `to_channel` | Nu | Creează copia pe un canal diferit. Așa trimiți același lucru pe două canale — o difuzare are întotdeauna un singur canal. |

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

**Răspuns** (`201`)

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

O copie nu moștenește niciodată o aprobare WhatsApp activă: pe o copie WhatsApp, șablonul vine necesitând confirmarea ta, iar pe o copie către un alt canal, acesta este eliminat și textul devine deschiderea simplă. Copierea către SMS elimină, de asemenea, orice atașament, deoarece SMS-ul nu poate trimite unul.

---

## Șterge o difuzare

`DELETE /broadcasts/{broadcastId}`

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

O difuzare `Sending` sau `Scheduled` este refuzată cu `400` — întrerupeți-o mai întâi.

---

## Difuzări care oglindesc o campanie clasică

Campaniile clasice care trimit mesaje apar, de asemenea, în Difuzări, iar API-ul le returnează alături de difuzările native (acestea poartă un `source_campaign_id`). Acestea se comportă puțin diferit, deoarece campania rămâne responsabilă:

- **Editarea** audienței, a mesajului sau a programării funcționează și este aplicată campaniei.
- **Canalul, agentul de răspuns, atașamentul și toți contorii de rulare sunt doar în citire** aici — `400` dacă încercați să îi modificați. Modificați-i în cadrul campaniei.
- **Lansarea** returnează `400`, direcționându-vă către editorul campaniei.
- **Întreruperea și reluarea** funcționează și acționează asupra campaniei.
- **Ștergerea** returnează `400` — ștergeți campania în schimb, iar intrarea sa din Difuzări va fi eliminată odată cu aceasta.
- **Duplicarea** vă oferă o difuzare nativă independentă, care este metoda acceptată pentru a transfera o campanie dovedită.

---

## Erori

Cererile eșuate returnează `{"success": false, "error": "<message>"}` cu următoarele stări:

| Status | Semnificație |
|---|---|
| `400` | Ceva nu este în regulă cu cererea sau cu starea difuzării — un câmp lipsă, un atașament invalid sau o lansare/întrerupere/reluare/ștergere care nu este permisă în starea curentă a difuzării. Mesajul `error` indică motivul. |
| `401` | Cheie API lipsă sau invalidă. |
| `403` | Planul dumneavoastră nu include acces API. |
| `404` | Nu există o astfel de difuzare în contul dumneavoastră (sau, la selectarea șablonului, nu există un astfel de șablon). |
| `429` | Limită de rată atinsă. Așteptați și reîncercați. |
| `500` | Ceva nu a funcționat corect de partea noastră. Reîncercați după o scurtă așteptare. |

---

## Pașii următori

- [Ghidul Difuzărilor](../broadcasts/broadcasts.md) — produsul din spatele acestor endpoint-uri, inclusiv ritmul și comportamentul de siguranță
- [API Contacte](contacts.md) — construiți lista către care trimite o difuzare
- [API Șabloane](templates.md) — gestionați șabloanele WhatsApp aprobate pe care le puteți selecta
- [API Webhooks](webhooks.md) — abonați-vă la `Broadcast Started` și `Broadcast Completed` în loc să interogați
