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 tiers | All paid tiers. |
| Who can use it | Admins and Account Owners create and manage endpoints. |
| Channels covered | All — WhatsApp, Instagram, Messenger, Email, and Web Chat. |
| Events | 14 event types across messages, templates, tickets, contacts, chat workflow, campaigns, and channels. |
| Top limits | Up to 3 endpoints per organisation. Up to 30 custom headers per endpoint. |
| Delivery | Signed (HMAC-SHA256), automatically retried, with a delivery log you can inspect and replay. |
| API | Yes — 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 tool —
ticket.createdandticket.assignedevents 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
- Something happens in Lodgestory — a message is sent or received, a ticket changes, a campaign finishes.
- Lodgestory checks which of your endpoints subscribe to that event.
- For each matching endpoint, Lodgestory builds a standard notification, signs it with that endpoint's secret, and delivers it to your URL.
- 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.
- 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
| Role | Can do |
|---|---|
| Account Owner / Admin | Create, edit, enable/disable, and delete endpoints; view and rotate secrets; view delivery logs; send test events; replay deliveries. |
| Team member / Agent | No access to webhook settings. |
Connections
- Unified Inbox —
message.sentandmessage.receivedfire for every channel that lands in the inbox. - Tickets —
ticket.created,ticket.status_changed, andticket.assignedkeep an external helpdesk or on-call tool in sync. - Campaigns —
campaign.createdandcampaign.completedlet you track broadcast progress in your own reporting. - Contacts —
contact.creatednotifies you when a new contact is added from a conversation or the create-contact action. - WhatsApp Templates —
template.createdandtemplate.status_updatedtell you when a template is submitted and when Meta approves or rejects it. - Workflow Lifecycle Stages —
chat.state_changedfires when a conversation moves between workflow stages. - Connections —
channel.connectedandchannel.disconnectednotify 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
| Event | Fires when |
|---|---|
message.sent | An outbound message is sent on any channel. |
message.received | An inbound message arrives on any channel. |
message.status_updated | A message's delivery status changes (sent / delivered / read / failed). |
template.created | A WhatsApp template is created and submitted. |
template.status_updated | A template is approved, rejected, or otherwise updated. |
ticket.created | A ticket is created. |
ticket.status_changed | A ticket is resolved or reopened. |
ticket.assigned | A ticket's assignee changes. |
contact.created | A contact is created. |
chat.state_changed | A conversation moves between workflow lifecycle stages. |
campaign.created | A campaign is created. |
campaign.completed | A campaign finishes sending. |
channel.connected | A channel is connected. |
channel.disconnected | A 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
| Header | Purpose |
|---|---|
X-Webhook-Id | Unique delivery ID — use it for idempotency. |
X-Webhook-Event | The event type (matches event in the body). |
X-Webhook-Timestamp | When the delivery was signed (Unix seconds). |
X-Webhook-Signature | sha256=<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
- Connections — connect the channels whose events you'll receive.
- Tickets and Campaigns — common event sources.
- WhatsApp Templates — track template approval via
template.status_updated.
Updated about 1 hour ago
