Skip to content

Header and footer on interactive CTA URL messages

Released: July 3, 2026

The interactive.type=cta_url variant on POST /v1/{phone_number_id}/messages previously accepted only body + action. Any header or footer field was silently stripped by validation, even though Meta’s own documentation lists both as supported and the dashboard chat composer has been sending them for months.

Both fields are now accepted on the public API. Shape matches Meta 1:1 — and matches the existing reply_buttons variant so the two interactive surfaces share the same header union:

{
"messaging_product": "whatsapp",
"to": "+628123456789",
"type": "interactive",
"interactive": {
"type": "cta_url",
"header": {
"type": "image",
"image": { "link": "https://cdn.example.com/order-banner.png" }
},
"body": { "text": "Pesananmu siap diambil." },
"footer": { "text": "Pickup sebelum 20:00 WIB" },
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Lihat detail",
"url": "https://example.com/orders/42"
}
}
}
}

Both fields stay optional — payloads that omit them keep working unchanged.

Header variants: text (≤60 chars), image, video, document (each via a public HTTPS link). Footer text is capped at 60 characters. Same limits Meta enforces upstream.

@kirimdev/sdk picks up the new fields via the refreshed openapi.json snapshot. phone.messages.send(...) accepts header and footer on the cta_url variant automatically — the SDK derives its types from the same OpenAPI spec that powers the API reference. No new method is required.

await phone.messages.send({
messaging_product: 'whatsapp',
to: '+628123456789',
type: 'interactive',
interactive: {
type: 'cta_url',
header: {
type: 'image',
image: { link: 'https://cdn.example.com/order-banner.png' },
},
body: { text: 'Pesananmu siap diambil.' },
footer: { text: 'Pickup sebelum 20:00 WIB' },
action: {
name: 'cta_url',
parameters: {
display_text: 'Lihat detail',
url: 'https://example.com/orders/42',
},
},
},
})

The existing send_message MCP tool inherits the same schema update — Claude, ChatGPT, and other MCP-aware clients can now pass header / footer on cta_url sends without tripping the validator.