Before sending
WhatsApp has two Meta rules that the API applies exactly like the app:
- 24-hour window: up to 24 h after the contact's last message you can send text, buttons or a list. The conversation shows it in
window.openandwindow.expires_at. - Outside the window, only an approved template (
GET /v1/templates?status=approved).
Contacts who opted out don't get templates; you can reply only if they write again.
Text
curl -X POST https://api.converzap.com/v1/conversations/CONVERSATION_ID/messages \
-H "Authorization: Bearer czk_live_YOUR_KEY" \
-H "Idempotency-Key: 6c1f0e2a-5b7d-4c1e-9b1a-1f2e3d4c5b6a" \
-H "Content-Type: application/json" \
-d '{ "type": "text", "text": "Hi Ana! Your order is on its way." }'
Template (outside the window)
{
"type": "template",
"template": {
"name": "appointment_reminder",
"language": "pt_BR",
"params": { "body": ["Ana", "tomorrow at 3pm"] }
}
}
Variables: body as a list ({{1}}, {{2}}…) or an object (named: { "name": "Ana" }), header the same, buttons: { "0": "url-suffix" }. template.id also works instead of name + language.
Buttons and list
{
"type": "interactive",
"interactive": {
"type": "buttons",
"body": "Confirm tomorrow's appointment?",
"buttons": [{ "id": "yes", "title": "Confirm" }, { "id": "no", "title": "Reschedule" }]
}
}
The contact's reply arrives as a text message with the button title (and in the message.received webhook).
What happens when you send
- The sender becomes the conversation assignee if it had none.
- The number's AI agent logs the human reply and pauses, if configured to.
- The message shows in the inbox as sent by the key's user.
Common errors
| code | What to do |
|---|---|
outside_24h_window | Use an approved template. |
opt_out | The contact opted out; wait for them to write. |
template_invalid | Wrong name/language or template not approved for this number. |
template_param_missing | A variable is missing; detail says which. |
number_disconnected / number_blocked | Number disconnected or blocked by Meta; check WhatsApp Health in the app. |
meta_error | Meta refused; detail has its message. |
Always send Idempotency-Key: if the network drops and you retry, the message isn't sent twice.