Overview
Contacts and location are standard Cloud API message types sent through the same messaging endpoint. Both are free-form message types and must follow the standard customer service window policy.
Send Location Messages
Set type to location and provide latitude, longitude, name, and address:
{
"messaging_product": "whatsapp",
"to": "<RECIPIENT_PHONE_NUMBER>",
"type": "location",
"location": {
"latitude": 37.7790262,
"longitude": -122.4199061,
"name": "<LOCATION_NAME>",
"address": "<LOCATION_ADDRESS>"
}
}
Send Contacts Messages
Set type to contacts and provide one or more contacts. The name.formatted_name field is required, plus at least one of first_name, last_name, middle_name, suffix, or prefix.
{
"messaging_product": "whatsapp",
"to": "<RECIPIENT_PHONE_NUMBER>",
"type": "contacts",
"contacts": [
{
"name": {
"formatted_name": "<CONTACT_DISPLAY_NAME>",
"first_name": "<CONTACT_FIRST_NAME>",
"last_name": "<CONTACT_LAST_NAME>"
},
"phones": [
{ "phone": "<CONTACT_PHONE_E164>", "type": "WORK" }
],
"emails": [
{ "email": "<CONTACT_EMAIL>", "type": "WORK" }
],
"org": {
"company": "<COMPANY_NAME>",
"title": "<JOB_TITLE>"
}
}
]
}
Inbound Location Webhook
When a user shares a location, it arrives as a messages webhook with type="location":
{
"messages": [
{
"from": "<WHATSAPP_USER_PHONE_NUMBER>",
"id": "<WHATSAPP_MESSAGE_ID>",
"timestamp": "<TIMESTAMP>",
"type": "location",
"location": {
"latitude": 37.7790262,
"longitude": -122.4199061,
"name": "<OPTIONAL_LOCATION_NAME>",
"address": "<OPTIONAL_LOCATION_ADDRESS>"
}
}
]
}
Inbound Contact Card Webhook
When a user sends a contact card, it arrives with type="contacts":
{
"messages": [
{
"from": "<WHATSAPP_USER_PHONE_NUMBER>",
"id": "<WHATSAPP_MESSAGE_ID>",
"timestamp": "<TIMESTAMP>",
"type": "contacts",
"contacts": [
{
"name": {
"formatted_name": "<CONTACT_DISPLAY_NAME>",
"first_name": "<CONTACT_FIRST_NAME>"
},
"phones": [
{ "phone": "<CONTACT_PHONE_E164>", "wa_id": "<CONTACT_WA_ID>", "type": "CELL" }
]
}
]
}
]
}
Blocking and Unblocking Contacts
Use Meta's Block Users API on the phone-number node:
POST /<PHONE_NUMBER_ID>/block_users— blockDELETE /<PHONE_NUMBER_ID>/block_users— unblockGET /<PHONE_NUMBER_ID>/block_users— list blocked
A blocked user cannot message that business number, and the business number cannot send messages to blocked users. Dualhook does not proxy block/unblock calls — execute from your backend against Meta Graph API.