API Reference

DoubleTick supports webhooks that can alert you of the following via callback URLs.

How to add a webhook to DoubleTick

  1. Head on to Doubletick Web and open settings from the sidebar and click on webhooks. Then click on the New webhook button.

  2. Enter a fully qualified webhook URL and choose the events you would like to capture with the webhook and click on Save webhook.


  1. Once saved, you can see the webhooks with their respective count of events


Webhooks supported by DoubleTick

1. Message Received

This webhook is triggered whenever an existing or a new customer sends any supported message to your registered number. The list of supported messages include: Text; media such as image, video, stickers, audio; document messages such as PDF, word, etc; location message; phonebook contact message; and button reply messages

Payload Structure

NameTypeNullableNotes
tostringNoAPI Number
fromstringYesCustomer mobile number
messageIdstringNoUnique id of message
dtMessageIdstringNoUnique id of message (you can use this to track message status updates via Message Status Webhook)
pairedMessageIdstringYesmessageId of the previous message if this message is a reply to that previous message
dtPairedMessageIdstringYesdtMessageId of the previous message if this message is a reply to that previous message
receivedAtstringyesDate of message received (in ISO Format)
integrationTypestringYesIntegrationType (WHATSAPP)
statusstringYesStatus of message
messageMessageNoMessage body
contactstringNoThe contact who sent the message

Message

NameTypeNullableNotes
typeTEXT | IMAGE | VIDEO | AUDIO | DOCUMENT | LOCATION | CONTACTS | BUTTON | TEMPLATE | INTERACTIVENoType of message
textstring-Present when type is TEXT
urlstring-Present when type is IMAGE | VIDEO | AUDIO | DOCUMENT
captionstringYesPresent when type is IMAGE | VIDEO | AUDIO | DOCUMENT and a caption was added to the message by the sender
payloadstring-Present when type is BUTTON
namestring-Present when type is LOCATION
addressstring-Present when type is LOCATION
latitudestring-Present when type is LOCATION
longitudestring-Present when type is LOCATION
templateMessageTemplateMessage-Present when type is TEMPLATE and message is sent
interactiveMessageInteractiveMessage-Present when type is INTERACTIVE and message is sent
contactsList of Contacts-Present when type is CONTACTS
contextContextYesContext of the message

Context

NameTypeNullableNotes
idstringYesmessageId of the previous message if this message is a reply to that previous message
fromstringYesWhatsApp Id of the sender of the original message

Contacts

NameTypeNullableNotes
nameNameYesName properties
phonesPhoneYesPhone properties

Name

NameTypeNullableNotes
first_namestringYesFirst name
last_namestringYesLast name
formatted_namestringNoFormatted name

Phone

NameTypeNullableNotes
phonestringNoPhone number
typestringNoType of phone number
waIdstringNoWhatsapp id

TemplateMessage

NameTypeNullableNotes
headerTemplateMessageHeader-Header of template
bodyTemplateMessageTextNoBody of template
footerTemplateMessageText-Footer of template
buttonArray of TemplateMessageButton-List of Buttons present in template
templateNamestringNoName of template
templateLanguagestringNoLanguage of template

TemplateMessageHeader

NameTypeNullableNotes
typetext | image | video | documentNoType of the template header
textstring-Present when type is text
urlstring-Present when type is image / video / document
fileNamestringYesPresent when type is document

TemplateMessageText

NameTypeNullableNotes
typetext-
textstring-

TemplateMessageButton

NameTypeNullableNotes
typeQUICK_REPLY | URL | PHONE_NUMBERNobutton type
textstringNobutton text
payloadstringYesPresent when type is QUICK_REPLY
urlstring-Present when type is URL
phoneNumberstring-Present when type is PHONE_NUMBER

InteractiveMessage

NameTypeNullableNotes
typelist | buttonNoInteractive message type
headerInteractiveMessageHeaderText | InteractiveMessageHeaderMediaYesFor type = button, both Text and Media can be present; For type = list, only Text can be present
bodyInteractiveTextNoBody type
footerInteractiveTextYesFooter type
sectionsArray of InteractiveMessageListSection-Present when type is LIST
buttonsArray of InteractiveMessageButton-Present when type is BUTTON
buttonstring-Present when type is LIST

InteractiveText

NameTypeNullableNotes
textstring-

InteractiveMessageHeaderText

NameTypeNullableNotes
typetext-
textstring-

