AISARAISAR
All webhooks

Messages

Message created

message.created

Fires when a new message is created — inbound from a contact or outbound from a user or the system. For ad-originated messages (e.g. WhatsApp Click-to-Message ads) the payload includes a referral object with ad details. WhatsApp quick-reply and interactive button taps are normalized into a regular text message: the button label goes to content.text and the button payload to content.interactive_reply_payload.

HTTP request

AISAR sends a signed POST request to your webhook_url:

http
POST {webhook_url}
Content-Type: application/json
X-AISAR-Signature: sha256=...

{
  "event": "message.created",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-22T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message": {
      "id": 123,
      "external_id": "3EB0ABC123456789",
      "conversation_id": 45,
      "thread_id": 67,
      "channel_id": 2,
      "direction": "inbound",
      "type": "text",
      "content": {
        "text": "Hello, I need help"
      },
      "display_content": "Hello, I need help",
      "media": null,
      "reply_to_message_id": null,
      "is_deleted": false,
      "system_notification": false,
      "created_at": "2026-03-22T12:00:00.000000Z"
    },
    "sender": {
      "type": "contact",
      "contact_id": 10,
      "contact_account_id": 15,
      "name": "John Doe",
      "phone": "+77001234567",
      "email": "john@example.com",
      "external_id": "77001234567@s.whatsapp.net"
    },
    "recipient": null,
    "conversation": {
      "id": 45,
      "status": "active",
      "contact_id": 10,
      "deal_id": null,
      "subject": null,
      "is_archived": false,
      "is_group": false
    },
    "channel": {
      "id": 2,
      "type": "whatsapp",
      "name": "Main WhatsApp"
    },
    "is_dialog_assigned": false,
    "referral": null
  }
}

The X-AISAR-Signature header carries an HMAC-SHA256 signature of the request body — use it to verify the request came from AISAR.

Example payload

json
{
  "event": "message.created",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-22T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message": {
      "id": 123,
      "external_id": "3EB0ABC123456789",
      "conversation_id": 45,
      "thread_id": 67,
      "channel_id": 2,
      "direction": "inbound",
      "type": "text",
      "content": {
        "text": "Hello, I need help"
      },
      "display_content": "Hello, I need help",
      "media": null,
      "reply_to_message_id": null,
      "is_deleted": false,
      "system_notification": false,
      "created_at": "2026-03-22T12:00:00.000000Z"
    },
    "sender": {
      "type": "contact",
      "contact_id": 10,
      "contact_account_id": 15,
      "name": "John Doe",
      "phone": "+77001234567",
      "email": "john@example.com",
      "external_id": "77001234567@s.whatsapp.net"
    },
    "recipient": null,
    "conversation": {
      "id": 45,
      "status": "active",
      "contact_id": 10,
      "deal_id": null,
      "subject": null,
      "is_archived": false,
      "is_group": false
    },
    "channel": {
      "id": 2,
      "type": "whatsapp",
      "name": "Main WhatsApp"
    },
    "is_dialog_assigned": false,
    "referral": null
  }
}

Payload fields

FieldTypeDescription
message.idintegerInternal message ID
message.external_idstringExternal message ID (platform-specific, e.g. WhatsApp message ID)
message.conversation_idintegerConversation ID
message.thread_idintegerThread ID
message.channel_idintegerChannel ID
message.directionstringinbound (from contact) or outbound (from user/system)
message.typestringMessage type: text, image, video, audio, voice, document, sticker, location, contact, reaction, poll. voice is a voice note (recorded audio, OGG/Opus); plain audio is an audio file. WhatsApp quick-reply / interactive button taps are normalized to text
message.contentobject|stringMessage content. For text: {"text": "..."}. For media it includes caption, mime_type, etc. For button taps it also carries interactive_reply_payload — the button payload / list option id (null when the template button has no payload)
message.display_contentstring|nullPlain text representation of the message content
message.mediaarray|nullAttachments array; null if the message has no media
message.media[].typestringAttachment type: image, video, audio, voice, document, sticker
message.media[].urlstringDownload URL
message.media[].filenamestring|nullOriginal filename
message.media[].mime_typestring|nullMIME type (e.g. image/jpeg; voice notes are audio/ogg)
message.media[].sizeinteger|nullFile size in bytes
message.media[].durationinteger|nullDuration in seconds (audio / voice / video)
message.reply_to_message_idinteger|nullID of the quoted message, if this is a reply
message.is_deletedbooleanWhether the message has been deleted
message.system_notificationbooleanWhether this is a system notification
message.created_atstringISO 8601 timestamp
sender.typestringcontact for inbound messages, user for outbound
sender.contact_idintegerContact ID (inbound messages)
sender.contact_account_idintegerContact account ID (inbound messages)
sender.user_idintegerUser ID (outbound messages)
sender.namestringSender display name
sender.phonestring|nullContact phone number (inbound messages)
sender.emailstring|nullSender email
sender.external_idstringPlatform-specific contact ID, e.g. 77001234567@s.whatsapp.net (inbound messages)
recipientobject|nullPresent only for outbound messages: the recipient contact, same structure as sender with type=contact
conversation.idintegerConversation ID
conversation.statusstringactive or closed
conversation.contact_idintegerContact ID
conversation.deal_idinteger|nullAssociated deal ID
conversation.subjectstring|nullConversation subject
conversation.is_archivedbooleanWhether the conversation is archived
conversation.is_groupbooleantrue if this conversation is a group chat (e.g. a WhatsApp group), false for direct messages
channel.idintegerChannel ID
channel.typestringChannel type: whatsapp, whatsapp_business, instagram, telegram
channel.namestringChannel name
is_dialog_assignedbooleantrue if a user is assigned to this conversation, false otherwise
referralobject|nullReferral data for ad-originated messages (e.g. WhatsApp Click-to-Message ads from Facebook/Instagram); null for regular messages
referral.source_urlstringURL of the ad or post
referral.source_typestringSource type: ad or post
referral.source_idstringAd or post ID; can be used with the Meta API to get campaign details
referral.headlinestringAd headline text
referral.bodystringAd body text
referral.ctwa_clidstringClick tracking ID for precise attribution
referral.media_typestringMedia type in the ad: image or video
referral.image_urlstringURL of the ad image (if applicable)
referral.video_urlstringURL of the ad video (if applicable)