Callbacks

This page describes the callbacks that are sent from the Sinch WhatsApp API. These callbacks can contain both delivery reports (about outbound messages) and inbound messages.

A callback is a HTTP POST request with a notification made by the Sinch WhatsApp API to a URI of your choosing.

Note:

The Sinch WhatsApp API allows you to specify, at most, one callback URL. However, that callback URL can be overwritten and updated whenever you make an API call to send a WhatsApp message.

The Sinch WhatsApp API expects the receiving server to respond with a response code within the 2xx Success range. If no successful response is received then the API will either schedule a retry if the error is expected to be temporary or discard the callback if the error seems permanent. The first initial retry will happen 5 seconds after the first try. The next attempt is after 10 seconds, then after 20 seconds, after 40 seconds, and after 80 seconds, doubling on every attempt. The last retry will be at 81920 seconds (or 22 hours 45 minutes) after the initial failed attempt.

A callback from the Sinch WhatsApp API will always have the following structure:

Name Description JSON Type
type Will always be whatsapp String
statuses Array of delivery reports Array[Object]
contacts Array of inbound contact messages Array[Object]
notifications Array of inbound messages Array[Object]
Note

A callback from the Sinch WhatsApp API can contain both delivery reports and inbound messages.

Contacts can be included only in inbound messages of the text, contact and location types.

Signature

If you wish to have your callbacks signed and have made the proper configuration for this, the callbacks will include the following signature-related headers.

Header Description JSON Type
sinch-whatsapp-callback-signature The signature String
sinch-whatsapp-callback-signature-algorithm The algorithm that was used to compute the signature: HMAC_SHA_256 String
sinch-whatsapp-callback-signature-nonce The nonce that was used together with the callback payload to create the signature String

The signature is computed by using the signature algorithm with two inputs:

  1. The Callback verification key that you supplied during configuration
  2. A string that is constructed by joining the callback payload (the full request body) with the nonce by a dot: payload.nonce .

After computing the signature, verify that it matches the signature that was sent in the sinch-whatsapp-callback-signature header.

Delivery report callback

A delivery report contains the status and state of each message sent through the Sinch WhatsApp API. The format of a delivery report is as follows:

Name Description JSON Type
status The status of the message, either success or failure String
state The state of the message, which provides more information on the success or failure status String
message_id The message id of the message to which this delivery report belong to String
details Detailed message containing information. String
recipient The recipient of the message that this delivery report belong to String
conversation Details about the conversation the message belongs to Object
timestamp ISO-8601 datetime of the status update String
errors A list of errors Array[Object]

Each error object can have the following fields:

Name Description JSON Type
type Fixed value error. String
title The title of the error. String

Applicable states

Different states are associated with the success status and failure status.

States applicable to the success status:

State Description
queued Message has been received and queued by the Sinch WhatsApp API
dispatched Message has been dispatched by Sinch WhatsApp API to WhatsApp servers
sent Message has been sent by WhatsApp to end-user
delivered Message has been successfully delivered to end-user by WhatsApp
read Message has been read by the end-user in the WhatsApp application
deleted Message has been deleted or expired in the application
warning Message has some problems, described in errors
Note

A delivery report with state warning can include a list of errors.

States applicable to the failure status:

State Description
failed Message has failed to be delivered
no_opt_in Message rejected by Sinch API as recipient is not registered to have opted in
no_capability Message rejected by the Sinch API as the recipient lacks WhatsApp capability

Conversation object

Name Description JSON Type
conversation_id The ID of the conversation the message belongs to String
expiration_timestamp Time in seconds since 1st of January 1970 UTC when conversation will expire Number
pricing_category Conversation category, one of business_initiated, user_initiated or referral_conversion String

Status callback with state sent

Copy
Copied
{
  "type": "whatsapp",
  "statuses": [
    {
      "status": "success",
      "state": "sent",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "recipient": "+46732001122",
      "conversation": {
        "conversation_id": "06209994d9d7f3b595f05891dfd66cad",
        "expiration_timestamp": 1642858500,
        "pricing_category": "user_initiated"
      },
      "timestamp": "2022-01-02T18:40:42Z"
    }
  ]
}

