Webhooks

Lodgestory CRM › Settings → Webhooks

Added On Request

Webhooks

Get real-time notifications in your own systems the moment something happens in Lodgestory — a message sent or received, a ticket created, a campaign finished, a channel connected.

TL;DR

  • What it is — you register an HTTPS endpoint, choose which events you care about, and Lodgestory sends a signed notification to that endpoint whenever one of those events happens, across every channel.
  • Who it's for — developers and technical teams who want to sync Lodgestory activity into a CRM, data warehouse, helpdesk, or any internal tool.
  • Top outcome — no polling. Your systems learn about messages, tickets, contacts, campaigns, and channel changes within seconds of them happening.

At a glance

Plan tiersAll paid tiers.
Who can use itAdmins and Account Owners create and manage endpoints.
Channels coveredAll — WhatsApp, Instagram, Messenger, Email, and Web Chat.
Events14 event types across messages, templates, tickets, contacts, chat workflow, campaigns, and channels.
Top limitsUp to 3 endpoints per organisation. Up to 30 custom headers per endpoint.
DeliverySigned (HMAC-SHA256), automatically retried, with a delivery log you can inspect and replay.
APIYes — manage endpoints and view deliveries via the admin API; receive events at your own endpoint.

How to find it

Sidebar: Settings → Webhooks.

Direct URL: https://lodgestory.com/crm/settings/webhooks

[SCREENSHOT: webhooks-landing.png — list of configured endpoints with status, events, and actions]

What is Webhooks?

The problem it solves

Most teams that want Lodgestory data in another system end up polling our API on a timer — asking "anything new?" over and over. That's slow, wasteful, and always a little behind. Webhooks flip it around: instead of you asking, Lodgestory tells you the instant something happens, so your CRM, data warehouse, or internal dashboard stays in sync in near real time.

What you get

  • Real-time event delivery — events reach your endpoint within seconds of happening.
  • Full coverage — one place to subscribe to messages, delivery statuses, templates, tickets, contacts, chat-workflow transitions, campaigns, and channel connect/disconnect, across every channel.
  • The whole record, not just an ID — each notification carries the full object (the message, the ticket, the contact), so you usually don't need a follow-up API call.
  • Signed and verifiable — every delivery is signed with a secret only you and Lodgestory know, so you can confirm it really came from us.
  • Reliable delivery — failed deliveries are retried automatically with increasing delays; a delivery log lets you see exactly what happened and replay anything.

How it's different

You subscribe once and receive a single, consistent notification format for every event type — the same envelope whether it's a WhatsApp message, an email, a ticket assignment, or a campaign completion. The event type tells you what happened; the payload always carries the full object. That uniformity makes it fast to build one handler that routes everything.

Customer scenarios

  • A hotel group syncing to their PMS — every inbound guest message and ticket is pushed into their property-management system the moment it arrives, so front-desk staff see context without opening Lodgestory.
  • An agency with a data warehouse — campaign completions and message delivery statuses stream into their warehouse for reporting, with no nightly export job.
  • A team with a custom on-call toolticket.created and ticket.assigned events page the right person instantly.

How it fits with the rest of Lodgestory

Webhooks observe the rest of the platform — the Unified Inbox, Tickets, Campaigns, Contacts, WhatsApp Templates, Workflow Lifecycle Stages, and Connections — and forward those events to you.

[SCREENSHOT: webhooks-create.png — the add-endpoint form with URL field and event checkboxes grouped by category]

Core concepts

  • Endpoint — an HTTPS URL you own that receives event notifications. You can have up to 3 per organisation.
  • Event — something that happened in Lodgestory (for example, message.received). You choose which events each endpoint receives.
  • Signing secret — a unique secret generated for each endpoint. Lodgestory uses it to sign every delivery so you can verify authenticity. You can view or rotate it at any time.
  • Delivery — a single attempt (with retries) to send one event to one endpoint. Every delivery is recorded in the log.
  • Delivery log — the recent history of deliveries for an endpoint, including status, response code, and number of attempts. You can resend any past delivery.

Quick Start — receive your first event in 5 minutes

Step 1 — Open Webhooks

Go to Settings → Webhooks and click Add Endpoint.

[SCREENSHOT: webhooks-addbutton.png]

Step 2 — Enter your endpoint URL

