πŸ’¬ SalesByte

Settings

Manage your profile, team, notifications, templates, and billing.

Profile

Go to Settings β†’ Profile to update your name, WhatsApp number (used for notifications), and avatar.

Team

Go to Settings β†’ Team to invite new members, change roles, or remove someone from your workspace.

Notifications

Go to Settings β†’ Notifications to control:

  • Which events send you a WhatsApp message (follow-up due, campaign complete, connection lost, etc.)
  • Which events send you an email
  • Turn off specific notification types

Templates

Go to Settings β†’ Templates to create, edit, and manage all your message templates.

Template guide β†’

Occasion Greetings

Go to Settings β†’ Occasion Greetings to set up automatic birthday and anniversary messages.

Pick a template for birthdays and a separate one for anniversaries. SalesByte sends them automatically at 9 AM IST on the right day β€” as long as you've saved the contact's birthday or anniversary date.

Webhooks

Go to Settings β†’ Webhooks to send real-time events to your own server when things happen in SalesByte (e.g. message received, message delivered).

A message.received event looks like this:

{
  "event": "message.received",
  "workspace_id": "...",
  "timestamp": "2026-10-01T10:00:00.000Z",
  "data": {
    "channel": "business",
    "connection_id": "...",
    "received_on": "+919811122233",
    "wa_message_id": "3EB0...",
    "phone": "+919876543210",
    "contact_name": "Raj Kumar",
    "body": "Hello, I'm interested"
  }
}
FieldMeaning
channelbusiness (Business WhatsApp) or personal (Personal WhatsApp)
received_onYour own number the message arrived on, as +<country code><number>
connection_idWhich of your connected numbers received it
phoneThe sender's number

If you have more than one number connected, use channel or received_on to decide how to handle each message β€” for example, letting a bot answer only messages that arrive on your Business WhatsApp number.

On a Business number, a bot can pass this event's wa_message_id to POST /api/v1/messages/read to turn the customer's ticks blue and show typing… while it prepares a reply.

Depending on the message, message.received can also carry:

FieldWhenMeaning
interactive_type, interactive_payloadThe customer tapped a button, picked a list row, or submitted a Flow (Business WhatsApp)interactive_type is button_reply, list_reply or nfm_reply. For a button or list, interactive_payload holds the button_id / list_id you set when sending, and its title. For a Flow, interactive_payload.response holds the customer's answers.
group_jid, group_name, sender_name, sender_phoneThe message was posted in a WhatsApp group (Personal WhatsApp)Which group it was, and who in the group sent it (sender_phone when known). phone is not set for a group message.
reply_toThe customer replied to a specific message (swipe to reply), or tapped a button on one{ "message_id": "...", "text": "..." }. message_id is the id the send API returned for that original message, so you can match the reply to your own send. text is the quoted text when available (Personal WhatsApp), otherwise null. reply_to is null for an ordinary message.
attachment_type, attachment_name, media_urlThe customer sent a photo, video, voice note or documentattachment_type is image, video, audio or document; media_url is a private link to a copy of the file stored with us. It works for 7 days, so download the file if you need to keep it (null if the file could not be downloaded).
{
  "event": "message.received",
  "data": {
    "channel": "business",
    "phone": "+919876543210",
    "body": "Confirm",
    "interactive_type": "button_reply",
    "interactive_payload": { "button_id": "confirm", "button_title": "Confirm" },
    "reply_to": { "message_id": "wamid.HBgM...", "text": null }
  }
}

message.sent, message.delivered, message.read and message.failed events carry the same identifying fields:

{
  "event": "message.delivered",
  "workspace_id": "...",
  "timestamp": "2026-10-01T10:00:05.000Z",
  "data": {
    "channel": "business",
    "connection_id": "...",
    "sent_from": "+919811122233",
    "phone": "+919876543210",
    "wa_message_id": "wamid.HBgM...",
    "delivery": "delivered"
  }
}

Here sent_from is your number and phone is the person the message went to. These events are only sent for messages you sent β€” a customer's message being read on your own phone does not produce a message.read. message.failed also includes error_code and error_title. For a message sent to a group, phone is null and group_jid identifies the group.

Status order (Business WhatsApp): each message produces at most one event per step β€” message.sent (WhatsApp accepted it), then message.delivered, then message.read β€” or message.failed. If WhatsApp repeats a status, or reports an older one late, no duplicate event is sent. message.sent is new: choose Message sent when adding an endpoint in Settings β†’ Webhooks (for an existing endpoint, ask support to add it).

Verifying the signature

Every webhook request includes an X-SalesByte-Signature header: sha256= followed by the hex HMAC-SHA256 of the raw request body, keyed with your endpoint's signing secret. Find the secret under Settings β†’ Webhooks β†’ Reveal on your endpoint (use Rotate if it's ever exposed).

import crypto from "node:crypto";
 
function isFromSalesByte(rawBody, signatureHeader, secret) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Compute the HMAC over the body exactly as received, before parsing it as JSON β€” re-serializing can change spacing and break the match.

Webhook docs β†’

On this page