Chatera Docs
API & Integrasi

Kirim Pesan WhatsApp

Kirim pesan teks, media, lokasi, audio, video, reaksi, stiker, dan kartu kontak lewat API Chatera.

POST /v1/whatsapp/messages

Scope 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:

FieldWajibTipeKeterangan
to✅stringNomor tujuan (E.164)
type✅stringtext | 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
  }
}
FieldWajibKeterangan
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!"
  }
}
FieldWajibKeterangan
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"
  }
}
FieldWajibKeterangan
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": "👍"
  }
}
FieldWajibTipeKeterangan
reaction.message_id✅stringID pesan yang direaksikan: wamid.xxx dari Meta, atau UUID pesan Chatera (mis. messageId dari webhook / response kirim)
reaction.emoji✅stringSatu 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"
  }
}
FieldWajibTipeKeterangan
sticker.idsalah satu ✅stringID media yang sudah di-upload ke Meta
sticker.linksalah satu ✅stringURL 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" }
      ]
    }
  ]
}
FieldWajibTipeKeterangan
contacts✅arrayMinimal 1 kartu kontak
contacts[].name.formatted_name✅stringNama lengkap yang ditampilkan
contacts[].name.first_name / last_name✅ (salah satu)stringNama 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"
  }
}
FieldKeterangan
messageIdID pesan di Chatera (UUID) — pakai untuk lookup di webhook
whatsappMessageIdID dari Meta (wamid.xxx)
statussent (artinya diterima oleh server WhatsApp Cloud API; status delivered & read dikirim via webhook)
toNomor tujuan dalam E.164 (dengan +)
timestampWaktu kirim (ISO 8601)

Pesan error

KodePenyebabSolusi
VALIDATION_INVALID_PHONEFormat to salahPakai E.164
VALIDATION_MISSING_FIELDto atau type kosong, atau channel_id kosong padahal kamu punya lebih dari satu saluran aktifLengkapi field wajib (lihat details.field)
VALIDATION_INVALID_FIELDField reaction / sticker / contacts tidak lengkap, atau reaction.message_id (UUID Chatera) tidak ditemukanLihat details.errors[] atau details.field
WHATSAPP_SESSION_CLOSEDDi luar jendela 24 jam (berlaku juga untuk reaksi, stiker, dan kontak)Pakai template
WHATSAPP_CHANNEL_NOT_FOUNDchannel_id tidak valid / tidak aktif, atau belum ada saluran WhatsApp aktifCek saluran di dashboard
WHATSAPP_SEND_FAILEDMeta menolak requestLihat 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.

On this page