When a customer messages your WhatsApp Business number, taps a button, picks a list option or sends you their location, Sozuri pushes the event to your webhook. The same endpoint also receives delivery and read receipts for every message you send.

Configure your webhook URL from Manage API › Callback URLs. Use HTTPS, respond with 200 OK within 10 seconds, and verify the optional authKey for safety.

Common envelope

Every incoming-message webhook shares the same outer shape — the type field tells you which payload to expect inside messages[0]:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "wamid.ID",
        "timestamp": "TIMESTAMP",
        "type": "TYPE"
        // ... type-specific payload below
    }]
}

Incoming text message

The simplest case — a customer types a message to your business:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "text",
        "text": { "body": "MESSAGE_BODY" }
    }]
}

Reaction

A customer reacts to one of your messages with an emoji. Reactions on messages older than 30 days are not delivered.

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "reaction",
        "reaction": {
            "message_id": "MESSAGE_ID",
            "emoji": "EMOJI"
        }
    }]
}

Media & stickers

When a customer sends an image, video, audio note, document or sticker, WhatsApp downloads the file first and then fires the webhook. Use the id to fetch the media bytes from Sozuri.

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "wamid.ID",
        "timestamp": "TIMESTAMP",
        "type": "image",
        "image": {
            "caption": "CAPTION",
            "mime_type": "image/jpeg",
            "sha256": "IMAGE_HASH",
            "id": "ID"
        }
    }]
}

Stickers come through in the same shape with type: "sticker":

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "wamid.ID",
        "timestamp": "TIMESTAMP",
        "type": "sticker",
        "sticker": {
            "mime_type": "image/webp",
            "sha256": "HASH",
            "id": "ID"
        }
    }]
}

Location pin

A customer shares their location, or a named place:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "location",
        "location": {
            "latitude": "LOCATION_LATITUDE",
            "longitude": "LOCATION_LONGITUDE",
            "name": "LOCATION_NAME",
            "address": "LOCATION_ADDRESS"
        }
    }]
}

Quick reply button tap (template)

Fires when a customer taps a button on a message template you sent earlier:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "button",
        "button": {
            "text": "No",
            "payload": "No-Button-Payload"
        }
    }]
}

List reply

Fires when a customer chooses an item from a list message you sent:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "interactive",
        "interactive": {
            "type": "list_reply",
            "list_reply": {
                "id": "list_reply_id",
                "title": "list_reply_title",
                "description": "list_reply_description"
            }
        }
    }]
}

Button reply tap

Fires when a customer taps one of your interactive reply buttons:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "interactive",
        "interactive": {
            "type": "button_reply",
            "button_reply": {
                "id": "unique-button-identifier-here",
                "title": "button-text"
            }
        }
    }]
}

Incoming contact card

A customer shares one or more contact cards with your business:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "to": "BUSINESS_PHONE_NUMBER",
    "messages": [{
        "from": "PHONE_NUMBER",
        "message_id": "MESSAGE_ID",
        "timestamp": "TIMESTAMP",
        "type": "contacts",
        "contacts": [{
            "addresses": [
                { "street": "STREET", "city": "CITY", "state": "STATE", "zip": "ZIP", "country": "COUNTRY", "country_code": "COUNTRY_CODE", "type": "HOME" },
                { "street": "STREET", "city": "CITY", "state": "STATE", "zip": "ZIP", "country": "COUNTRY", "country_code": "COUNTRY_CODE", "type": "WORK" }
            ],
            "birthday": "YEAR_MONTH_DAY",
            "emails": [
                { "email": "EMAIL", "type": "WORK" },
                { "email": "EMAIL", "type": "HOME" }
            ],
            "name": {
                "formatted_name": "NAME",
                "first_name": "FIRST_NAME",
                "last_name": "LAST_NAME",
                "middle_name": "MIDDLE_NAME",
                "suffix": "SUFFIX",
                "prefix": "PREFIX"
            },
            "org": { "company": "COMPANY", "department": "DEPARTMENT", "title": "TITLE" },
            "phones": [
                { "phone": "PHONE_NUMBER", "type": "HOME" },
                { "phone": "PHONE_NUMBER", "type": "WORK", "wa_id": "PHONE_OR_WA_ID" }
            ],
            "urls": [
                { "url": "URL", "type": "WORK" },
                { "url": "URL", "type": "HOME" }
            ]
        }]
    }]
}

Outbound message status

WhatsApp pushes a status webhook each time one of your messages is sent, delivered, read or failed. These can arrive out of order — rely on the timestamp, not the order of receipt.

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "phone_number": "BUSINESS_DISPLAY_PHONE_NUMBER",
    "statuses": [{
        "recipient": "CUSTOMER_PHONE_NUMBER",
        "message_id": "WHATSAPP_MESSAGE_ID",
        "status": "sent",
        "type": "status",
        "conversation_id": "CONVERSATION_ID",
        "expiration_timestamp": "CONVERSATION_EXPIRATION_TIMESTAMP",
        "category": "user_initiated"
    }]
}

A failure callback includes a human-readable error:

{
    "project": "YOUR_PROJECT_NAME",
    "channel": "whatsapp",
    "phone_number": "BUSINESS_DISPLAY_PHONE_NUMBER",
    "statuses": [{
        "recipient": "CUSTOMER_PHONE_NUMBER",
        "message_id": "WHATSAPP_MESSAGE_ID",
        "status": "failed",
        "type": "status",
        "error": "Request for url https://URL.jpg failed with error: 404 (Not Found)"
    }]
}

Use cases

The conversations you unlock once your webhook is live.

Chatbots that route by intent

Match incoming text against a small set of keywords (“order”, “balance”, “agent”) and route to the right flow.

Tappable customer feedback

Send a list or buttons after every purchase and capture the reply ID — richer data, less typing for the user.

Pickup & delivery handoff

A customer pins a meet-up spot; you ingest the coordinates and dispatch the rider.

Read-receipt-driven follow-ups

If a status webhook reports read and the customer hasn’t replied in an hour, schedule a follow-up nudge.

Make every WhatsApp reply count.

Point your webhook at Sozuri and you’ll have every message, tap, status and reaction streaming into your stack.