InteractiveMessageHeaderMedia

NameTypeNullableNotes
typeimage | video | documentNoMedia types for header
fileTypeSupportedMediaTypesNoTable for supported media types
urlstringNoPresent for all types
sizenumberNoPresent for all types
fileNamestringYesPresent when type is document

SupportedMediaTypes

NameType
imageimage/jpeg' , image/png
videovideo/mp4 , video/3gpp
documenttext/plain, application/pdf, application/vnd.ms-powerpoint, application/msword, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

InteractiveMessageListSection

NameTypeNullableNotes
titlestringYes
rowsArray of InteractiveMessageListSectionRowNo

InteractiveMessageListSectionRow

NameTypeNullableNotes
titlestringNo
idstringNo
descriptionstringYes

InteractiveMessageButton

NameTypeNullableNotes
titlestringNo
idstringNo

Sample Payload for Receive Text Message

{
    "to": "15550090106",
    "from": "919999999999",
    "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
    "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
    "receivedAt": "2022-12-15T10:27:00.000Z",
    "contact": {
        "name": "Contact Name"
    },
    "integrationType": "WHATSAPP",
    "message": {
        "type": "TEXT",
        "text": "Ok",
        "context": {}
    }
}

Sample Payload for Receive Text Message (which is a reply to some previous message)

{
    "to": "15550090106",
    "from": "919999999999",
    "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
    "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
    "pairedMessageId": "HBgMOTE3MDM4ODk2MTQwFQIAERgSMzAwRUE1Nzg0REJDOTgzRTM1AA==",
    "dtPairedMessageId": "01c6106d-916e-4dd7-b4b5-c295467fb411",
    "receivedAt": "2022-12-15T10:27:00.000Z",
    "contact": {
        "name": "Contact Name"
    },
    "integrationType": "WHATSAPP",
    "message": {
        "type": "TEXT",
        "text": "Ok",
        "context": {
          "from": "15550090106",
        	"id": "HBgMOTE3MDM4ODk2MTQwFQIAERgSMzAwRUE1Nzg0REJDOTgzRTM1AA=="
        }
    }
}

Sample Payload for Receive Image Message

{
  "to": "15550090106",
  "from": "919999999999",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-15T10:27:00.000Z",
  "contact": {
    "name": "Contact Name"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "IMAGE",
    "caption": "This is a caption",
    "url": "https://via.placeholder.com/300.jpg",
    "context": {}
  }
}

Sample Payload for Receive Audio Message

{
  "to": "15550090106",
  "from": "919999999999",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-15T10:27:00.000Z",
  "contact": {
    "name": "Contact Name"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "AUDIO",
    "url": "https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3",
    "context": {}
  }
}

Sample Payload for Receive Video Message

{
  "to": "15550090106",
  "from": "919999999999",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-15T10:27:00.000Z",
  "contact": {
    "name": "Contact Name"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "VIDEO",
    "url": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
    "context": {}
  }
}

Sample Payload for Receive Document Message

{
  "to": "15550090106",
  "from": "919999999999",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-15T10:27:00.000Z",
  "contact": {
    "name": "Contact Name"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "DOCUMENT",
    "url": "https://www.africau.edu/images/default/sample.pdf",
    "context": {}
  }
}

Sample Payload for Receive Button Message

{
  "to": "15550090106",
  "from": "919999999999",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-15T10:27:00.000Z",
  "contact": {
    "name": "Contact Name"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "BUTTON",
    "text": "Click Me",
    "payload": "Click Me",
    "context": {}
  }
}

Sample Payload for Receive Location Message

{
    "to": "15550090106",
    "from": "919999999999",
    "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0FGMjcxNEY2NjVFQzBFMEE0MkYA",
    "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
    "receivedAt": "2022-12-15T10:27:00.000Z",
    "contact": {
        "name": "Contact Name"
    },
    "integrationType": "WHATSAPP",
    "message": {
        "type": "LOCATION",
        "name": "QuickSell Inc",
        "address": "98, Bhagwandas Todi Bal Udyan Marg",
        "latitude": 18.944149017334,
        "longitude": 72.824394226074,
        "context": {}
    }
}

Sample Payload for Receive Contact Message