Status callback with state delivered

Copy
Copied
{
  "type": "whatsapp",
  "statuses": [
    {
      "status": "success",
      "state": "delivered",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "recipient": "+46732001122",
      "conversation": {
        "conversation_id": "06209994d9d7f3b595f05891dfd66cad",
        "pricing_category": "user_initiated"
      },
      "timestamp": "2022-01-02T18:40:42Z"
    }
  ]
}

Status callback with state read

Copy
Copied
{
  "type": "whatsapp",
  "statuses": [
    {
      "status": "success",
      "state": "read",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "recipient": "+46732001122",
      "conversation": {},
      "timestamp": "2022-01-02T18:40:42Z"
    }
  ]
}

Status callback with state warning

Copy
Copied
{
  "type":"whatsapp",
  "statuses": [
    {
      "status":"success",
      "state":"warning",
      "message_id": "01FX0FGEH0E2E50HRCA7190ZE8",
      "recipient":"+46732001122",
      "timestamp":"2022-02-28T15:34:45Z",
      "conversation":{},
      "errors": [
        {
          "code":2026,
          "title":"Some products could not be sent because they are either hidden or they don't have an approved status. Please check your catalog. Products not sent include: productid"
        }
      ]
    }
  ]
}

Inbound message callback

An inbound message or MO (Mobile Originated) message is a message sent to one of your bots from a WhatsApp user. The format is as follows:

Inbound message fields

Contacts

Name Description JSON Type
profile Profile details of message sender Object
wa_id WhatsApp account id (phone number) String

Profile

Name Description JSON Type
name Sender name of message String

Notifications

Name Description JSON Type
from MSISDN of the user sending the message String
to The identifier of the receiving bot String
replying_to A context object, present only if the user is replying to a specific thread Object
message_id Generated message id for the inbound message String
message Message object describing the inbound message Object
timestamp ISO-8601 datetime of the status update String
forwarded Boolean object stating if message was forwarded Boolean
frequently_forwarded Boolean object stating if message was frequently forwarded Boolean
referral A referral object, if the message is sent in reponse to an ad or a post Object
Context

This object (namely replying_to) is included in the MO notification if it is in reply to a message. It contains information about the original message.

Name Description JSON Type
message_id Message ID of the message which is being replied directly to String
from MSISDN of the user which sent the message with the above message id String
Referral

This object (namely referral) may be included in the MO notification if it is in response to an ad or a post. It contains information about the ad or post.

Name Description JSON Type Required
headline The headline of the ad or post that generated the message String Yes
body The body of the ad or post that generated the message String Yes
source_type The type of ad that generated the message: either ad or post String Yes
source_id The Facebook ID of the ad or post that generated the message String Yes
source_url The URL that leads to of the ad or post that generated the message String Yes
referral_media An object that describes the media in the ad or post that generated the message Object No

The following MO notification types can include a referral object:

  • text
  • location
  • contacts
  • image
  • video
  • document
  • voice
  • sticker
Referral media

This object (namely referral_media) may be included in the referral object.

Name Description JSON Type Required
type The type of media in the ad or post that generated the MO message String Yes
url The public url of a copy of the the media file in the ad or post that generated the MO message String Yes
Referred product

A referred_product object may be included in a message object if the message callback was generated through an interaction with a product in an interactive product or product list message.

Note

You can find examples of interactive product and interactive product list messages here.

The referred_product object contains a reference to the specific product.

The referred_product object has the following fields:

Name Description JSON Type Required
catalog_id The ID of the product catalog to which the product belongs String Yes
product_retailer_id The ID of the product in the product catalog String Yes
Note

Some message examples below include references to products.

Text message

