Kirim Pesan WhatsApp via API: Contoh cURL, Node, Python, PHP
Cara mengirim pesan WhatsApp dengan API: contoh cURL, Node.js, Python, dan PHP yang berfungsi untuk template dan pesan sesi, plus pelacakan status dan error.
Oleh OmniChannels.ai Editorial Team · Ditinjau oleh BroadNet Messaging Solutions Team
Integrasi
Jawaban singkat
Dengan API OmniChannels.ai, Anda mengirim setiap pesan WhatsApp melalui satu endpoint, POST https://api.broadnet.me/whatsapp/message/sendbulk, sebagai multipart form data dengan header Authorization: Bearer. Field messageType memilih payload: TEMPLATE untuk template yang disetujui, yang Anda butuhkan untuk memulai percakapan atau menulis di luar jendela 24 jam, dan TEXT, IMAGE, atau INTERACTIVE untuk balasan di dalam jendela tersebut.
Di halaman ini
- Bagaimana cara mengirim pesan WhatsApp melalui API?
- Template atau pesan sesi: mana yang dikirim?
- Bagaimana cara mengirim template yang disetujui?
- Field request mana yang paling penting?
- Bagaimana mengirim template dengan tombol atau OTP?
- Bagaimana membalas di dalam jendela layanan pelanggan?
- Bagaimana melacak pengiriman?
- Error apa yang harus ditangani?
- Contoh kasus: layanan notifikasi pesanan
- Apa saja kesalahan umum?
- Bagaimana OmniChannels.ai membantu
Poin penting
- Semua pesan WhatsApp melalui POST /whatsapp/message/sendbulk; messageType (TEMPLATE, TEXT, IMAGE, INTERACTIVE, dan lainnya) menentukan field mana yang wajib.
- Request-nya multipart/form-data, bukan JSON, jadi Python membutuhkan files= dan PHP membutuhkan body berupa array agar tidak ter-encode sebagai url-encoded.
- Di luar jendela layanan pelanggan 24 jam hanya template yang disetujui yang dapat dikirim; di dalamnya Anda dapat mengirim teks bebas, media, dan pesan interaktif.
- Panggilan ini mengantrekan pesan dan langsung mengembalikan batchId; status per penerima tiba di webhook Anda dan dari endpoint bulk-insights.
- API tidak menerima idempotency key, jadi catat setiap pengiriman sebelum Anda melakukannya dan periksa status setelah timeout alih-alih mengirim ulang.
Panduan ini ditujukan bagi developer yang mengintegrasikan pengiriman WhatsApp ke dalam aplikasi. Panduan ini menunjukkan request yang berfungsi dalam cURL, Node.js, Python, dan PHP, menjelaskan perbedaan pesan template dan pesan sesi, serta membahas pelacakan dan error. Setiap endpoint dan field berasal dari referensi WhatsApp API dan spesifikasi OpenAPI kami.
Bagaimana cara mengirim pesan WhatsApp melalui API?
Anda melakukan satu POST terautentikasi ke https://api.broadnet.me/whatsapp/message/sendbulk dengan field form. Field messageType memilih jenis pesan, dan responsnya mengonfirmasi bahwa pesan telah diantrekan.
| Item | Nilai |
|---|---|
| Base URL | https://api.broadnet.me (tanpa awalan /v1) |
| Endpoint | POST /whatsapp/message/sendbulk |
| Autentikasi | Authorization: Bearer $BROADNET_TOKEN |
| Content type | multipart/form-data (diatur otomatis oleh klien HTTP Anda) |
| Respons | Ringkasan batch JSON dengan batchId |
Kredensial uji diterbitkan setelah permintaan akses singkat, dan pengiriman uji dikirim ke nomor terverifikasi milik Anda sendiri. Lihat quickstart dan halaman autentikasi. Simpan token hanya di server Anda.
Template atau pesan sesi: mana yang dikirim?
Kirim template untuk memulai percakapan atau menulis di luar jendela, dan pesan sesi jika pelanggan menulis kepada Anda dalam 24 jam terakhir. Aturan ini ditetapkan oleh Meta, bukan oleh kami.
| Pesan template | Pesan sesi | |
|---|---|---|
messageType |
TEMPLATE |
TEXT, IMAGE, VIDEO, AUDIO, DOCUMENT, INTERACTIVE, dan lainnya |
| Kapan diizinkan | Kapan saja, setelah template disetujui | Hanya saat jendela layanan pelanggan terbuka |
| Perlu persetujuan | Ya, oleh Meta | Tidak |
| Penggunaan umum | Pembaruan pesanan, OTP, pengingat, kampanye | Balasan dukungan, jawaban atas pertanyaan |
Meta menagih per pesan terkirim menurut kategori, dan aturannya untuk pesan layanan dan template utilitas (utility) berubah pada 1 Oktober 2026. Panduan jendela kami membahas mekanismenya, dan halaman harga serta kalkulator kami membahas biayanya.
Bagaimana cara mengirim template yang disetujui?
Atur messageType=TEMPLATE, sebutkan nama template dan kode bahasanya, lalu berikan nilai variabel. Buat batchId=0 untuk memulai batch baru.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F campaignName=order-updates \
-F destinationNo=971500000000 \
-F messageType=TEMPLATE \
-F templateName=order_update \
-F templateLanguage=en_US \
-F bodyTemplateVariables=INV-400
// Node.js 18+ (fetch dan FormData bawaan)
const form = new FormData();
form.append("batchId", "0");
form.append("campaignName", "order-updates");
form.append("destinationNo", "971500000000");
form.append("messageType", "TEMPLATE");
form.append("templateName", "order_update");
form.append("templateLanguage", "en_US");
form.append("bodyTemplateVariables", "INV-400");
const res = await fetch("https://api.broadnet.me/whatsapp/message/sendbulk", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.BROADNET_TOKEN}` }, // fetch mengatur boundary multipart
body: form,
});
console.log(await res.json());
import os
import requests
fields = {
"batchId": "0",
"campaignName": "order-updates",
"destinationNo": "971500000000",
"messageType": "TEMPLATE",
"templateName": "order_update",
"templateLanguage": "en_US",
"bodyTemplateVariables": "INV-400",
}
# Kirim setiap field sebagai bagian multipart (files=), bukan url-encoded (data=).
r = requests.post(
"https://api.broadnet.me/whatsapp/message/sendbulk",
headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
files={k: (None, v) for k, v in fields.items()},
timeout=30,
)
print(r.json())
<?php
$ch = curl_init("https://api.broadnet.me/whatsapp/message/sendbulk");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BROADNET_TOKEN")],
// Array (bukan string) membuat cURL mengirim multipart/form-data.
CURLOPT_POSTFIELDS => [
"batchId" => "0",
"campaignName" => "order-updates",
"destinationNo" => "971500000000",
"messageType" => "TEMPLATE",
"templateName" => "order_update",
"templateLanguage" => "en_US",
"bodyTemplateVariables" => "INV-400",
],
]);
echo curl_exec($ch);
curl_close($ch);
Tujuan berupa kode negara ditambah nomor, hanya angka. Panggilan ini langsung kembali dengan ringkasan batch:
{
"totalFiles": 1,
"totalSuccess": 1,
"totalFailed": 0,
"totalDuplicates": 0,
"batchId": "2609091405000000001",
"fileResults": [
{
"fileName": "direct",
"totalRecords": 1,
"successCount": 1,
"failedRecipients": [],
"duplicateRecipients": []
}
],
"message": "Messages queued for delivery"
}
Simpan batchId di samping catatan Anda sendiri. "Diantrekan" bukan "terkirim".
Field request mana yang paling penting?
Field mana yang wajib bergantung pada messageType. Berikut yang umum.
| Field | Wajib | Deskripsi |
|---|---|---|
messageType |
Ya | TEXT, IMAGE, VIDEO, AUDIO, DOCUMENT, STICKER, LOCATION, CONTACTS, TEMPLATE, INTERACTIVE, REACTION, atau FLOW |
destinationNo atau destinationFiles |
Salah satu dari keduanya | Nomor yang dipisahkan koma, titik koma, atau baris baru; atau file TXT, CSV, atau XLSX |
batchId |
Tidak | 0 memulai batch baru |
campaignName |
Tidak | Label Anda untuk pelaporan |
allowDuplicate |
Tidak | false menghapus penerima duplikat |
templateName, templateLanguage |
Untuk TEMPLATE |
Nama template yang disetujui dan kode bahasanya, seperti en_US atau ar |
bodyTemplateVariables |
Sesuai template | Nilai variabel body; parameter bernama diberikan sebagai JSON |
buttonsTemplateVariable |
Sesuai template | Nilai tombol dinamis: akhiran URL, kode kupon, atau kode OTP |
content |
Untuk TEXT |
Isi teks, hingga 4.096 karakter, atau caption untuk media |
mediaUrl |
Sesuai tipe | URL HTTPS publik dari media |
interactivePayload |
Untuk INTERACTIVE |
Objek interaktif Meta sebagai string JSON |
Penjadwalan memakai scheduled, scheduleTime, dan gmt, dan delay mengatur laju pengiriman. Daftar lengkapnya ada di referensi WhatsApp API.
Bagaimana mengirim template dengan tombol atau OTP?
Tambahkan nilai tombol di buttonsTemplateVariable. Untuk template autentikasi dengan tombol salin kode, berikan kode itu di field body maupun field tombol.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=TEMPLATE \
-F templateName=login_code \
-F templateLanguage=en_US \
-F bodyTemplateVariables=482913 \
-F buttonsTemplateVariable=482913
Di sini login_code adalah placeholder untuk template autentikasi Anda sendiri yang sudah disetujui. Untuk beberapa tombol, buttonsTemplateVariable menerima array JSON. Buat kode di server Anda, simpan dalam bentuk hash dengan masa berlaku, dan jangan pernah mencatatnya di log. Panduan OTP kami membahas pengiriman one-tap, zero-tap, dan salin kode.
Bagaimana membalas di dalam jendela layanan pelanggan?
Gunakan tipe pesan sesi. Balasan teks biasa membutuhkan messageType=TEXT dan content.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=TEXT \
-F campaignName=support \
-F "content=Your order has shipped. Reply here if you need anything."
Untuk tombol balasan, kirim messageType=INTERACTIVE dan interactivePayload yang mengikuti format pesan interaktif Meta.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=INTERACTIVE \
-F campaignName=support \
-F 'interactivePayload={"type":"button","body":{"text":"Confirm your delivery slot?"},"action":{"buttons":[{"type":"reply","reply":{"id":"slot_ok","title":"Confirm"}},{"type":"reply","reply":{"id":"slot_change","title":"Change"}}]}}'
Untuk menandai pesan masuk sebagai sudah dibaca, dan secara opsional menampilkan indikator mengetik, panggil POST /whatsapp/message/read dengan JSON:
curl -X POST https://api.broadnet.me/whatsapp/message/read \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "messageId": "wamid.HBgMOTcxNTAwMDAwMDAwFQIAEhgg", "typing": true }'
Lihat panduan kami tentang pesan interaktif untuk arahan desain.
Bagaimana melacak pengiriman?
Status dikirim (push) ke webhook yang dikonfigurasi di akun Anda dan juga dapat dibaca per batch. Setiap penerima bergerak melalui SUBMITTED, SENT, DELIVERED, dan READ, atau berakhir sebagai FAILED atau REJECTED beserta alasannya.
curl "https://api.broadnet.me/whatsapp/message/bulk-insights?batch_Id=2609091405000000001&status=FAILED&page=0&size=50" \
-H "Authorization: Bearer $BROADNET_TOKEN"
batch_Id wajib; status, destination, search, page, dan size opsional, dan page dimulai dari nol. Gunakan polling sebagai cadangan untuk event yang terlewat, dan bangun penerima Anda seperti dijelaskan di panduan webhook kami. Batch juga dapat dijeda, dilanjutkan, dan dibatalkan dengan endpoint batch dalam referensi.
Error apa yang harus ditangani?
Baca status HTTP terlebih dahulu, lalu body error. API memunculkan error dalam body JSON lima field, dan kegagalan khusus WhatsApp dapat berasal dari Meta.
| Status | Arti | Tindakan |
|---|---|---|
400 |
Error validasi, seperti field khusus tipe yang hilang atau tujuan tidak valid | Perbaiki request; jangan ulangi tanpa perubahan |
401 / 403 |
Token hilang atau tidak valid, atau operasi tidak diizinkan | Perbaiki token atau minta kami mengaktifkan operasinya |
404 |
Template atau sender tidak ditemukan | Periksa nama dan bahasa template |
413 |
File yang diunggah terlalu besar | Perkecil file |
429 |
Batas laju | Tunggu Retry-After |
502 |
Meta menolak panggilan; message memuat kode dan teks error Meta |
Baca; ulangi hanya jika bersifat sementara |
500, 503, 504 |
Masalah server atau upstream | Ulangi dengan exponential backoff dan jitter |
Panduan kode error kami menjelaskan kode Meta yang umum. Karena tidak ada idempotency key, ikuti langkah perlindungan duplikasi di Error dan batas: tulis catatan pending terlebih dahulu, simpan batchId yang dikembalikan, dan setelah timeout periksa status sebelum mengirim lagi.
Contoh kasus: layanan notifikasi pesanan
"Souq Rafiq" (fiktif), pengecer di UEA, mengirim template order_update saat pesanan dikirim.
- Layanan pesanan menulis baris dengan kunci
order-8842-shippedberstatuspending. - Layanan memanggil
sendbulkdengan template dan nomor pesanan sebagaibodyTemplateVariables. - Pada
200, layanan menyimpanbatchIddan menandai barisaccepted. - Handler webhook memperbarui baris menjadi
DELIVEREDatauREAD, atauFAILEDbeserta alasannya. - Jika pelanggan membalas, alat dukungan memakai pesan sesi
TEXTdi dalam jendela. - Job malam hari membaca
bulk-insightsuntuk batch kemarin dan merekonsiliasi status yang hilang.
Apa saja kesalahan umum?
- Mengirim JSON. Endpoint pengiriman WhatsApp memakai multipart;
Content-Type: application/jsontidak akan berfungsi. data=di Python alih-alihfiles=, yang meng-encode form sebagai url-encoded.- Teks bebas di luar jendela, yang gagal. Gunakan template.
- Kode bahasa yang salah, seperti
enalih-alihen_USmilik template. - Menganggap
200sebagai terkirim. Artinya diantrekan. - Pengulangan buta setelah timeout, yang dapat mengirim pesan dua kali kepada pelanggan.
- Token di kode sisi klien. Panggil API hanya dari backend Anda.
- Batasan: detail payload bervariasi menurut template. Konfirmasikan tata letak variabel untuk kampanye personal pertama Anda bersama tim kami.
Bagaimana OmniChannels.ai membantu
BroadNet adalah Meta Business Solution Provider resmi, dan onboarding ke WhatsApp Business API memakai Meta Embedded Signup; tim kami menyiapkan registrasi bersama Anda, sementara persetujuan tetap di tangan Meta. REST API didokumentasikan dengan spesifikasi OpenAPI 3.1 dan SDK TypeScript, @broadnet/cpaas-sdk, dan status pengiriman dinormalisasi di semua kanal. Mulailah dengan dokumentasi WhatsApp API atau quickstart.
Pertanyaan yang sering diajukan
Apakah pesan WhatsApp dikirim sebagai JSON atau form data?
Form data. Endpoint pengiriman WhatsApp, POST /whatsapp/message/sendbulk, menerima multipart/form-data, dengan setiap field sebagai bagian form. Pengiriman SMS tunggal memakai JSON, yang sering menjadi sumber kebingungan. Di Python kirim field melalui files=, bukan data=, dan di PHP berikan array sebagai body agar cURL membangun multipart.
Bisakah saya mengirim pesan WhatsApp tanpa template?
Hanya di dalam jendela layanan pelanggan. Saat pelanggan mengirim pesan kepada Anda, jendela 24 jam terbuka dan Anda dapat membalas dengan teks, media, atau pesan interaktif. Di luar jendela itu, atau untuk memulai percakapan, Anda harus mengirim template yang disetujui. API menegakkan aturan Meta, dan pengiriman teks bebas ke jendela yang tertutup akan gagal.
Bagaimana saya tahu apakah pesan terkirim?
Panggilan pengiriman hanya mengonfirmasi bahwa pesan telah diantrekan dan mengembalikan batchId. Status per penerima bergerak melalui SUBMITTED, SENT, DELIVERED, dan READ, atau berakhir sebagai FAILED atau REJECTED. Status dikirim (push) ke webhook Anda, dan Anda juga dapat membacanya per batch dari endpoint bulk-insights.
Bisakah saya mengirim ke banyak penerima dalam satu request?
Bisa. destinationNo menerima beberapa nomor yang dipisahkan koma, titik koma, atau baris baru, dan destinationFiles menerima file TXT, CSV, atau XLSX. Untuk template dengan variabel berbeda per penerima, unggah file yang dipersonalisasi dengan satu baris per penerima. Atur allowDuplicate ke false untuk menghapus nomor duplikat.
Apakah ada idempotency key untuk mencegah pengiriman ganda?
Tidak. API tidak menerima idempotency key. Jika request mengalami timeout, Anda tidak dapat mengetahui dari sisi klien apakah request diterima. Catat setiap pengiriman di database Anda sendiri sebelum memanggil, simpan batchId yang dikembalikan, dan periksa status atau daftar batch sebelum mengulang.
Apakah saya perlu opt-in sebelum mengirim?
Ya. Kebijakan Meta mensyaratkan setiap penerima telah opt-in untuk menerima pesan dari bisnis Anda, dan template harus disetujui sebelum dipakai. API tidak memeriksa persetujuan untuk Anda. Kumpulkan opt-in di sumbernya, simpan buktinya, dan tekan (suppress) siapa pun yang berhenti berlangganan.
Sumber
Lanjut membaca
Panduan lainnyaIntegrasi
Panduan Webhook WhatsApp: Event, Keamanan, dan Retry
Cara kerja webhook WhatsApp: event pesan dan status, handler yang andal, pemeriksaan tanda tangan Meta, retry, idempotensi, dan pemulihan saat event hilang.
10 menit baca
Integrasi
Kirim SMS via API: Contoh Python, Node.js, PHP, dan cURL
Kirim SMS dengan API di Python, Node.js, PHP, dan cURL: pengiriman tunggal dan massal, Unicode dan Arab, hitung segmen, webhook status, dan penanganan error.
10 menit baca
WhatsApp
OTP WhatsApp vs OTP SMS: Biaya, Pengiriman, dan Fallback
Perbandingan OTP WhatsApp vs OTP SMS: model biaya, pengiriman, pengalaman pengguna, template autentikasi, fallback WhatsApp ke SMS, dan kontrol fraud.
10 menit baca