{
  "to": "15550090106",
  "from": "917600728254",
  "messageId": "HBgMOTE3NjAwNzI4MjU0FQIAEhgUM0E5NjdENzA5ODIwQTRDQkEwQ0QA",
  "dtMessageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "receivedAt": "2022-12-19T17:33:45.000Z",
  "contact": {
    "name": "Abhideep"
  },
  "integrationType": "WHATSAPP",
  "message": {
    "type": "CONTACTS",
    "contacts": [
      {
        "name": {
          "first_name": "Yogesh",
          "last_name": "DoubleTick",
          "formatted_name": "Yogesh DoubleTick"
        },
        "phones": [
          {
            "phone": "+91 99999 99999",
            "type": "Mobile",
            "waId": "919999999999"
          }
        ]
      }
    ],
    "context": {}
  }
}

2. Sent Message Status

This webhook is triggered whenever a sent message's status changes.

For ex: sent message changes from sent to delivered to read. To optimise the system, there may be some cases where the read status change is sent but the delivered status change is not sent. In such cases, please assume that the message was also delivered at the same time

Payload Structure

NameTypeNullableNotes
statusSENT | DELIVERED | READ | FAILEDNoSent message status
messageIdstringNoId of sent message. Same as the dtMessageId in the Receive Message webhook payload
messageMessageNopresent only if status is equal to SENT or FAILED
tostringNoCustomer number
statusTimeStampstringNoISO formatted string of the timestamp when the message status changed
failMessagestringYesError message (present if status is FAILED)

Sample payload for Message sent status

{
  "status": "SENT",
  "messageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "to": "919999999999",
  "statusTimestamp": "2022-12-15T07:36:24.504Z",
  "message": {
    "type": "template",
    "templateMessage": {
      "header": {
        "type": "text",
        "text": "This is Template Header"
      },
      "body": {
        "type": "text",
        "text": "This is Template Body"
      },
      "footer": {
        "type": "text",
        "text": "This is Template Footer"
      },
      "button": [
        {
          "type": "QUICK_REPLY",
          "text": "Click here",
          "payload": "Click here"
        }
      ]
    },
    "templateName": "template_1",
    "templateLanguage": "en"
  }
}            

Sample payload for Message delivered status

 {
  "status": "DELIVERED",
  "messageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "to": "919999999999",
  "statusTimestamp": "2022-12-15T07:36:24.504Z"
}

Sample payload for Message read status

{
  "status": "READ",
  "messageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "to": "919999999999",
  "statusTimestamp": "2022-12-15T07:36:24.504Z"
}

Sample payload for Message failed status

{
  "status": "FAILED",
  "messageId": "3bf23c11-6c34-4c1e-b259-12a0e518d3cd",
  "to": "919999999999",
  "statusTimestamp": "2022-12-15T07:36:24.504Z",
  "failMessage": "Error Description",
  "message": {
    "type": "template",
    "templateMessage": {
      "header": {
        "type": "text",
        "text": "This is Template Header"
      },
      "body": {
        "type": "text",
        "text": "This is Template Body"
      },
      "footer": {
        "type": "text",
        "text": "This is Template Footer"
      },
      "button": [
        {
          "type": "QUICK_REPLY",
          "text": "Click here",
          "payload": "Click here"
        }
      ]
    },
    "templateName": "template_1",
    "templateLanguage": "en"
  }
}

3. Template Update

This webhook is triggered whenever a template status changes.

Payload Structure

NameTypeNullableNotes
eventTEMPLATE_STATUS_UPDATENoEvent type for status update of template
wabaPhoneNumberstringNoWhatsApp number to which the template belongs
templateNamestringNoName of the template
newStatusAPPROVED | PAUSED | REJECTED | PENDINGNoUpdated status of template
oldStatusAPPROVED | PAUSED | REJECTED | PENDINGNoOld status of template
templateLanguagestringNoLanguage of the template
rejectedReasonstringYesPresent when the newStatus is REJECTED

Sample payload for Template status change

{
  "event": "TEMPLATE_STATUS_UPDATE",
  "wabaPhoneNumber": "1415523888",
  "templateName": "test_template",
  "newStatus": "APPROVED",
  "oldStatus": "PENDING",
  "templateLanguage": "en",
  "rejectedReason": null
}

Sample payload for Template status change to REJECTED

{
  "event": "TEMPLATE_STATUS_UPDATE",
  "wabaPhoneNumber": "1415453888",
  "templateName": "test_template_1",
  "newStatus": "REJECTED",
  "oldStatus": "PENDING",
  "templateLanguage": "en",
  "rejectedReason": "INVALID_FORMAT"
}