Name Description JSON Type
type Fixed value text String
body The text of the text message String
Sample inbound text messageSample inbound text message with a reference to a product
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "replying_to": {
        "from": "447537817391",
        "message_id": "01E7Q9AVTRB5A30JD7D9ZN0HTE"
      },
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "text",
        "body": "Hello bot I want to know something!"
      },
      "timestamp": "2020-05-02T19:48:42Z"
    }
  ]
}
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "replying_to": {
        "from": "447537817391",
        "message_id": "01E7Q9AVTRB5A30JD7D9ZN0HTE"
      },
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "text",
        "body": "Hi, do you have this product in red?",
        "referred_product": {
          "catalog_id": "catalogid",
          "product_retailer_id": "productid",
        }
      },
      "timestamp": "2020-05-02T19:48:42Z"
    }
  ]
}

Location message

Name Description JSON Type
type Fixed value location String
latitude Latitude of location being sent Number
longitude Longitude of location being sent Number
address Address of the location String
name Name of the location String
url URL for the website where the user downloaded the location information String
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "location",
        "latitude": 55.7047,
        "longitude": 13.191,
        "name": "Sinch Ideon Lund",
        "address": "Scheelevägen 17"
      },
      "timestamp": "2020-05-02T19:40:52Z"
    }
  ]
}

Quick reply button reply message

This is the reply from a template quick reply button message. Don't confuse with the reply from an interactive button message below.

Name Description JSON Type
type Fixed value button. String
index The index of the button in the message template (0–2). String
text The button text. String
payload The payload that was sent with the button. String
Copy
Copied
{
  "type": "whatsapp",
  "notifications": [
    {
      "from": "0732001122",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "button",
        "index": "2",
        "text": "Option 3",
        "payload": "some_payload"
      },
      "timestamp": "2020-05-07T10:02:10Z",
      "to": "sinchbot",
      "replying_to": {
        "from": "447537817391",
        "message_id": "01E7Q9AVTRB5A30JD7D9ZN0HTE"
      }
    }
  ]
}

Other samples of inbound messages

Sample inbound forwarded messageSample inbound frequently forwarded message
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "text",
        "body": "Hello bot I want to know something!"
      },
      "timestamp": "2020-05-02T17:43:32Z",
      "forwarded": true
    }
  ]
}
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "text",
        "body": "Hello bot I want to know something!"
      },
      "timestamp": "2020-05-03T07:28:54Z",
      "frequently_forwarded": true
    }
  ]
}

Interactive button reply message

This is the reply from an interactive button message. Don't confuse with the reply from a template quick reply button message above.

Name Description JSON Type
type Fixed value interactive. String
message An object containing the button reply Object

The button reply has the following fields:

Name Description JSON Type
type Fixed value button. String
id The ID of the button. String
title The title of the button. String
Copy
Copied
{
  "type" : "whatsapp",
  "notifications" : [
    {
      "from" : "0732001122",
      "message_id" : "01DPNXZ0WCF9XD19MH84XD0P62",
      "message" : {
        "type" : "interactive",
        "message" : {
          "type" : "button",
          "id" : "Reply button id 1",
          "title" : "Reply button title 1"
        }
      },
      "timestamp" : "2021-06-07T13:38:36Z",
      "to" : "sinchbot",
      "replying_to": {
        "from": "447537817391",
        "message_id": "01E7Q9AVTRB5A30JD7D9ZN0HTE"
      }
    }
  ]
}

Order message

This message type represents an order of products sent in response to a product message or a product list message.

Name Description JSON Type
type Fixed value order. String
text A text message. String
catalog_id The ID of the product catalog to which the products in the order belong. String
product_items An array of product item objects describing the products ordered. Array

Each product item object in the product_items array has the following fields:

