Send templates with buttons
WhatsApp templates can include up to 10 buttons across two categories: call-to-action (URL, phone) and quick reply. Some button types accept a runtime parameter; others are fully baked at approval time.
| Button type | Runtime parameter | sub_type |
|---|---|---|
| Dynamic URL (suffix) | Yes — fills {{1}} in the URL | url |
| Quick reply | Yes — payload returned in webhook | quick_reply |
| Copy code (marketing / utility) | Yes — the coupon / code text | copy_code |
| Phone number | No (baked at approval) | — |
| Static URL | No (baked at approval) | — |
Each button is addressed by its zero-based index in the template’s
button row, in the order they were approved.
Dynamic URL button
Section titled “Dynamic URL button”The template URL is approved as something like
https://example.com/orders/{{1}}. You fill {{1}} at send time.
curl -X POST \ https://api.kirimdev.com/v1/$PHONE_ID/messages \ -H "Authorization: Bearer $KIRIM_KEY" \ -H "Content-Type: application/json" \ -d '{ "messaging_product": "whatsapp", "to": "+628123456789", "type": "template", "template": { "name": "order_shipped", "language": "id", "components": [ { "type": "body", "parameters": [ { "type": "text", "text": "Andi" }, { "type": "text", "text": "INV-4521" } ] }, { "type": "button", "sub_type": "url", "index": 0, "parameters": [ { "type": "text", "text": "INV-4521" } ] } ] } }'import { Kirim } from '@kirimdev/sdk'
const kirim = new Kirim({ apiKey: process.env.KIRIM_KEY! })const phone = kirim.phoneNumbers(process.env.PHONE_ID!)
await phone.messages.send({ messaging_product: 'whatsapp', to: '+628123456789', type: 'template', template: { name: 'order_shipped', language: 'id', components: [ { type: 'body', parameters: [ { type: 'text', text: 'Andi' }, { type: 'text', text: 'INV-4521' }, ], }, { type: 'button', sub_type: 'url', index: 0, parameters: [{ type: 'text', text: 'INV-4521' }], }, ], },})Quick reply button
Section titled “Quick reply button”The payload is what your server receives in the inbound webhook
when the user taps the button.
{ "type": "button", "sub_type": "quick_reply", "index": 0, "parameters": [ { "type": "payload", "payload": "CONFIRM_ORDER_4521" } ]}When the customer taps it, your webhook receives a
type: "button" message with button.payload = "CONFIRM_ORDER_4521".
See Receive messages for the webhook
shape.
Copy-code button
Section titled “Copy-code button”Used for coupon codes and redemption codes on marketing / utility templates — the user taps once to copy the value to their clipboard.
{ "type": "button", "sub_type": "copy_code", "index": 1, "parameters": [ { "type": "coupon_code", "coupon_code": "DISKON30" } ]}Mixing multiple buttons
Section titled “Mixing multiple buttons”Send one button component per button index, in any order:
"components": [ { "type": "body", "parameters": [ /* ... */ ] }, { "type": "button", "sub_type": "quick_reply", "index": 0, "parameters": [{ "type": "payload", "payload": "YES" }] }, { "type": "button", "sub_type": "quick_reply", "index": 1, "parameters": [{ "type": "payload", "payload": "NO" }] }]