
# API Siaran

Sebuah **siaran** adalah satu pengiriman keluar: audiens, pesan pembuka, satu saluran, dan jadwal. Secara opsional, siaran juga menamai Agen AI yang menangani balasan yang diterima. API Siaran memungkinkan Anda untuk membuat, menentukan harga, meluncurkan, dan memantau pengiriman tersebut dari kode Anda sendiri, bukan dari dasbor. Untuk produk itu sendiri, lihat [panduan Siaran](../broadcasts/broadcasts.md).

- **URL Dasar** — `https://api.youraiconnector.com/v1`
- **Autentikasi** — kunci API Anda (lihat [Autentikasi](authentication.md))
- **Kesalahan & penomoran halaman** — lihat [Kesalahan & Penomoran Halaman](errors-and-pagination.md)

Semua contoh di bawah ini menunjukkan formulir kueri `?apiKey=` dalam cURL dan header `X-API-Key` dalam JavaScript dan Python — keduanya berfungsi di setiap endpoint.

> **Di penjelajah API.** Setiap endpoint di halaman ini ada dalam spesifikasi OpenAPI yang dipublikasikan, sehingga Anda dapat menelusuri kolom-kolomnya secara tepat dan menjalankan permintaan langsung di [penjelajah API](reference.md).


---

## Cara menyusun pengiriman

Mengirim siaran terdiri dari empat panggilan, bukan satu:

1. **Buat** siaran dengan audiens, saluran, dan jadwalnya — siaran dimulai sebagai `Draft`.
2. **Atur pesan pembuka.** Pada WhatsApp Business, ini berarti mengirimkan templat untuk disetujui (atau memilih templat yang sudah disetujui). Pada saluran lain, ini berupa teks biasa.
3. **Perkirakan biaya** jika Anda ingin memeriksa harga sebelum mengeluarkan biaya apa pun (opsional).
4. **Luncurkan.** Meluncurkan akan menjalankan pemeriksaan penuh — audiens, pesan, persetujuan templat, pengirim yang terhubung — dan kemudian memulai pengiriman atau memberi tahu Anda apa yang kurang.

Tidak ada yang dikirim sampai Anda memanggil fungsi luncurkan.

---

## Objek siaran

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

**Stempel waktu dikembalikan sebagai milidetik epoch** (`execution_date`, `created_at`, `last_modified_at`, …), dan referensi kontak apa pun dikembalikan sebagai string jalur seperti `contacts/uid_whatsapp_15551234567`.

### Kolom yang Anda atur

