Kirim Pesan WhatsApp
Kirim pesan teks, media, lokasi, audio, video, reaksi, stiker, dan kartu kontak lewat API Chatera.
POST /v1/whatsapp/messagesScope yang dibutuhkan: whatsapp:send
Endpoint ini dipakai untuk mengirim semua jenis pesan WhatsApp: teks, gambar, dokumen, audio, video, lokasi, reaksi emoji, stiker, kartu kontak, template, dan pesan interaktif.
Semua path di halaman ini relatif terhadap base URL https://api.chatera.id/v1.
Aturan jendela 24 jam
Pesan teks, media, lokasi, interaktif, reaksi, stiker, dan kontak hanya bisa dikirim jika kontak telah mengirim pesan ke kamu dalam 24 jam terakhir. Untuk komunikasi proaktif di luar jendela ini, gunakan template WhatsApp yang sudah disetujui Meta.
Butuh waktu menyiapkan balasan?
Tampilkan status "mengetik…" di WhatsApp pelanggan dulu lewat Indikator Mengetik, lalu kirim balasan dengan endpoint ini.
Body request — field umum
Semua tipe pesan menggunakan field umum berikut:
| Field | Wajib | Tipe | Keterangan |
|---|---|---|---|
to | ✅ | string | Nomor tujuan (E.164) |
type | ✅ | string | text | image | audio | video | document | location | reaction | sticker | contacts | template | interactive |
channel_id | — | string (UUID) | ID saluran WhatsApp pengirim. Wajib jika kamu punya lebih dari satu saluran aktif. |
Tipe pesan
Teks
{
"to": "628123456789",
"type": "text",
"text": {
"body": "Halo, ini pesan dari API Chatera!",
"preview_url": false
}
}| Field | Wajib | Keterangan |
|---|---|---|
text.body | ✅ | Isi pesan, maks 4096 karakter |
text.preview_url | — | true untuk preview link otomatis (default false) |
Gambar
{
"to": "628123456789",
"type": "image",
"image": {
"link": "https://contoh.com/produk.jpg",
"caption": "Produk baru tersedia!"
}
}| Field | Wajib | Keterangan |
|---|---|---|
image.link | ✅ | URL HTTPS publik ke gambar (JPEG/PNG) |
image.caption | — | Caption di bawah gambar |
Audio
{
"to": "628123456789",
"type": "audio",
"audio": {
"link": "https://contoh.com/voicenote.ogg"
}
}Audio tidak mendukung caption.
Video
{
"to": "628123456789",
"type": "video",
"video": {
"link": "https://contoh.com/promo.mp4",
"caption": "Lihat video promo terbaru kami!"
}
}Dokumen
{
"to": "628123456789",
"type": "document",
"document": {
"link": "https://contoh.com/invoice.pdf",
"caption": "Invoice #ORD-12345",
"filename": "invoice-ord-12345.pdf"
}
}| Field | Wajib | Keterangan |
|---|---|---|
document.link | ✅ | URL HTTPS publik ke dokumen |
document.filename | ✅ | Nama file yang ditampilkan ke penerima |
document.caption | — | Caption di atas attachment |
Lokasi
{
"to": "628123456789",
"type": "location",
"location": {
"latitude": -6.2,
"longitude": 106.816666,
"name": "Kantor Chatera",
"address": "Jl. Contoh No. 123, Jakarta"
}
}name dan address opsional.
Mau minta pelanggan yang mengirim lokasinya? Pakai pesan interaktif Minta Lokasi.
Reaksi (reaction)
Beri reaksi emoji ke pesan tertentu di percakapan — pesan pelanggan maupun pesan kamu sendiri.
{
"to": "628123456789",
"type": "reaction",
"reaction": {
"message_id": "wamid.HBgNNjI4MTIzNDU2Nzg5FQIAEhgUM0E...",
"emoji": "👍"
}
}| Field | Wajib | Tipe | Keterangan |
|---|---|---|---|
reaction.message_id | ✅ | string | ID pesan yang direaksikan: wamid.xxx dari Meta, atau UUID pesan Chatera (mis. messageId dari webhook / response kirim) |
reaction.emoji | ✅ | string | Satu emoji. Kirim string kosong "" untuk menghapus reaksi |
Kalau kamu memakai UUID pesan Chatera, Chatera mencarikan wamid-nya
dulu. Pesan yang tidak ditemukan (atau belum punya wamid) ditolak
dengan VALIDATION_INVALID_FIELD (details.field: "reaction.message_id").
Stiker (sticker)
{
"to": "628123456789",
"type": "sticker",
"sticker": {
"link": "https://contoh.com/stiker/terima-kasih.webp"
}
}| Field | Wajib | Tipe | Keterangan |
|---|---|---|---|
sticker.id | salah satu ✅ | string | ID media yang sudah di-upload ke Meta |
sticker.link | salah satu ✅ | string | URL HTTPS publik ke file stiker |
Stiker wajib WebP
Meta hanya menerima stiker berformat WebP: stiker statis maks
100 KB, stiker animasi maks 500 KB. Format lain atau file yang
lebih besar akan ditolak Meta (biasanya dilaporkan lewat webhook
message.failed).
Kartu kontak (contacts)
Kirim satu atau beberapa kartu kontak (vCard) yang bisa langsung disimpan pelanggan.
{
"to": "628123456789",
"type": "contacts",
"contacts": [
{
"name": { "formatted_name": "Budi Santoso", "first_name": "Budi" },
"phones": [
{ "phone": "+628123456789", "type": "CELL", "wa_id": "628123456789" }
]
}
]
}| Field | Wajib | Tipe | Keterangan |
|---|---|---|---|
contacts | ✅ | array | Minimal 1 kartu kontak |
contacts[].name.formatted_name | ✅ | string | Nama lengkap yang ditampilkan |
contacts[].name.first_name / last_name | ✅ (salah satu) | string | Nama depan / belakang. Minimal salah satu wajib — tanpa ini Meta menolak dengan #131009 |
contacts[].phones[] | — | array | { phone, type, wa_id }. type mis. CELL, WORK, HOME. Isi wa_id supaya muncul tombol Kirim pesan di WhatsApp |
contacts[].emails[] | — | array | { email, type } |
contacts[].org | — | object | { company, title } |
contacts[].urls[] | — | array | { url, type } |
Field lain yang didukung Meta (mis. addresses, birthday) diteruskan
apa adanya.
Validasi reaksi, stiker, dan kontak
Field yang kurang di tiga tipe ini ditolak sebelum dikirim ke Meta
dengan VALIDATION_INVALID_FIELD (HTTP 400). Detail tiap field ada di
details.errors[], mis. { "field": "contacts[0].name.formatted_name", "message": "Each contact requires name.formatted_name" }.
Multi-channel: memilih saluran pengirim
Jika organisasi kamu punya lebih dari satu saluran WhatsApp aktif,
sertakan channel_id untuk memilih saluran pengirim:
{
"to": "628123456789",
"type": "text",
"channel_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"text": { "body": "Halo dari channel sales!" }
}Cara mendapatkan channel_id:
- Dari payload webhook (
data.channelId). - Dari halaman Pengaturan > Saluran di dashboard.
Jika channel_id tidak disertakan dan kamu hanya punya satu saluran
aktif, saluran tersebut otomatis dipakai. Jika punya beberapa saluran
aktif tanpa channel_id, request ditolak dengan error
VALIDATION_MISSING_FIELD (details.field: "channel_id") supaya pesan
tidak terkirim dari nomor yang salah.
Response
{
"success": true,
"data": {
"messageId": "9b8c1234-e5f6-4789-90ab-cdef01234567",
"whatsappMessageId": "wamid.HBgNNjI4MTIzNDU2Nzg5FQIAERgSRDM0NEU3RkY1...",
"status": "sent",
"to": "+628123456789",
"timestamp": "2026-04-27T10:51:33.228Z"
}
}| Field | Keterangan |
|---|---|
messageId | ID pesan di Chatera (UUID) — pakai untuk lookup di webhook |
whatsappMessageId | ID dari Meta (wamid.xxx) |
status | sent (artinya diterima oleh server WhatsApp Cloud API; status delivered & read dikirim via webhook) |
to | Nomor tujuan dalam E.164 (dengan +) |
timestamp | Waktu kirim (ISO 8601) |
Pesan error
| Kode | Penyebab | Solusi |
|---|---|---|
VALIDATION_INVALID_PHONE | Format to salah | Pakai E.164 |
VALIDATION_MISSING_FIELD | to atau type kosong, atau channel_id kosong padahal kamu punya lebih dari satu saluran aktif | Lengkapi field wajib (lihat details.field) |
VALIDATION_INVALID_FIELD | Field reaction / sticker / contacts tidak lengkap, atau reaction.message_id (UUID Chatera) tidak ditemukan | Lihat details.errors[] atau details.field |
WHATSAPP_SESSION_CLOSED | Di luar jendela 24 jam (berlaku juga untuk reaksi, stiker, dan kontak) | Pakai template |
WHATSAPP_CHANNEL_NOT_FOUND | channel_id tidak valid / tidak aktif, atau belum ada saluran WhatsApp aktif | Cek saluran di dashboard |
WHATSAPP_SEND_FAILED | Meta menolak request | Lihat details untuk detail. Coba lagi setelah beberapa saat. |
Limit ukuran media
Meta WhatsApp Cloud API membatasi ukuran media:
- Gambar: 5 MB
- Stiker (WebP): 100 KB statis, 500 KB animasi
- Audio: 16 MB
- Video: 16 MB
- Dokumen: 100 MB
URL kamu harus dapat di-fetch oleh server Meta — pastikan tidak di
belakang IP whitelist atau autentikasi.
Kalau Meta gagal mengambil media, pesan tetap diterima di awal lalu
dilaporkan gagal lewat webhook message.failed.