Paste the HTTPS URL that will receive events (for example, https://example.com/webhooks/lodgestory). Add an optional description so your team knows what it's for.

Step 3 — Choose your events

Tick the events you want this endpoint to receive, or use Select all. You can change this later.

[SCREENSHOT: webhooks-events.png — event checkboxes grouped by Messages, Templates, Tickets, Contacts & Campaigns, Chat Workflow, Channels]

Step 4 — Save and copy your signing secret

When you create the endpoint, Lodgestory shows your signing secret once. Copy it and store it securely — you'll use it to verify deliveries. You can always copy or rotate it later from the endpoint's row.

[SCREENSHOT: webhooks-secret.png — the signing-secret reveal dialog with a copy button]

Step 5 — Send a test event

Click Send test on the endpoint to fire a sample notification at your URL, then check it arrived and that your signature check passes.

Step 6 — Verify and go live

Once your endpoint returns a success response (any 2xx) to the test, you're live. Real events will start flowing as they happen.

How it works

  1. Something happens in Lodgestory — a message is sent or received, a ticket changes, a campaign finishes.
  2. Lodgestory checks which of your endpoints subscribe to that event.
  3. For each matching endpoint, Lodgestory builds a standard notification, signs it with that endpoint's secret, and delivers it to your URL.
  4. If your endpoint doesn't respond with a success code, Lodgestory automatically retries with increasing delays — up to 6 attempts. Each delivery is recorded in the log.
  5. If an endpoint keeps failing over many events, Lodgestory pauses it automatically so it isn't hammered. You can re-enable it once it's fixed.

Behind the scenes Lodgestory does all of this asynchronously, so sending events never slows down your messaging or your team's inbox.

Features in depth

Choose exactly what you receive

Each endpoint subscribes to its own set of events. Point one endpoint at your CRM for messages and contacts, and another at your on-call tool for tickets only.

One consistent notification format

Every event uses the same envelope. The event field tells you what happened; data.object tells you the type of record; and data carries the full object. Update-type events (statuses, assignments, workflow transitions) also include a previous_attributes block showing what changed.

Signed deliveries

Every request includes a signature header computed from your endpoint's secret. Verifying it confirms the request genuinely came from Lodgestory and wasn't altered in transit. (See API → Verifying deliveries.)

Automatic retries and auto-pause

Temporary outages on your side are handled for you: failed deliveries are retried automatically with growing delays. If an endpoint fails consistently across many events, it's paused so it stops receiving traffic until you re-enable it.

Delivery log, test, and replay

Open any endpoint's delivery log to see recent attempts with their status, response code, and attempt count. Send test fires a sample event on demand. Redeliver re-sends any past delivery — useful after you fix a bug on your side.

Rotate the secret

Rotate an endpoint's signing secret at any time (for example, if it may have leaked). Update your verification code with the new secret to continue accepting deliveries.

Roles & permissions

RoleCan do
Account Owner / AdminCreate, edit, enable/disable, and delete endpoints; view and rotate secrets; view delivery logs; send test events; replay deliveries.
Team member / AgentNo access to webhook settings.

Connections

  • Unified Inboxmessage.sent and message.received fire for every channel that lands in the inbox.
  • Ticketsticket.created, ticket.status_changed, and ticket.assigned keep an external helpdesk or on-call tool in sync.
  • Campaignscampaign.created and campaign.completed let you track broadcast progress in your own reporting.
  • Contactscontact.created notifies you when a new contact is added from a conversation or the create-contact action.
  • WhatsApp Templatestemplate.created and template.status_updated tell you when a template is submitted and when Meta approves or rejects it.
  • Workflow Lifecycle Stageschat.state_changed fires when a conversation moves between workflow stages.
  • Connectionschannel.connected and channel.disconnected notify you when a channel is added or removed.

Limits a user will run into

  • 3 endpoints per organisation. Delete one before adding another if you hit the limit.
  • Custom headers: up to 30 per endpoint; names and values must be plain text with no line breaks.
  • Endpoint URL: must be a reachable HTTPS URL; it can't point at the Lodgestory API itself.
  • Delivery history is retained for 30 days.
  • Bulk operations (such as a large contact import) don't fire per-record events, to avoid flooding your endpoint.

Errors & FAQ

My endpoint isn't receiving events. Check that the endpoint is enabled, that it's subscribed to the event you expect, and that your URL returns a 2xx response. Use Send test and the delivery log to diagnose.

My endpoint was disabled automatically. That happens after many consecutive failed deliveries. Fix your endpoint, then re-enable it from its row — re-enabling clears the failure count.

Signature verification fails. Make sure you're computing the signature over the exact raw request body (not a re-serialized version) together with the timestamp header, using the current secret. If you recently rotated the secret, update your verification code.

I received the same event twice. Treat deliveries as at-least-once. Use the delivery ID (the id field, also in the X-Webhook-Id header) to make your handler idempotent.

Do campaign sends fire a message.sent per recipient? Yes — each outbound message is a real send. Subscribe to message.sent only if you want that volume.

API

Webhooks are a developer feature. There are two surfaces: the admin API to manage endpoints, and the delivery contract for the events you receive.

Events you can subscribe to

EventFires when
message.sentAn outbound message is sent on any channel.
message.receivedAn inbound message arrives on any channel.
message.status_updatedA message's delivery status changes (sent / delivered / read / failed).
template.createdA WhatsApp template is created and submitted.
template.status_updatedA template is approved, rejected, or otherwise updated.
ticket.createdA ticket is created.
ticket.status_changedA ticket is resolved or reopened.
ticket.assignedA ticket's assignee changes.
contact.createdA contact is created.
chat.state_changedA conversation moves between workflow lifecycle stages.
campaign.createdA campaign is created.
campaign.completedA campaign finishes sending.
channel.connectedA channel is connected.
channel.disconnectedA channel is disconnected or removed.

The notification format

Every delivery is an HTTP POST with this JSON body:

{
  "id": "f1c2…",
  "event": "message.received",
  "api_version": "2026-05-01",
  "occurred_at": "2026-05-25T10:14:02.000Z",
  "organisation_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "object": "message",
    "message": {
      "id": "wamid.HBgL…",
      "chat_id": "[email protected]",
      "channel_id": "…",
      "channel_type": "whatsapp",
      "direction": "inbound",
      "type": "text",
      "text": "Is breakfast included?",
      "media_uri": null,
      "status": "DELIVERED",
      "from_name": "John Doe",
      "from_number": "+919999999999",
      "timestamp": "2026-05-25T10:14:02.000Z"
    }
  }
}

