Send a template with a header and footer
A WhatsApp template message can have up to four parts:
| Part | Required | What it holds |
|---|---|---|
| Header | No | A short title, or an image, video, document or location shown above the text |
| Body | Yes | The main text, with optional {{variables}} |
| Footer | No | A short line of small grey text, for example an opt-out hint |
| Buttons | No | See Buttons |
The header’s type and the footer’s text are fixed when the template is created and approved. When you send, you only supply values for the variable parts: header media, header text variables and body variables.
Text header and footer
Section titled “Text header and footer”Template definition
Section titled “Template definition”{ "name": "appointment_reminder", "language": "en", "category": "UTILITY", "components": [ { "type": "HEADER", "format": "TEXT", "text": "Reminder for {{1}}", "example": { "header_text": ["Asha"] } }, { "type": "BODY", "text": "Your appointment with {{1}} is on {{2}} at {{3}}.", "example": { "body_text": [["Dr. Rao", "3 October", "10:30 am"]] } }, { "type": "FOOTER", "text": "Reply STOP to unsubscribe" } ]}The footer is static, so it needs nothing at send time. Supply the header variable in a header
component, and the body variables in a body component:
curl -X POST "$HELLO_API_URL/v1/<your-phone-number-id>/messages" \ -H "Authorization: Bearer $HELLO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+919999999999", "type": "template", "template": { "name": "appointment_reminder", "language": { "code": "en" }, "components": [ { "type": "header", "parameters": [{ "type": "text", "text": "Asha" }] }, { "type": "body", "parameters": [ { "type": "text", "text": "Dr. Rao" }, { "type": "text", "text": "3 October" }, { "type": "text", "text": "10:30 am" } ] } ] } }'The customer sees:
Reminder for Asha Your appointment with Dr. Rao is on 3 October at 10:30 am. Reply STOP to unsubscribe
A text header without a variable (for example "text": "Appointment reminder") needs no
header component when sending.
Image, video or document header
Section titled “Image, video or document header”Template definition
Section titled “Template definition”A media header needs a sample file for WhatsApp’s review. Pass a public URL of the sample in
example.header_handle; Hello fetches it and uploads it to WhatsApp for you.
{ "name": "order_dispatched", "language": "en", "category": "UTILITY", "components": [ { "type": "HEADER", "format": "IMAGE", "example": { "header_handle": ["https://example.com/samples/parcel.jpg"] } }, { "type": "BODY", "text": "Hi {{1}}, order {{2}} is on its way.", "example": { "body_text": [["Asha", "#10432"]] } }, { "type": "FOOTER", "text": "Thanks for shopping with us" } ]}Every send must supply the actual media for a media header, as link or as an uploaded id:
{ "to": "+919999999999", "type": "template", "template": { "name": "order_dispatched", "language": { "code": "en" }, "components": [ { "type": "header", "parameters": [ { "type": "image", "image": { "link": "https://example.com/orders/10432/parcel.jpg" } } ] }, { "type": "body", "parameters": [ { "type": "text", "text": "Asha" }, { "type": "text", "text": "#10432" } ] } ] }}For other header formats, swap the parameter:
Header format |
Send parameter |
|---|---|
IMAGE |
{ "type": "image", "image": { "link": "…" } } or { "image": { "id": "<media_id>" } } |
VIDEO |
{ "type": "video", "video": { "link": "…" } } |
DOCUMENT |
{ "type": "document", "document": { "link": "…", "filename": "Invoice.pdf" } } |
LOCATION |
{ "type": "location", "location": { "latitude": "12.9716", "longitude": "77.5946", "name": "…", "address": "…" } } |
Media must meet the supported media limits. In a location
header, latitude and longitude are strings.
Limits
Section titled “Limits”These are WhatsApp’s rules, checked when the template is reviewed:
- Text header: up to 60 characters, at most one variable.
- Footer: up to 60 characters, no variables.
- Body: up to 1,024 characters.
Troubleshooting
Section titled “Troubleshooting”If the header or body parameters don’t match the approved template (wrong count, missing media
for a media header), WhatsApp rejects the message. The send is queued first, so the rejection
shows up as status: "failed" with an error_message on
GET /v1/messages/{id}, or straight away as SEND_FAILED with
?sync=true.