Receiving WhatsApp messages
Receive the messages customers send to your WhatsApp numbers, read their files, and reply within the 24-hour service window.
When a customer writes to one of your connected WhatsApp numbers, Nexiom Connect stores the message and sends it to your webhook. You decide what happens next: answer automatically, pass the conversation to your team, or record the customer's choice. Receiving messages is free: received messages never count toward your plan.
Set up receiving
Subscribe to the webhook
In the dashboard, add a webhook endpoint to your project and select whatsapp.message.received. See Webhooks.
Create an API key with full access
Reading received messages and their files with the API needs a key with
whatsapp.full_access. A key with onlywhatsapp.sendcan still reply and mark messages as read, but received messages return404to it. See API keys.Handle each message
Verify the webhook signature, store the message by its
data.id, then act on itstype. Deduplicate by the envelopeid: an event can be delivered more than once.
Every received message also appears in Messaging → Logs, with Received as its direction. From a received message's page, you can reply while the service window is open, and mark it as read.
What customers can send
The webhook's data.type names the field that holds the message.
type | What the customer did | Content |
|---|---|---|
text | Wrote a message. | text.body |
image, video, audio, document, sticker | Sent a file or a voice message. | A media object, with the caption and file details |
location | Shared a location. | location.latitude, location.longitude, location.name, location.address |
contacts | Shared one or more contact cards. | contacts[], with names, phones, and emails |
button | Tapped a quick-reply button of your template. | button.text, and button.payload: the value you sent for that button |
interactive | Tapped a reply button, or chose a row of a list, from your interactive message. | interactive.kind (button_reply or list_reply), interactive.id, interactive.title |
reaction | Reacted to a message with an emoji, or removed a reaction. | reaction.emoji, reaction.message_id |
unsupported | Sent something Nexiom Connect doesn't read yet, such as an order. | unsupported.provider_type |
When the customer replies to a specific message, reply_to holds its ID. A conversation the customer started from a Click-to-WhatsApp ad or post includes referral on its first message, with the ad or post they came from.
Files customers send
Nexiom Connect downloads each file from WhatsApp and stores it privately, then sends the webhook. By the time you receive whatsapp.message.received, the file is ready to download.
Media status | Meaning |
|---|---|
pending | The file is still being downloaded. Only visible if you retrieve the message before the webhook arrives. |
ready | The file is stored. Download it with Get message media. |
unavailable | WhatsApp no longer had the file, it was larger than 100 MB, or it couldn't be downloaded after retries for up to 24 hours. The webhook still fires, so no message goes unnoticed. |
Download a file with a short-lived URL:
curl "https://api-connect.nxiom.com/api/v1/messaging/messages/msg_example/media" \
-H "Authorization: Bearer $NEXIOM_API_KEY"The response's url works for 5 minutes by default, up to 1 hour with expiresInSeconds. Request a new one each time you need the file.
The 24-hour service window
A customer's message opens a 24-hour customer service window between your number and that customer, counted from when they sent it. Each new message from them extends it. While it is open, you can reply with any message type: text, media, a location, buttons, a list, or a reaction. Once it closes, you can only send a template, and a free-form message returns 422 with the code whatsapp_service_window_closed.
Retrieve a received message to see its conversation's window: chat.service_window_expires_at, and chat.can_send_free_form, which becomes false one minute before the window closes. See The customer service window.
Reply to a customer
Send a reply with Send a message: from is your number that received the message (data.recipient of the webhook), and to is the customer (data.sender). Add reply_to to show the customer's message quoted above yours.
{
"channel": "whatsapp",
"from": "+213555000111",
"to": "+213555123456",
"reply_to": "msg_example",
"text": {
"body": "Sorry about that, Amina. We're sending a replacement today."
}
}Replies are messages you send: they need an Idempotency-Key, follow the same statuses and webhooks as templates, and count toward your plan like any message you send. See Costs.
Mark messages as read
Mark a message as read to show the customer blue ticks. Add "typing_indicator": true to also show that you are typing while you prepare the answer.
curl -X POST "https://api-connect.nxiom.com/api/v1/messaging/messages/msg_example/read" \
-H "Authorization: Bearer $NEXIOM_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "typing_indicator": true }'Confirm an order with quick replies
Send a template with quick replies
Create a utility template with Confirm and Cancel quick-reply buttons. When you send it, give each button a payload that identifies the order:
{ "template": { "id": "mtp_example", "variables": { "body": { "1": "Amina", "2": "A-1234" } }, "buttons": [ { "index": 0, "value": "confirm-A-1234" }, { "index": 1, "value": "cancel-A-1234" } ] } }Receive the tap
When the customer taps a button, you receive
whatsapp.message.receivedwithtypeset tobutton,button.payloadset toconfirm-A-1234orcancel-A-1234, andreply_toset to your template message's ID.Update the order and reply
Update the order from the payload. The tap opened the service window, so you can answer with a text message that thanks the customer and confirms the next step.
Answer questions with a menu
Acknowledge the message
When a
textmessage arrives, mark it as read with the typing indicator.Offer choices
Reply with an interactive list of topics, such as Track my order and Return an item, each with its own row
id.Route the answer
The customer's choice arrives with
typeset tointeractive,interactive.kindset tolist_reply, and the row'sid. Answer it automatically, or pass the conversation to your team.
Collect a photo or document
Ask the customer to send a photo of a damaged item or a scanned document. When the message arrives, its file is already stored: get its URL, download it, and keep it in your own storage if you need it for longer than 30 days.
Retention
Received messages, their content, and their files are kept for 30 days, like the messages you send. After that, they are deleted and the API returns 404. Store what you need in your own system when you receive it.