Lewati ke konten utama

Kirim satu pesan

POST /api/messages, izin write:messages. Satu pesan ke satu pelanggan WhatsApp, dijawab dengan id pesan yang terbentuk. Cocok untuk pengingat janji, status pesanan, atau hasil laboratorium yang dikirim dari sistem Anda.

Pesan berupa salah satu dari dua bentuk:

  • template yang sudah disetujui Meta, bisa dikirim kapan saja;
  • teks bebas, hanya bila pelanggan mengirim pesan dalam 24 jam terakhir.

Contoh permintaan​

curl -X POST https://kareeb.id/api/messages \
-H "Authorization: Bearer kt_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "6281234567890",
"template": {
"name": "pengingat_kontrol",
"language": "id",
"body_params": {"1": "Budi", "2": "Rumah Sakit Sentra", "3": "Selasa 10.00"}
},
"idempotency_key": "janji-88123-h1"
}'

Untuk teks bebas, ganti template dengan text:

{
"contact_id": 88,
"text": "Halo Budi, hasil laboratorium Anda sudah bisa diambil.",
"idempotency_key": "lab-88-2026-11-04"
}

Isi permintaan​

Isi tepat satu dari to atau contact_id, dan tepat satu dari text atau template. Mengisi keduanya atau tidak mengisi keduanya dijawab 422.

KolomWajibKeterangan
tosalah satu dari to / contact_idNomor WhatsApp tujuan, format internasional, 7 sampai 20 digit. Tanda plus di depan dan spasi di tepi dibuang. Nomor yang belum dikenal Kareeb otomatis menjadi kontak baru.
contact_idsalah satu dari to / contact_idId kontak di cabang pengirim.
textsalah satu dari text / templateTeks bebas, 1 sampai 4.096 karakter.
template.namebila memakai templateNama template yang sudah disetujui dan ada di akun WhatsApp cabang pengirim.
template.languagetidakKode bahasa template. Bawaan "id".
template.body_paramstidakIsi variabel badan, kunci "1" sampai "N" tanpa celah. Lihat Daftar template.
template.cta_parambila template punya tombol tautan per pelangganBagian akhir alamat yang ditempel ke tautan tombol.
idempotency_keyyaTeks unik per pesan, 1 sampai 128 karakter, unik di organisasi Anda. Lihat Kirim ulang tanpa pesan ganda.
workspace_idtidakCabang pengirim, harus milik organisasi Anda. Bawaan: cabang Utama.

Jawaban​

201 Created untuk kiriman baru, 200 OK bila kunci yang sama sudah pernah dikirim.

{
"message_id": 9137,
"conversation_id": 412,
"wa_message_id": "wamid.HBgM...",
"contact_id": 88,
"replay": false
}

Jawaban 201 berarti Meta sudah menerima pesan dari Kareeb. Sampai atau tidaknya ke ponsel pelanggan dilaporkan kemudian lewat webhook message.status dengan wa_message_id yang sama (lihat Webhook). Simpan wa_message_id di sistem Anda.

Urutan pemeriksaan​

Kareeb memeriksa permintaan dengan urutan ini dan berhenti pada penolakan pertama:

  1. Batas permintaan. Setiap panggilan dihitung per token, termasuk yang ditolak dan kiriman ulang. Bila terlalu banyak, jawabannya 429: tunggu sebanyak detik di header Retry-After.
  2. Kunci. Kunci yang sudah pernah dipakai dijawab 200 dengan id pesan pertama dan "replay": true. Tidak ada yang dikirim lagi.
  3. Cabang. workspace_id di luar organisasi Anda dijawab 404.
  4. Tujuan. contact_id harus kontak cabang itu (404); to harus nomor WhatsApp (422); kontaknya harus kontak WhatsApp (422).
  5. Berhenti berlangganan. Pelanggan yang sudah meminta berhenti dikirimi pesan ditolak, untuk teks maupun template (422). Bila memang harus dihubungi, lakukan lewat operator.
  6. Teks: jendela 24 jam harus terbuka (409). Template: sudah disinkronkan, ada di akun WhatsApp cabang ini, berstatus APPROVED, variabelnya valid, dan cta_param terisi bila template punya tombol tautan. Template MARKETING juga butuh persetujuan promosi dari pelanggan bila instalasi Kareeb Anda mewajibkannya.
  7. Pengiriman lewat jalur yang sama dengan semua pesan Kareeb. Organisasi yang dinonaktifkan atau berstatus baca saja ditolak di sini, dan penolakan dari Meta dikembalikan seperti di kotak masuk.

Kode penolakan​

Penolakan membawa detail berupa objek. Bercabanglah pada code; kalimat di message ditulis untuk dibaca orang dan bisa diubah kapan saja.

{"detail": {"code": "window_closed", "message": "..."}}
HTTPcodeArti dan yang perlu dilakukan
404cabang_not_foundworkspace_id bukan cabang organisasi ini. Periksa id cabang.
404contact_not_foundcontact_id bukan kontak cabang ini. Periksa id kontak.
409window_closedTeks di luar jendela 24 jam. Kirim template.
422invalid_phoneto bukan 7 sampai 20 digit.
422channel_unsupportedKontak ada di Instagram, Messenger, atau WhatsApp Lite. Endpoint ini hanya untuk WhatsApp Cloud API.
422opted_outPelanggan sudah meminta berhenti dikirimi pesan.
422consent_requiredTemplate MARKETING ke pelanggan yang belum menyetujui promosi, pada instalasi yang mewajibkan persetujuan.
422template_not_syncedTemplate belum ada di Kareeb. Admin menekan Sinkronkan di menu Template, lalu kirim lagi.
422template_other_accountTemplate hanya ada di akun WhatsApp yang tidak lagi dipakai organisasi ini.
422template_other_cabangTemplate ada di akun WhatsApp cabang lain. Kirim dengan workspace_id cabang itu.
422template_not_approvedTemplate belum disetujui Meta (PENDING, REJECTED, PAUSED). Mengulang tidak membantu; tunggu persetujuan Meta.
422invalid_paramsKunci atau nilai body_params yang akan ditolak WhatsApp.
422template_needs_ctaTemplate punya tombol tautan per pelanggan dan cta_param kosong.
429rate_limitedTerlalu banyak permintaan. Tunggu Retry-After, lalu ulangi dengan kunci yang sama.

Badan yang tidak sesuai bentuk di atas dijawab 422 oleh FastAPI dengan daftar galat per kolom. Token tanpa izin write:messages dijawab 403 yang menyebut nama izinnya.

Aturan yang perlu diingat​

  • Hanya WhatsApp Cloud API. Kontak Instagram, Messenger, dan WhatsApp Lite ditolak.
  • Pesan dari API tercatat tanpa nama pengirim di Kareeb, ditandai sebagai kiriman API, dan tidak mengambil alih percakapan dari Agen AI.
  • Template UTILITY (pengingat, status pesanan) tidak butuh persetujuan promosi. Template MARKETING butuh, bila instalasi mewajibkannya.