Webhooks

Receive signed HTTP notifications when bookings, payments and catalogue items change.

Webhooks let Localoy tell your server when something happens — a customer books, a payment settles, a catalogue item changes — instead of your server asking. Each notification is an HTTPS POST with a JSON body, signed so you can prove it came from Localoy.

Set up an endpoint#

In the Partner Portal, open Open Network → Webhooks and add an endpoint:

SettingDetail
URLWhere Localoy sends events. See the requirements below.
EnvironmentSANDBOX or PRODUCTION. An endpoint receives only its environment's events.
EventsThe event types to send it.

Each endpoint gets its own signing secret, starting whsec_. You can reveal it again and rotate it from the portal. Rotation takes effect immediately — see Rotating the secret.

You can have up to 10 endpoints. The same URL cannot be added twice in one environment.

URL requirements#

Localoy checks the URL when you save it and before every delivery:

  • It must use https.
  • It must not contain a username, password or #fragment, and must be at most 2,048 characters.
  • It must resolve only to public IP addresses — not private, loopback, link-local or similar ranges.
  • It must not use port 22, 23, 25, 445, 3306, 5432, 6379, 9200, 11211 or 27017.

Receive an event#

Request from Localoy
POST /webhooks/localoy HTTP/1.1
Host: api.example.com
Content-Type: application/json
User-Agent: Localoy-Webhooks/1.0
X-Localoy-Signature: t=1790410530,v1=5b1f0c9e…
X-Localoy-Event-Id: evt_mfz3k2a1Xq9vT0bLm3Rk
X-Localoy-Event-Type: booking.created
X-Localoy-Delivery-Attempt: 1
X-Localoy-Webhook-Id: cm6wh00k0000000000000001
X-Localoy-Delivery-Id: cm6d3l1v3ry00000000000001

{"id":"evt_mfz3k2a1Xq9vT0bLm3Rk","event":"booking.created","occurredAt":"2026-09-26T08:15:30.123Z",…}

Your endpoint should:

  1. Verify the signature against the raw body.
  2. Skip the event if you have already processed its X-Localoy-Event-Id.
  3. Answer with any 2xx status within 10 seconds, then do slow work in the background.
Receiving an event
Receiving an eventLocaloyYour endpointYour job queue1. POST event + X-Localoy-Signature2. Verify signature and timestamp3. Seen this event ID? Then skip4. Enqueue the event5. 200 OK — within 10 s6. Process: update your records
  1. Localoy → Your endpoint: POST event + X-Localoy-Signature
  2. Your endpoint → Your endpoint: Verify signature and timestamp
  3. Your endpoint → Your endpoint: Seen this event ID? Then skip
  4. Your endpoint → Your job queue: Enqueue the event
  5. Your endpoint → Localoy: 200 OK — within 10 s
  6. Your job queue → Your job queue: Process: update your records
HeaderMeaning
X-Localoy-Signaturet={unix seconds},v1={hex HMAC-SHA256}.
X-Localoy-Event-IdThe event's ID. The same on every retry and replay — use it to de-duplicate.
X-Localoy-Event-TypeThe event type, such as booking.created.
X-Localoy-Delivery-Attempt1 on the first try, then 2, 3… on retries.
X-Localoy-Webhook-IdWhich of your endpoints this is.
X-Localoy-Delivery-IdThis delivery. A replay from the portal gets a new delivery ID but keeps the event ID.

Test your endpoint#

Press Test next to an endpoint in the portal. Localoy sends a signed ping event to it, whatever events it subscribes to — even while it is disabled.

ping event
{
  "id": "evt_mfz3k9c4Lw2pY7aHn0Qe",
  "event": "ping",
  "occurredAt": "2026-09-26T08:15:30.123Z",
  "environment": "sandbox",
  "partnerId": "cm1partnerid000000000000001",
  "data": {
    "message": "This is a test event from Localoy. Your receiver is reachable and this signature was produced by your endpoint's current signing secret.",
    "endpointId": "cm6wh00k0000000000000001"
  }
}

Next#