Template WhatsApp
Kirim template WhatsApp yang sudah disetujui Meta untuk komunikasi di luar jendela 24 jam.
Template WhatsApp adalah pesan pre-approved oleh Meta yang bisa dikirim kapan saja — bahkan ketika kontak belum mengirim pesan ke kamu dalam 24 jam terakhir. Template umumnya dipakai untuk OTP, notifikasi order, reminder pembayaran, dan promo.
Semua path di halaman ini relatif terhadap base URL https://api.chatera.id/v1.
Identitas template: name + language, bukan ID
Pengiriman template selalu memakai template.name + template.language.code
— field id (UUID) di response list hanyalah identifier internal Chatera dan
tidak bisa dipakai di body POST /v1/whatsapp/messages. Nama template
tidak bisa diubah setelah dibuat di Meta, jadi aman dijadikan referensi stabil
di integrasi kamu. (Alternatif: endpoint
POST /v1/whatsapp/templates/{id}/send
menerima UUID.)
List template yang tersedia
GET /v1/whatsapp/templatesScope yang dibutuhkan: whatsapp:templates
Endpoint ini mengembalikan daftar template yang sudah tersinkron dari
Meta Business Manager dan siap dipakai (status APPROVED).
| Query param | Wajib | Keterangan |
|---|---|---|
channel_id | — | UUID channel WhatsApp. Sangat disarankan bila akun punya lebih dari satu channel — tanpa ini dipakai channel aktif terbaru. Channel tidak ditemukan → WHATSAPP_CHANNEL_NOT_FOUND |
page | — | Halaman (default 1) |
per_page | — | Jumlah per halaman |
curl -X GET "https://api.chatera.id/v1/whatsapp/templates" \
-H "Authorization: Bearer chatera_sk_xxxxx"Response list
{
"success": true,
"data": [
{
"id": "9b8c1234-e5f6-4789-90ab-cdef01234567",
"name": "order_confirmation",
"category": "UTILITY",
"status": "APPROVED",
"languages": [
{ "code": "id", "status": "APPROVED" }
],
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Konfirmasi Order" },
{
"type": "BODY",
"text": "Halo {{1}}, order {{2}} sudah kami terima.",
"example": { "body_text": [["Hafari", "ORD-12345"]] }
},
{ "type": "FOOTER", "text": "Terima kasih." }
],
"channel_id": "1ec6a154-02fa-49f4-bad0-ab9f89a5eb85",
"created_at": "2026-04-27T10:30:00Z",
"updated_at": "2026-04-27T10:30:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 1, "has_more": false }
}| Field | Tipe | Keterangan |
|---|---|---|
id | string (UUID) | Identifier internal Chatera — bukan untuk body template.name |
name | string | Nama template di Meta. Ini yang dipakai saat kirim |
category | string | AUTHENTICATION / MARKETING / UTILITY |
status | string | Selalu APPROVED di endpoint ini |
languages[] | array | Bahasa yang tersedia: { code, status }. Pakai code yang ber-status APPROVED sebagai template.language.code saat kirim |
components[] | array | Struktur template dari Meta: HEADER/BODY/FOOTER/BUTTONS. Variabel posisional tampil sebagai {{1}}, {{2}}, dst. di text |
channel_id | string (UUID) | Channel pemilik template — kirim channel_id yang sama di POST /messages supaya template pasti tersedia di nomor tujuan |
created_at / updated_at | string | Timestamp sinkronisasi |
Mengirim template
Ada dua cara mengirim template — gunakan endpoint /messages untuk
konsistensi.
POST /v1/whatsapp/messagesScope: whatsapp:send
Body memakai type: template dan field template:
{
"to": "628123456789",
"type": "template",
"template": {
"name": "otp_verification",
"language": { "code": "id" },
"components": [...]
}
}| Field | Wajib | Keterangan |
|---|---|---|
template.name | ✅ | Nama template (sesuai yang terdaftar di Meta) — bukan UUID dari list |
template.language.code | ✅ | Kode bahasa persis seperti saat template dibuat di Meta, mis. id, en, en_US. Lihat languages[].code di response list — kode yang salah menghasilkan error Meta #132001 |
template.components | tergantung template | Komponen yang berisi parameter dinamis |
channel_id | — | UUID channel WhatsApp pengirim. Wajib secara praktik bila punya lebih dari satu channel — pakai channel_id yang sama dengan yang muncul di response list supaya template pasti terdaftar di nomor pengirim |
Kirim lewat endpoint template
Alternatif dari /messages: endpoint ini menerima UUID template Chatera
(dari response list) atau nama template di path.
POST /v1/whatsapp/templates/{templateId}/sendScope: whatsapp:send
curl -X POST "https://api.chatera.id/v1/whatsapp/templates/9b8c1234-e5f6-4789-90ab-cdef01234567/send" \
-H "Authorization: Bearer chatera_sk_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"to": "628123456789",
"components": [
{ "type": "body", "parameters": [{ "type": "text", "text": "Hafari" }] }
]
}'| Field | Wajib | Keterangan |
|---|---|---|
{templateId} (path) | ✅ | UUID template dari list, atau langsung nama template |
to | ✅ | Nomor tujuan E.164 |
language | — | Kode bahasa. Bila templateId UUID dan field ini kosong, otomatis dipakai bahasa translation yang APPROVED; bila pakai nama template, default id |
components | tergantung template | Sama seperti template.components di /messages |
channel_id | — | Override channel pengirim. Bila kosong dan templateId UUID, otomatis dipakai channel pemilik template |
Kelebihan jalur UUID: nama, bahasa, dan channel di-resolve dari data template
tersimpan — menghilangkan dua penyebab paling umum error #132001
(salah language.code dan salah channel).
Struktur komponen
Komponen template dipisah berdasarkan posisinya di template:
type | Fungsi | Parameter yang valid |
|---|---|---|
header | Media / lokasi di header pesan | text, image, video, document, location |
body | Variabel di body | text, currency, date_time |
button | Variabel tombol (URL dinamis / payload) | text (untuk sub_type: url), payload (untuk sub_type: quick_reply) |
Contoh-contoh
1. Template OTP sederhana
{
"to": "628123456789",
"type": "template",
"template": {
"name": "otp_verification",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "123456" }
]
}
]
}
}2. Template dengan header gambar
{
"to": "628123456789",
"type": "template",
"template": {
"name": "order_confirmation",
"language": { "code": "id" },
"components": [
{
"type": "header",
"parameters": [
{ "type": "image", "image": { "link": "https://toko-anda.com/products/item-1.jpg" } }
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Pak Hafari" },
{ "type": "text", "text": "ORD-12345" }
]
}
]
}
}3. Template dengan named parameter
Jika template kamu memakai variabel bernama (mis. {{customer_name}}):
{
"to": "628123456789",
"type": "template",
"template": {
"name": "promo_weekly",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John", "parameter_name": "customer_name" },
{ "type": "text", "text": "50%", "parameter_name": "discount" }
]
}
]
}
}4. Template dengan tombol Quick Reply
{
"to": "628123456789",
"type": "template",
"template": {
"name": "order_status_check",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "ORD-12345" }
]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": 0,
"parameters": [{ "type": "payload", "payload": "track_shipment" }]
},
{
"type": "button",
"sub_type": "quick_reply",
"index": 1,
"parameters": [{ "type": "payload", "payload": "contact_support" }]
}
]
}
}indexadalah posisi tombol (0-based).payloaddikirim ke webhook ketika user menekan tombol.
5. Template dengan tombol URL dinamis
Template dengan URL tombol bernama {{1}}:
URL template di Meta: https://toko-anda.com/order/{{1}}{
"to": "628123456789",
"type": "template",
"template": {
"name": "view_order_details",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" }
]
},
{
"type": "button",
"sub_type": "url",
"index": 0,
"parameters": [
{ "type": "text", "text": "ORD-12345" }
]
}
]
}
}Penerima akan melihat tombol yang membuka
https://toko-anda.com/order/ORD-12345.
6. Template dengan header lokasi
{
"to": "628123456789",
"type": "template",
"template": {
"name": "store_location",
"language": { "code": "id" },
"components": [
{
"type": "header",
"parameters": [
{
"type": "location",
"location": {
"latitude": -6.2,
"longitude": 106.816666,
"name": "Toko ABC Cabang Sudirman",
"address": "Jl. Sudirman No. 123, Jakarta"
}
}
]
}
]
}
}7. Template dengan currency
{
"to": "628123456789",
"type": "template",
"template": {
"name": "payment_reminder",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" },
{
"type": "currency",
"currency": {
"fallback_value": "Rp 250.000",
"code": "IDR",
"amount_1000": 250000000
}
}
]
}
]
}
}Konversi `amount_1000`
amount_1000 menyimpan nilai dalam unit terkecil × 1000 untuk
menghindari floating-point error:
- IDR (Rupiah): Rp 250.000 →
250000 × 1000 = 250000000 - USD (Dolar): $25,50 →
25.50 × 1000 = 25500 - MYR (Ringgit): RM 99,99 →
99.99 × 1000 = 99990
fallback_value adalah teks tampilan yang dipakai kalau penerima
WhatsApp tidak mendukung format currency native.
Response sukses
{
"success": true,
"data": {
"messageId": "9b8c1234-e5f6-4789-90ab-cdef01234567",
"whatsappMessageId": "wamid.HBgNNjI4MTIz...",
"status": "sent",
"to": "+628123456789",
"template": "order_confirmation",
"timestamp": "2026-04-27T10:30:00Z"
}
}Pesan error template
| Kode | Penyebab | Solusi |
|---|---|---|
WHATSAPP_TEMPLATE_NOT_FOUND | Nama template tidak ditemukan / belum approved | Cek nama dan status di Meta Business Manager |
WHATSAPP_TEMPLATE_REJECTED | Template ditolak Meta | Perbaiki konten template di Meta lalu submit ulang |
WHATSAPP_TEMPLATE_INVALID_COMPONENTS | Struktur components tidak valid | Lihat details.errors[] |
WHATSAPP_TEMPLATE_MISSING_BUTTON_INDEX | Komponen button tidak punya index | Tambahkan index: 0 (atau 1, 2, dst sesuai posisi) |
WHATSAPP_TEMPLATE_INVALID_PARAMETER_TYPE | Tipe parameter tidak cocok dengan komponen | Mis. currency di komponen header (tidak diperbolehkan) |
WHATSAPP_SEND_FAILED | Meta menolak request | Baca details.error — berisi pesan error asli dari Meta (lihat contoh di bawah) |
Detail error contoh
Validasi komponen (dari Chatera, sebelum request ke Meta):
{
"success": false,
"error": {
"code": "WHATSAPP_TEMPLATE_INVALID_COMPONENTS",
"message": "Template components validation failed",
"details": {
"errors": [
{
"field": "components[2].index",
"message": "Button component requires index field (0-based button position)"
}
]
}
}
}Penolakan dari Meta (WHATSAPP_SEND_FAILED) — pesan asli Meta diteruskan
apa adanya di details.error:
{
"success": false,
"error": {
"code": "WHATSAPP_SEND_FAILED",
"message": "Failed to send WhatsApp message",
"details": {
"error": "(#132001) Template name does not exist in the translation"
}
}
}Troubleshooting #132001
Error Meta (#132001) Template name does not exist in the translation
artinya kombinasi nama + bahasa + nomor pengirim tidak menemukan
template. Tiga penyebab paling umum, urut dari yang paling sering:
- Salah
language.code— template dibuat dengan bahasaentapi kamu kirimid(atau sebaliknya). Cocokkan denganlanguages[].codedi response list. - Salah channel — template terdaftar di channel/nomor lain. Kirim
channel_idyang sama denganchannel_idtemplate di response list. - Template sudah tidak ada di Meta — mis. nomor lama dilepas/diblokir. Lakukan sinkronisasi ulang template dari dashboard; template yang sudah hilang di Meta akan dinonaktifkan otomatis dari list.