Name Description JSON Type
product_retailer_id The product ID of the product being ordered. String
quantity The quantity of the product that is being ordered. Number
item_price The price for one unit of the product Number
currency The currency of the item_price. String
Copy
Copied
{
  "type" : "whatsapp",
  "notifications" : [
    {
      "from" : "0732001122",
      "message_id" : "01DPNXZ0WCF9XD19MH84XD0P62",
      "message" : {
        "type" : "order",
        "text" : "Here's my order",
        "catalog_id" : "catalogid",
        "product_items" : [
          {
            "product_retailer_id" : "product1",
            "quantity" : 10,
            "item_price" : 10.2,
            "currency" : "USD"
          },
          {
            "product_retailer_id" : "product2",
            "quantity" : 2,
            "item_price" : 4,
            "currency" : "SEK"
          }
        ]
      },
      "timestamp" : "2021-06-07T13:38:36Z",
      "to" : "sinchbot"
    }
  ]
}

Find more order message examples here.

Interactive list reply message

This is the reply from an interactive list message.

Name Description JSON Type
type Fixed value interactive. String
message An object containing the list reply String

The button reply has the following fields:

Name Description JSON Type
type Fixed value list. String
id The ID of the button. String
title The title of the button. String
description The description of the button, if included when sending the list message String
Copy
Copied
{
  "type" : "whatsapp",
  "notifications" : [
    {
      "from" : "0732001122",
      "message_id" : "01DPNXZ0WCF9XD19MH84XD0P62",
      "message" : {
        "type" : "interactive",
        "message" : {
          "type" : "list",
          "id" : "ID 1",
          "title" : "Title",
          "description" : "Description",
        }
      },
      "timestamp" : "2021-06-07T13:38:36Z",
      "to" : "sinchbot",
      "replying_to": {
        "from": "447537817391",
        "message_id": "01E7Q9AVTRB5A30JD7D9ZN0HTE"
      }
    }
  ]
}

Contacts message

Name Description JSON Type
type Fixed value contacts String
contacts Array of contact objects Array[Object]

Contact object

Name Description JSON Type
addresses Array of contact address(e) Array[Object]
birthday Contact's birthday, YYYY-MM-DD formatted string String
emails Array of contact email address(es) Array[Object]
ims Array of message contact information Array[String]
name Contact full name information Object
org Contact organization information Object
phones Array of contact phone number(s) Array[Object]
urls Array of contact URL(s) Array[Object]
contact_image_url The public URL of the contact image. Doesn't contain WhatsApp profile picture, but the image in the phone itself String

Contact address

Name Description JSON Type
type Type of address, HOME, WORK String
street Street number and address String
city City name String
state State abbreviation String
zip ZIP code String
country Full country name String
country_code Two-letter country abbreviation String

Contact email

Name Description JSON Type
type Type of email address, HOME, WORK String
email Email address String
Contact IM
Name Description JSON Type
service Type of service String
user_id User identifier on service String

Contact name

Name Description JSON Type
formatted_name Full name as it normally appears String
first_name First name String
last_name Last name String
middle_name Middle name String
suffix Name suffix String
prefix Name prefix String

Contact organization

Name Description JSON Type
company Name of the contact's company String
department Name of the contact's department String
title Contact's business title String

Contact phone number

Name Description JSON Type
type Type of phone number, CELL, MAIN, HOME, WORK, IPHONE String
phone Automatically populated with the WhatsApp phone number of the contact String

Contact URL

Name Description JSON Type
type Type of URL HOME, WORK String
url URL String
Copy
Copied
{
  "type": "whatsapp",
  "contacts": [
    {
      "profile": {
        "name": "John Smith"
      },
      "wa_id": "0732001122"
    }
  ],
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "contacts",
        "contacts": [
          {
            "addresses": [
              {
                "city": "Menlo Park",
                "country": "United States",
                "country_code": "us",
                "state": "CA",
                "street": "1 Hacker Way",
                "type": "HOME",
                "zip": "94025"
              }
            ],
            "birthday": "2012-08-18",
            "emails": [
              {
                "email": "test@fb.com",
                "type": "WORK"
              }
            ],
            "name": {
              "first_name": "John",
              "formatted_name": "John Smith",
              "last_name": "Smith"
            },
            "org": {
              "company": "WhatsApp",
              "department": "Design",
              "title": "Manager"
            },
            "phones": [
              {
                "phone": "+1 (650) 555-1234",
                "type": "WORK",
                "wa_id": "16505551234"
              }
            ],
            "urls": [
              {
                "url": "https://www.facebook.com",
                "type": "WORK"
              }
            ]
          }
        ]
      },
      "timestamp": "2020-05-02T17:23:55Z"
    }
  ]
}

