Sign inGet started

Carousel media WhatsApp

Carousel media adalah sekumpulan dua hingga sepuluh kartu yang digeser penerima secara berdampingan, masing-masing dengan gambar atau video, teks pendek, dan tombol sendiri. Gunakan carousel untuk menampilkan beberapa item sekaligus, misalnya beberapa produk, alih-alih mengirim satu pesan per item.
Atur interactive.type ke carousel, dengan body_text di level pesan dan array cards berisi 2 hingga 10 entri:
const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  interactive: {
    type: "carousel",
    body_text: "Here are two of our latest arrivals, each under $25:",
    cards: [
      {
        header: { type: "image", url: "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/blue-echeveria" },
          },
        ],
      },
      {
        header: { type: "image", url: "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/zebra-haworthia" },
          },
        ],
      },
    ],
  },
});
console.log(msg.id, msg.status);
from wajib ada di setiap pesan layanan: nomor milik workspace Anda, bukan nomor yang dikelola Bird. Bentuk lengkapnya menambahkan teks kartu sendiri, tombol quick-reply kedua, dan kutipan pesan sebelumnya:
Contoh kode
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive": {
    "type": "carousel",
    "body_text": "Here are two of our latest arrivals, each under $25:",
    "cards": [
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        "body_text": "Blue Echeveria. Powdery blue leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-echeveria", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-echeveria", "text": "Details" } }
        ]
      },
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        "body_text": "Zebra Haworthia. White stripes on deep green leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-haworthia", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-haworthia", "text": "Details" } }
        ]
      }
    ]
  },
  "tags": [{ "name": "category", "value": "catalog" }],
  "metadata": { "order_id": "A-1" }
}
in_reply_to_message_id mengutip pesan sebelumnya dalam percakapan yang sama. Lihat bagian mengutip pesan untuk mengorelasikan balasan di hub untuk cara resolusi bekerja dan apa yang bisa terlewat.
Carousel tidak memiliki header level pesan maupun footer: body_text pesan adalah satu-satunya teks di atas kartu. Lihat bagian tombol di hub untuk bentuk tombol bersama yang digunakan kembali oleh kartu tipe ini.

Kartu

Setiap kartu memiliki header media, teks pendek, dan tombol sendiri:
  • header wajib ada di setiap kartu, dan nilainya hanya image atau video: tidak ada header teks maupun dokumen, berbeda dengan tipe interaktif lainnya.
  • body_text bersifat opsional. Letaknya di bawah media kartu, lebih pendek dari body pesan, dan mengizinkan maksimal dua jeda baris.
  • buttons wajib ada: satu tombol cta_url atau hingga tiga tombol quick_reply, tidak boleh dicampur dalam satu kartu.
Kartu ditampilkan dari kiri ke kanan sesuai urutan kemunculannya di array cards. Kartu tidak memiliki footer maupun field indeks sendiri; posisinya di array adalah posisinya di carousel.

Setiap kartu memiliki tombol yang sama

Setiap kartu dalam carousel harus memiliki tipe tombol yang sama, jumlah yang sama, dalam urutan yang sama. Carousel di mana kartu 1 memiliki satu tombol cta_url dan kartu 2 memiliki dua tombol quick_reply akan ditolak, begitu pula carousel di mana setiap kartu memiliki dua tombol quick_reply tetapi dalam urutan berbeda.
Alasannya adalah cara WhatsApp merender pesan: carousel adalah satu tampilan kartu dengan layout bersama, bukan sekumpulan kartu dengan layout masing-masing. Kartu dengan baris tombol berbeda akan merusak layout bersama tersebut, sehingga WhatsApp mengharuskan setiap kartu cocok dan Bird memeriksanya sebelum pengiriman dibuat atau dikenakan biaya. Ketidakcocokan menghasilkan E15059.
Label tombol adalah aturan terpisah, dan cakupannya berbeda: label harus unik dalam satu kartu, bukan di seluruh carousel. "Buy now" di setiap satu dari sepuluh kartu tidak masalah; "Buy now" dua kali di kartu yang sama menghasilkan E15056.

Batas

FieldBatas
cards2 hingga 10 entri
Card headerwajib di setiap kartu; hanya image atau video
Card header.urlwajib, tanpa panjang maksimum
Card body_textopsional, 1 hingga 160 karakter, maksimal 2 jeda baris
Card buttons1 hingga 3 entri: satu cta_url, atau hingga tiga quick_reply, tidak boleh dicampur
Label tombol (quick_reply.text, cta_url.text)wajib, 1 hingga 20 karakter, unik dalam satu kartu
quick_reply.slugwajib, 1 hingga 256 karakter
cta_url.urlwajib, 1 hingga 2.000 karakter
Message body_textwajib, 1 hingga 1.024 karakter
Header pesan, footertidak diizinkan pada carousel: tidak ada header, tidak ada footer_text
Bird membatasi tombol quick_reply menjadi tiga per kartu. Meta sendiri tidak menyebutkan batas numerik, hanya menyatakan bahwa kartu menerima satu tombol link atau satu atau lebih tombol reply, sehingga batas ini milik Bird, bukan WhatsApp.

Membaca balasan