Update-type events also include previous_attributes. For example, ticket.status_changed:

{
  "event": "ticket.status_changed",
  "api_version": "2026-05-01",
  "occurred_at": "2026-05-25T11:02:00.000Z",
  "organisation_id": "550e8400-…",
  "data": {
    "object": "ticket",
    "ticket": {
      "id": "…",
      "chat_id": "…",
      "status": "resolved",
      "priority": "HIGH_PRIORITY",
      "assigned_to_user_id": "…",
      "created_at": "2026-05-24T09:00:00.000Z",
      "updated_at": "2026-05-25T11:02:00.000Z"
    },
    "previous_attributes": { "status": "open" }
  }
}

data.object is one of message, message_status, template, ticket, contact, chat_state, campaign, or channel, and the object's full payload is under the matching key.

Headers on every delivery

HeaderPurpose
X-Webhook-IdUnique delivery ID — use it for idempotency.
X-Webhook-EventThe event type (matches event in the body).
X-Webhook-TimestampWhen the delivery was signed (Unix seconds).
X-Webhook-Signaturesha256=<hmac> — see below.

Verifying deliveries

The signature is an HMAC-SHA256, using your endpoint's signing secret, computed over the timestamp and the raw request body joined by a dot: {timestamp}.{body}. To verify, recompute it and compare:

import crypto from 'crypto';

function isValid(req, secret) {
  const timestamp = req.headers['x-webhook-timestamp'];
  const signature = req.headers['x-webhook-signature']; // "sha256=…"
  const expected =
    'sha256=' +
    crypto
      .createHmac('sha256', secret)
      .update(`${timestamp}.${req.rawBody}`) // the exact bytes you received
      .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Always use the raw, unparsed body — re-serializing the JSON will change the bytes and break the check.

Responding

Return any 2xx status to acknowledge a delivery. Any other status (or a timeout — each attempt waits up to 10 seconds) is treated as a failure and retried automatically, up to 6 attempts with increasing delays. Endpoints that fail consistently across many events are paused automatically.

Managing endpoints

Admins can create, list, update, enable/disable, and delete endpoints, rotate secrets, list deliveries, send test events, and replay a delivery through the admin API under /api/wp-crm/webhooks (all scoped to your organisation). The same actions are available in the UI.

Changelog

  • 2026-01-12 — Webhooks launched: 14 event types across all channels, signed delivery with automatic retries, a delivery log with test and replay, and per-endpoint custom headers.

Related modules & next steps