Media message

Name Description JSON Type
type Fixed value image, document, audio, video, voice, sticker String
url The public url of the media file String
mime_type Mime type of the media file String
caption Caption of the media file String
filename Optional filename, only valid for audio and document String
metadata Optional sticker metadata, only used for stickers Object
Note

Media URLs expire after seven days.

The sticker metadata object has the following parameters:

Name Description JSON Type
stickerpack-id The id of the stickerpack the sticker belongs to String
stickerpack-name The name of the stickerpack the sticker belongs to String
stickerpack-publisher The publisher of the stickerpack the sticker belongs to String
emojis The emojis included in the stickerpack the sticker belongs to Array[String]
ios-app-store-link A link to the stickerpack the sticker belongs to in the Apple iOS App Store String
android-app-store-link A link to the stickerpack the sticker belongs to in the Google Play store String
is-first-party-sticker 1 if the sticker is part of a first-party stickerpack, 0 otherwise Integer
Sample inbound image messageSample inbound audio message with a product reference
Copy
Copied
{
  "type": "whatsapp",
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "image",
        "url": "http://www.example.com/img.jpg",
        "mime_type": "image/jpeg",
        "caption": "Fantastic headphones"
      },
      "timestamp": "2020-05-02T15:43:52Z"
    }
  ]
}
Copy
Copied
{
  "type": "whatsapp",
  "notifications": [
    {
      "from": "0732001122",
      "to": "sinchbot",
      "message_id": "01DPNXZ0WCF9XD19MH84XD0P62",
      "message": {
        "type": "audio",
        "filename": "Question",
        "caption": "Caption",
        "url": "http://www.example.com/audio.ogg",
        "mime_type": "audio/ogg",
        "referred_product": {
          "catalog_id": "catalogid",
          "product_retailer_id": "productretailerid",
        }
      },
      "timestamp": "2020-05-02T15:43:52Z"
    }
  ]
}

Error notification

In case an error happens, an error notification can be sent.

Name Description JSON Type
type Fixed value error. String
details A description of the error. String
Copy
Copied
{
  "type": "whatsapp",
  "notifications": [
    {
      "from": "46702291874",
      "message_id": "01E7T5K8CREY9K0HGZW3ME1F26ABGGRnAiI1JfAhC5kP7rPIamw3JHBDfxEzvm",
      "message": {
        "type": "error",
        "details": "Unexpected callback contents received. Remember to add quick reply buttons to the request payload when sending the message template, even if no quick reply button payload is added."
      },
      "timestamp": "2020-05-08T12:54:07Z",
      "to": "bot_id",
      "replying_to": {
        "from": "447537918329"
      }
    }
  ]
}

Mark inbound message as read

For each incoming message you can inform a WhatsApp User that his message has been read.

Request

POST /whatsapp/v1/{bot-id}/events

JSON object parameters:

Name Description JSON Type Default Constraints Required
type Fixed value read String N/A read Yes
message_id ID of incoming message String N/A Valid message ID Yes
Copy
Copied
{
  "type": "read",
  "message_id": "01E7SP2FX8E16R0X3GE8Z41VSQABGGSFATkBVvAgo61AND5uEmlo54"
}

Response

201 CREATED

Message has been marked as read and WhatsApp user will now see two blue ticks under this message.

400 Bad Request

There was an error with your request. The body is a JSON object described in the introduction

401 Unauthorized

There was an authentication error with your request. Either you're using incorrect credentials or you're attempting to authenticate in a region where your bot doesn't reside. The body is a JSON object described in the introduction

500 Internal Server Error

There was an error with your request. The body is a JSON object described in the introduction

Was this page helpful?