| Kolom | Deskripsi |
|---|---|
| `name` | Nama siaran di dasbor. |
| `channel` | Satu saluran yang digunakan siaran ini untuk mengirim: `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `facebook`, `telegram`, `instagram_private`, `line`, `viber`, `imessage`, `email`, `chat_widget`, `custom_channel`. Sebuah siaran hanya memiliki satu saluran — untuk mengirim hal yang sama di tempat lain, [duplikat ke saluran lain](#duplicate-a-broadcast). `tiktok` dan `skool` hanya untuk balasan dan tidak pernah bisa digunakan untuk siaran. |
| `agent_id` | Agen AI yang menjawab balasan. Biarkan `null` agar balasan masuk ke kotak masuk tim Anda sebagai gantinya. |
| `list_id` | Daftar kontak yang dituju. Ini adalah cara Anda mengatur audiens dari API — lihat [Kontak](contacts.md) untuk membuat dan mengisi daftar. |
| `list_name` | Nama tampilan yang ditunjukkan di samping siaran. Hanya kosmetik. |
| `send_to_new_list_members` | `true` menjaga siaran tetap aktif sehingga siapa pun yang ditambahkan ke daftar nanti juga mendapatkan pesan pembuka. |
| `whats_app_template` | Pesan pembuka. Pada WhatsApp Business, ini adalah templat resmi yang disetujui; pada saluran lain, `body`-nya digunakan sebagai teks pembuka biasa. Atur melalui [endpoint templat](#the-opening-message), bukan secara manual. |
| `opener_media` | Satu gambar atau video yang dikirim bersama pesan pembuka. Selalu kirim seluruh objek (atau `null` untuk menghapusnya) — penulisan kunci individual di dalamnya akan ditolak. Tidak didukung pada SMS. |
| `execution_date` | Waktu pengiriman. Kirim stempel waktu ISO 8601 atau milidetik epoch. Tanggal di masa depan akan menjadwalkan pengiriman; hilangkan (atau gunakan tanggal yang sudah lewat) untuk mengirim segera setelah Anda meluncurkan. |
| `drip_mode` | `true` mengatur kecepatan pengiriman dalam batch dari waktu ke waktu, bukan sekaligus. |
| `time_critical` | `true` menolak pengaturan kecepatan otomatis yang aktif di atas 50 kontak — untuk audiens hangat yang perlu menerima pesan sekarang. Ini tidak menaikkan batas pengiriman harian saluran itu sendiri. |
| `batch_size` | Berapa banyak kontak per batch saat menggunakan pengiriman bertahap (drip). |
| `follow_up_config` | Rantai tindak lanjut untuk kontak yang tidak pernah membalas. |

Apa pun yang Anda kirim sebagai `user_id`, `id`, `status`, atau `source_campaign_id` akan diabaikan saat pembuatan dan dibuang saat pembaruan — status hanya akan berubah melalui endpoint luncurkan, jeda, dan lanjutkan di bawah.

### Kolom yang dikelola platform

`status`, `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate`, `credits_used`, `paused_reason`, `completion_summary`, penghitung batch, dan `contacts` (kontak individual yang dilampirkan dari dasbor, dibaca kembali sebagai string jalur). Baca kolom-kolom ini, jangan tulis.

### Status

| Status | Arti |
|---|---|
| `Draft` | Sedang dibuat. Tidak ada yang dijadwalkan. |
| `Pending Approval` | Diluncurkan, tetapi templat WhatsApp-nya masih menunggu keputusan. Pesan akan mulai terkirim secara otomatis setelah templat disetujui — Anda tidak perlu meluncurkannya lagi. |
| `Scheduled` | Diluncurkan dengan `execution_date` di masa mendatang. |
| `Sending` | Sedang aktif mengirim (siaran yang disiapkan untuk anggota daftar baru akan tetap di sini saat menunggu mereka). |
| `Paused` | Ditahan — oleh Anda, atau secara otomatis oleh pemeriksaan keamanan. |
| `Sent` | Selesai. |
| `Failed` | Selesai dengan lebih dari setengah pengiriman gagal. |

---

## Membuat siaran

`POST /broadcasts` — membuat `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"])
```

**Respons** (`201`)

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

---

## Mencantumkan siaran

`GET /broadcasts` — setiap siaran di akun, yang terbaru ditampilkan lebih dulu.

**Parameter kueri**

| Parameter | Wajib | Deskripsi |
|---|---|---|
| `status` | Tidak | Hanya mengembalikan siaran dalam satu status, contoh `Sending`. Sesuaikan ejaan dengan [tabel status](#statuses) secara tepat. |

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

**Respons** (`200`)

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

---

## Mendapatkan siaran

`GET /broadcasts/{broadcastId}` — mengembalikan `{ "success": true, "broadcast": { ... } }`. Gunakan ini untuk melakukan polling pada pengiriman yang sedang berjalan: `total_contacts_sent`, `unique_contacts_replied`, `overall_reply_rate`, dan `credits_used` akan diperbarui seiring berjalannya proses.

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

Siaran yang tidak ada di akun Anda akan mengembalikan `404`.

---

## Memperbarui siaran

`PUT /broadcasts/{broadcastId}` — kirim hanya kolom yang ingin Anda ubah. Anda juga dapat menentukan satu kunci di dalam objek bersarang dengan jalur bertitik, contoh `"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" }),
});
```

Isi kosong akan mengembalikan `400`. Dua aturan yang perlu diketahui:

- **`opener_media` bersifat semua-atau-tidak-sama-sekali.** Kirim objek lengkap, atau `null` untuk menghapus lampiran. Jalur bertitik ke dalamnya (`opener_media.name`) akan ditolak dengan `400`, karena lampiran yang diperbarui sebagian akan mendeskripsikan file yang tidak ada.
- **Status tidak dapat diedit.** Gunakan [luncurkan](#launch-a-broadcast), [jeda](#pause-and-resume), dan [lanjutkan](#pause-and-resume).

---

## Pesan pembuka

Setiap siaran membawa pembukanya di `whats_app_template`. Apa artinya itu bergantung pada salurannya:

- **WhatsApp Business** — harus berupa templat yang telah disetujui oleh WhatsApp. Gunakan salah satu dari dua endpoint di bawah ini.
- **Setiap saluran lainnya** (WhatsApp Web, SMS, Instagram, Messenger, Telegram, …) — `body` pada kolom yang sama hanyalah teks yang dikirimkan. Mengirimkannya melalui endpoint di bawah ini akan menyimpannya dan menandainya sebagai siap tanpa melibatkan WhatsApp sama sekali.

### Kirim templat untuk disetujui

`POST /broadcasts/{broadcastId}/template`

| Kolom | Wajib | Deskripsi |
|---|---|---|
| `body` | Ya | Teks pesan, maksimal 1024 karakter. Gunakan placeholder `{{variable}}` untuk personalisasi. |
| `name` | Tidak | Nama templat. Default-nya adalah nama siaran. |
| `language` | Tidak | Kode bahasa. Default-nya adalah `en`. |
| `category` | Tidak | `marketing` (default), `utility`, `authentication`, atau `authentication-international`. Ini adalah harga pengiriman, jadi pastikan sesuai. |
| `variables` | Tidak | Nama placeholder, sesuai urutan kemunculannya. Lewati jika ingin dibaca dari badan pesan — yang biasanya merupakan pilihan tepat, karena pengiriman akan mengisinya dari setiap kontak. |

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

**Respons** (`200`)

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

`template_status` adalah apa yang dikatakan WhatsApp: `pending` saat sedang ditinjau, `approved` saat dapat digunakan, `rejected` jika ditolak. Pada saluran non-WhatsApp, statusnya langsung kembali sebagai `approved` dengan `template_sid: null` — tidak ada yang perlu ditinjau.

Hal-hal yang akan menghambat Anda:

- Mengirim saat templat sebelumnya masih dalam peninjauan akan mengembalikan `400`. Tunggu keputusannya terlebih dahulu.
- Mengedit templat yang saat ini disetujui akan tetap mempertahankan templat yang disetujui tetap aktif hingga yang baru kembali, sehingga siaran yang sedang berjalan tidak akan kehilangan pembukanya.
- Pada nomor WhatsApp yang terhubung langsung melalui Meta, siaran dengan lampiran gambar atau video tidak dapat dikirim (`400`) — lampiran didukung pada jalur WhatsApp Business terkelola dan di WhatsApp Web.

### Gunakan templat yang sudah disetujui

`POST /broadcasts/{broadcastId}/template/select` — menyalin templat yang sudah disetujui dari [pustaka templat](templates.md) Anda ke siaran, sehingga tidak ada yang perlu ditunggu.

| Kolom | Wajib | Deskripsi |
|---|---|---|
| `template_id` | Ya | ID templat yang disetujui di akun Anda. |

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

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

Persetujuan diverifikasi di pihak kami dari catatan pustaka — Anda hanya perlu mengirimkan ID-nya. Anda akan mendapatkan `400` jika siaran bukan draf WhatsApp, jika templat tidak disetujui, jika itu adalah templat tindak lanjut (bukan pembuka), atau jika siaran memiliki lampiran (templat pustaka hanya berupa teks). ID templat yang tidak ada di akun Anda akan mengembalikan `404`.

---

## Perkirakan biaya

`POST /broadcasts/{broadcastId}/estimate-cost` — menentukan harga pengiriman sebelum Anda berkomitmen. Tersedia pada siaran `whatsapp` dan `sms`; saluran lain akan mengembalikan `400`. Siaran memerlukan `list_id`, karena estimasi menghitung jumlah audiens.

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

**Respons WhatsApp** (`200`) — kredit, dirinci berdasarkan negara tujuan:

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

**Respons SMS** (`200`) — Dolar AS, berdasarkan harga Twilio langsung untuk akun Twilio Anda sendiri:

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

**Baca `billing_mode` sebelum Anda menampilkan nomor.** Ini memberi tahu Anda siapa yang ditagih:

| `billing_mode` | Siapa yang membayar | Apa arti angka-angka tersebut |
|---|---|---|
| `credits` | Akun <span data-t="appName">Your AI Connector</span> Anda | `totalTemplateCost` dan angka per negara adalah kredit. |
| `twilio_direct` | Akun Twilio Anda sendiri | `estimatedCostUsd` adalah jumlah yang akan ditagihkan Twilio kepada Anda. |
| `meta_waba_direct` | Akun WhatsApp Business Anda sendiri, ditagih oleh Meta | Setiap angka kredit kembali sebagai `null` — sengaja dilakukan agar tidak pernah disalahartikan sebagai "gratis". Jumlah negara dan kontak tetap akurat. |

SMS tanpa kredensial Twilio yang terhubung tetap mengembalikan jumlah segmen, dengan `estimatedCostUsd: 0` — tidak ada harga untuk dicari.

---

## Luncurkan siaran

`POST /broadcasts/{broadcastId}/launch`

Meluncurkan akan memeriksa semuanya terlebih dahulu dan baru kemudian melanjutkan siaran. Tidak ada peluncuran parsial: siaran dimulai, atau tidak ada yang berubah dan Anda mendapatkan pesan kesalahan yang menjelaskan alasannya.

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

**Respons** (`200`)

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

`status` adalah tempat siaran mendarat:

- `Scheduled` — `execution_date` berada di masa depan.
- `Sending` — siaran dimulai sekarang.
- `Pending Approval` — templat WhatsApp masih dalam peninjauan. Siaran akan terkirim segera setelah templat disetujui; jangan panggil luncurkan lagi.

Hanya `Draft` (atau siaran `Pending Approval` yang templatnya telah disetujui) yang dapat diluncurkan — yang lainnya akan mengembalikan `400`.

### Mengapa peluncuran ditolak

Setiap masalah ini kembali sebagai `400` dengan pesan `error` dalam bahasa yang sederhana:

| Masalah | Apa yang harus diperbaiki |
|---|---|
| Tidak ada audiens | Tetapkan `list_id` (atau lampirkan kontak) sebelum meluncurkan. |
| Tidak ada pesan pembuka | Tetapkan pembuka — lihat [Pesan pembuka](#the-opening-message). |
| Lampiran pada SMS | SMS tidak dapat membawa gambar atau video. Hapus lampiran atau pindahkan siaran ke WhatsApp. |
| Lampiran tidak cocok dengan templat yang disetujui | Di WhatsApp, media berada di dalam templat yang disetujui, jadi mengganti lampiran setelahnya berarti harus mengirimkan ulang templat tersebut. |
| Templat ditolak | Tulis ulang pesan dan kirimkan lagi. |
| Templat tidak pernah dikirimkan | Kirimkan (atau pilih yang sudah disetujui) terlebih dahulu. |
| Templat disetujui tetapi hilang dari akun WhatsApp Anda | Biasanya templat disetujui sebelum nomor selesai dihubungkan. Kirimkan lagi. |
| Tidak ada pengirim yang terhubung untuk saluran tersebut | Hubungkan saluran terlebih dahulu — lihat [Saluran](channels.md). |
| Saluran khusus balasan | TikTok dan Skool tidak mengizinkan bisnis untuk memulai percakapan, jadi mereka tidak dapat digunakan untuk siaran. |
| Sudah dipersenjatai | Siaran sudah memiliki jadwal pengiriman. Jeda sebelum meluncurkan lagi. |
| Masih menunggu persetujuan | Siaran akan terkirim sendiri saat templat disetujui. |
| Akun WhatsApp Business diblokir oleh Meta | Meta telah menghentikan percakapan yang dimulai bisnis di Akun WhatsApp Business Anda sendiri — biasanya masalah metode pembayaran. Perbaiki di Meta Business Manager. |
| Dimulai dari kampanye klasik | Luncurkan dari editor kampanye sebagai gantinya. Lihat [kampanye klasik di Siaran](#broadcasts-that-mirror-a-classic-campaign). |

---

## Jeda dan lanjutkan

`POST /broadcasts/{broadcastId}/pause` menghentikan siaran `Sending` atau `Scheduled` dan menghapus apa pun yang ada dalam antrean.

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

Menjeda siaran `Pending Approval` akan mengembalikannya ke `Draft` — belum ada yang dijadwalkan, jadi tidak ada yang bisa dilanjutkan. Status lainnya akan mengembalikan `400`.

`POST /broadcasts/{broadcastId}/resume` memulai ulang siaran `Paused`:

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

**Respons** (`200`)

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

Siaran ini berlanjut ke `Sending`, atau kembali ke `Scheduled` jika `execution_date`-nya masih di masa mendatang. Hanya siaran `Paused` yang dapat dilanjutkan.

---

## Terus mengirim setelah jeda keterlibatan rendah

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

Saat siaran dikirim dalam batch, kami mengukur berapa banyak orang yang membalas setiap batch sebelum memulai batch berikutnya. Jika hampir tidak ada yang membalas, siaran akan menjeda dirinya sendiri — pengiriman yang terus dilakukan dalam keheningan adalah cara tercepat agar nomor difilter atau diblokir. Inilah tombol **Lanjutkan saja** di dasbor.

Karena tingkat balasan yang menyebabkan jeda tidak dapat berubah saat siaran dihentikan, [resume](#pause-and-resume) biasa hanya akan dijeda lagi oleh pemeriksaan berikutnya. Endpoint ini adalah keputusan untuk tetap melanjutkannya: ini mencatat penggantian (override) pada siaran tersebut, dan mencabut jeda dalam panggilan yang sama jika siaran dijeda karena keterlibatan rendah.

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

**Respons** (`200`)

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

- `resumed: true` — siaran dijeda karena keterlibatan rendah dan sekarang berjalan kembali; `status` adalah tempat siaran tersebut dilanjutkan.
- `resumed: false` — tidak ada yang dicabut, penggantian hanya dicatat untuk pemeriksaan di masa mendatang. Itulah yang Anda dapatkan jika siaran tidak pernah dijeda, atau dijeda karena alasan lain (Anda menjedanya secara manual, batas pengiriman tercapai, atau terlalu banyak pengiriman yang error). Jeda tersebut tidak dicabut di sini — lanjutkan sendiri setelah Anda mengatasi penyebabnya.

Penggantian hanya berlaku untuk siaran ini saja. Ini bukan pengaturan akun, dan aman untuk dipanggil dua kali.

---

## Menduplikasi siaran

`POST /broadcasts/{broadcastId}/duplicate` — menyalin audiens, pesan, dan pengaturan ke `Draft` baru. Segala sesuatu tentang proses sebelumnya (penghitung, batch, jadwal, statistik balasan) dimulai dari awal.

| Bidang | Wajib | Deskripsi |
|---|---|---|
| `to_channel` | Tidak | Buat salinan di saluran yang berbeda. Beginilah cara Anda mengirim hal yang sama di dua saluran — satu siaran hanya pernah memiliki satu saluran. |

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

**Respons** (`201`)

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

Salinan tidak pernah mewarisi persetujuan WhatsApp yang aktif: pada salinan WhatsApp, templat akan muncul dengan memerlukan konfirmasi Anda, dan pada salinan ke saluran lain, templat akan dihapus dan teks menjadi pembuka biasa. Menyalin ke SMS juga menghapus lampiran apa pun, karena SMS tidak dapat mengirimkannya.

---

## Menghapus siaran

`DELETE /broadcasts/{broadcastId}`

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

Siaran `Sending` atau `Scheduled` ditolak dengan `400` — jeda siaran tersebut terlebih dahulu.

---

## Siaran yang mencerminkan kampanye klasik

Kampanye klasik yang mengirimkan pesan juga muncul di Siaran, dan API mengembalikannya bersama siaran asli (ditandai dengan `source_campaign_id`). Perilakunya sedikit berbeda karena kampanye tetap memegang kendali:

- **Mengedit** audiens, pesan, atau jadwal dapat dilakukan dan akan diterapkan ke kampanye.
- **Saluran, agen balasan, lampiran, dan semua penghitung proses bersifat baca-saja (read-only)** di sini — `400` jika Anda mencoba mengubahnya. Ubahlah pada kampanye.
- **Luncurkan** mengembalikan `400` yang mengarahkan Anda ke editor kampanye.
- **Jeda dan lanjutkan** berfungsi dan memengaruhi kampanye.
- **Hapus** mengembalikan `400` — hapus kampanyenya saja, dan entri Siaran terkait akan ikut terhapus.
- **Duplikat** memberikan Anda siaran asli yang independen, yang merupakan cara yang didukung untuk memindahkan kampanye yang sudah terbukti.

---

## Kesalahan

Permintaan yang gagal mengembalikan `{"success": false, "error": "<message>"}` dengan status berikut:

| Status | Arti |
|---|---|
| `400` | Ada yang salah dengan permintaan atau status siaran — kolom yang hilang, lampiran tidak valid, atau peluncuran/jeda/lanjutkan/hapus yang tidak diizinkan dalam status siaran saat ini. Pesan `error` menyebutkan alasannya. |
| `401` | Kunci API hilang atau tidak valid. |
| `403` | Paket Anda tidak menyertakan akses API. |
| `404` | Tidak ada siaran seperti itu di akun Anda (atau, pada pemilihan templat, tidak ada templat tersebut). |
| `429` | Batas kecepatan tercapai. Tunggu sebentar dan coba lagi. |
| `500` | Terjadi kesalahan di pihak kami. Coba lagi setelah menunggu sebentar. |

---

## Langkah berikutnya

- [Panduan Siaran](../broadcasts/broadcasts.md) — produk di balik endpoint ini, termasuk perilaku pengaturan kecepatan dan keamanan
- [API Kontak](contacts.md) — membangun daftar tujuan pengiriman siaran
- [API Templat](templates.md) — mengelola templat WhatsApp yang disetujui yang dapat Anda pilih
- [API Webhook](webhooks.md) — berlangganan ke `Broadcast Started` dan `Broadcast Completed` alih-alih melakukan polling