Hanya tombol quick_reply pada kartu yang menghasilkan balasan. Ketukan pada tombol tersebut masuk sebagai pesan inbound tersendiri, membawa interactive_reply:
Contoh kode
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+16505551234" },
  "to": { "phone_number": "+13124495648" },
  "status": "received",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive_reply": {
    "type": "button",
    "button": {
      "slug": "buy-echeveria",
      "text": "Buy"
    }
  },
  "created_at": "2026-08-25T09:04:11Z"
}
slug yang Anda atur pada tombol yang diketuk dikembalikan persis sama pada interactive_reply.button.slug, bentuk yang sama seperti ketukan reply-buttons. Anda melihat balasan ini melalui daftar pesan atau GET /v1/whatsapp/messages/{id}; lihat bagian membaca balasan di hub untuk alur lengkapnya.
Tombol cta_url pada kartu membuka link-nya di browser penerima dan tidak mengirim apa pun kembali, sama seperti tombol link mandiri.
Halaman ini membahas carousel free-form yang Anda kirim secara inline dengan interactive.type: "carousel", hanya dapat dikirim di dalam jendela layanan pelanggan yang terbuka dan tidak pernah ditinjau oleh Meta. Template WhatsApp memiliki carousel terpisah: komponen template yang dibuat sekali, diajukan ke Meta untuk persetujuan, dan dikirim berdasarkan slug seperti template lainnya, termasuk di luar jendela. Keduanya berbagi kata "carousel" dan rentang 2-hingga-10 kartu dari Meta, dan tidak ada kesamaan lain: bentuk wire berbeda, jalur peninjauan berbeda, dan jumlah kartu carousel template ditetapkan saat persetujuan template, bukan dipilih per pengiriman. Jika Anda menelusuri template dan melihat "carousel" di sana, itu adalah tipe template, bukan halaman ini.

Batas dan kasus khusus

  • Jendela layanan pelanggan harus terbuka. Carousel adalah pesan layanan, hanya dapat dikirim di dalam jendela yang terbuka; lihat bagian jendela layanan pelanggan di hub. Pemeriksaan jendela bersifat fails open, sehingga 202 bukan bukti bahwa jendela benar-benar terbuka saat pengiriman berlangsung.
  • from harus berupa nomor milik workspace Anda. Menghilangkannya, atau menyebutkan nomor yang bukan sender terhubung, akan ditolak sebelum pengiriman dibuat.
  • Media kartu harus dapat diakses publik saat pengiriman diproses. Bird tidak menyimpan atau mem-proxy file: WhatsApp mengambil url setiap kartu sendiri, pada saat pengiriman, sehingga signed URL harus tetap berlaku lebih lama dari pengiriman.
  • URL media kartu yang tidak dapat diambil WhatsApp akan diterima, lalu gagal secara asinkron, dan tetap dikenakan biaya. Validasi permintaan Bird hanya memeriksa bahwa url kartu adalah URI yang valid secara format, bukan apakah WhatsApp dapat menjangkaunya atau apakah menggunakan https. File terlalu besar, 404, host tidak dapat di-resolve, atau tipe file salah semuanya dikembalikan sebagai 202 saat diterima, lalu whatsapp.accepted lalu whatsapp.sent lalu whatsapp.failed, dengan media_rejected pada last_error pesan dan biaya pengiriman sudah dikenakan tanpa jalur pengembalian dana. Uji setiap URL kartu sebelum mengirim, karena URL yang rusak tidak terdeteksi sampai setelahnya.
  • Setiap kartu harus memiliki tombol yang sama. Lihat Setiap kartu memiliki tombol yang sama di atas; ini adalah satu-satunya aturan carousel yang tidak dapat dinyatakan oleh skema permintaan sendiri, sehingga diperiksa secara terpisah dan menghasilkan E15059 alih-alih error validasi generik.
  • Tidak ada header atau footer level pesan. Satu-satunya teks di atas kartu pada carousel adalah body_text; tidak ada tempat untuk meletakkan catatan kecil seperti yang digunakan tipe lain pada footer_text.
  • Balasan tidak menyertakan indeks kartu. Ketukan quick_reply kartu hanya melaporkan {slug, text}, bentuk yang sama seperti ketukan reply-buttons, tanpa field yang menyebutkan kartu mana asalnya. Jika Anda perlu mengetahui kartu mana yang diketuk, encode kartu di slug setiap tombol, misalnya buy-echeveria alih-alih buy saja.
  • Tombol cta_url pada kartu tidak menghasilkan event inbound. Jika Anda perlu mengetahui bahwa kartu berinteraksi, gunakan tombol quick_reply pada kartu tersebut, atau lacak klik di URL tujuan Anda sendiri.
Selain E15059, satu-satunya error interaktif khusus carousel adalah E15056 untuk label tombol yang berulang pada satu kartu. Kutipan yang tidak ter-resolve akan menggagalkan permintaan sebelum apa pun dibuat atau dikenakan biaya: 404 E15071 ketika id menyebutkan pesan yang tidak dimiliki workspace ini, 422 E15072 ketika menyebutkan pesan yang tidak dapat dikutip. Untuk error yang dapat terjadi pada pengiriman WhatsApp mana pun, jendela tertutup, sender yang hilang atau tidak valid, atau penerima yang tidak valid, lihat bagian error dan Mengirim pesan WhatsApp di hub.

Langkah selanjutnya