What Address Messages Do
Address messages are an interactive service message type that asks a WhatsApp user to fill in a structured shipping address inside WhatsApp itself. The user sees a form, completes it, and submits — your backend receives the structured address back via webhook.
This eliminates the back-and-forth of asking for street, pin code, city, etc. as separate text questions and avoids typos in free-form text.
Availability (India Only)
This feature is only available for businesses based in India sending to Indian customers. The form only shows on WhatsApp clients that support address_message. Older or non-supporting clients receive nothing visible — see Feature Not Supported for the webhook you get instead.
country is a mandatory field in the action parameters; omitting it returns a validation error. Currently only IN is supported.
Supported Fields
| Field | Display label | Input type | Validation |
|---|---|---|---|
name | Name | text | — |
phone_number | Phone Number | tel | Valid phone numbers only |
in_pin_code | Pin Code | text | Max length: 6 |
house_number | Flat/House Number | text | — |
floor_number | Floor Number | text | — |
tower_number | Tower Number | text | — |
building_name | Building/Apartment Name | text | — |
address | Address | text | — |
landmark_area | Landmark/Area | text | — |
city | City | text | — |
state | State | text | — |
Send an Address Message
Minimal payload — just the country and a body prompt:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "+91xxxxxxxxxx",
"type": "interactive",
"interactive": {
"type": "address_message",
"body": {
"text": "Thanks for your order! Tell us what address you'd like this delivered to."
},
"action": {
"name": "address_message",
"parameters": { "country": "IN" }
}
}
}
The user sees an empty form, fills it in, submits — and you receive the address via webhook.
Prefill and Saved Addresses
Two optional ways to reduce the user's friction:
Prefill specific fields with values:
"action": {
"name": "address_message",
"parameters": {
"country": "IN",
"values": {
"name": "Pablo Morales",
"phone_number": "+91xxxxxxxxxx"
}
}
}
The user can edit prefilled values before submitting.
Pass saved addresses the user can pick from:
"action": {
"name": "address_message",
"parameters": {
"country": "IN",
"saved_addresses": [
{
"id": "address1",
"value": {
"name": "Pablo Morales",
"phone_number": "+91xxxxxxxxxx",
"in_pin_code": "400063",
"floor_number": "8",
"building_name": "",
"address": "Wing A, Cello Triumph, IB Patel Rd",
"landmark_area": "Goregaon",
"city": "Mumbai"
}
}
]
}
}
The user sees the saved addresses with an option to pick one or enter a new address. Each saved address needs a unique id you assign — when the user picks one, the webhook returns that id so you can map it back to your CRM record.
Validation Errors
When you receive a submitted address that fails server-side validation, re-send the address message with the same values and a validation_errors map. WhatsApp blocks submission until the user fixes the flagged fields.
"action": {
"name": "address_message",
"parameters": {
"country": "IN",
"values": {
"name": "Pablo Morales",
"phone_number": "+91xxxxxxxxxx",
"in_pin_code": "666666",
"address": "Some other location",
"city": "Delhi"
},
"validation_errors": {
"in_pin_code": "We could not locate this pin code."
}
}
}
validation_errors is a flat map of field_name → error_message. The error text is shown to the user beneath the offending field.
Address Submission Webhook
When the user submits, you receive a Native Flow Message (NFM) reply on the standard messages webhook field:
{
"messages": [
{
"context": {
"from": "15550001234",
"id": "wamid.HBgLMTIwNjU1NTAxMDcVAgARGBI3NjNFN0U5QzMzNDlCQjY0M0QA"
},
"from": "+91xxxxxxxxxx",
"id": "wamid.HBgLMTIwNjU1NTAxMDcVAgASGCA5RDhBNENEMEQ3RENEOEEzMEI0RUExRDczN0I1NThFQwA=",
"timestamp": "1671498855",
"type": "interactive",
"interactive": {
"type": "nfm_reply",
"nfm_reply": {
"name": "address_message",
"response_json": "{\"saved_address_id\":\"address1\",\"values\":{\"in_pin_code\":\"400063\",\"building_name\":\"\",\"landmark_area\":\"Goregaon\",\"address\":\"Wing A, Cello Triumph, IB Patel Rd\",\"city\":\"Mumbai\",\"name\":\"Pablo Morales\",\"phone_number\":\"+91xxxxxxxxxx\",\"floor_number\":\"8\"}}",
"body": "Pablo Morales\n +91xxxxxxxxxx\n 400063, Goregaon, Wing A, Cello Triumph, IB Patel Rd, Mumbai, 8"
}
}
}
]
}
| Field | Notes |
|---|---|
interactive.type | Always nfm_reply |
nfm_reply.name | Always address_message for this flow |
nfm_reply.response_json | String-encoded JSON containing saved_address_id (if user picked a saved one) and values (the submitted form fields) |
nfm_reply.body | Human-readable summary as the user sees it (optional) |
response_json is a string, not a nested object — parse it with JSON.parse before consuming. In Dualhook setups, this webhook arrives on the messages field and is delivered directly to your endpoint via Webhook Override.
Feature Not Supported (Old Clients)
If the recipient's WhatsApp client doesn't support address_message (older versions, certain platforms), the message is silently dropped and you receive a failed status webhook with error code 1026 (Receiver Incapable):
{
"statuses": [
{
"id": "wamid.HBgL...",
"status": "failed",
"timestamp": "1670394125",
"type": "message",
"recipient_id": "91xxxxxxxxxx",
"errors": [
{ "code": 1026, "title": "Receiver Incapable" }
]
}
]
}
Treat 1026 as "fall back to a text-based address question" — the user did not refuse, they just can't see the form.
Typical Flow
- Business sends an
address_message(withparameters.country: "IN", optionallyvaluesorsaved_addresses). - User taps the CTA, fills the form, submits.
- Webhook arrives with
type: "interactive",interactive.type: "nfm_reply",nfm_reply.name: "address_message",nfm_reply.response_jsoncontaining the address. - Backend validates server-side (e.g. real pin-code lookup, courier coverage check).
- If validation fails, re-send the message with
values(carrying over the user's input) plusvalidation_errors. - Loop until validation passes or user abandons.
If the recipient's client doesn't support the form, the send fails with error 1026 and you should fall back to text-based collection.