Hoppa till innehåll

Developers

Webhooks — real-time events from Stayo

Subscribe to events in Stayo in real time: new bookings, check-ins and check-outs, cancellations and successful payments. Signed delivery, test delivery, secret rotation and delivery history.

Automatic dispatch

Events are sent in real time when something happens in Stayo — no polling jobs or scheduling.

Signed deliveries

Every payload is signed with HMAC-SHA256 and your signing secret so you can verify that the request comes from Stayo.

Rotate secrets

Rotate the signing secret whenever you want directly from /settings/webhooks — without losing history.

Test delivery

Send a test event to your endpoint with one click and verify that the signature and payload arrive.

Delivery history

See all outgoing requests with status code, time, payload and response. Failed deliveries can be replayed.

Multiple endpoints

Register several URLs per event — build your own integrations, ops alerts or separate environments.

Events

Subscribe per endpoint to the events you're interested in.

EventWhen it's sent
booking.createdSent when a new booking is created — via front desk, booking engine or an external channel.
booking.checked_inSent when a guest is checked in.
booking.checked_outSent when a guest is checked out.
booking.cancelledSent when a booking is cancelled.
payment.succeededSent when a payment is completed (card, Swish, invoice and more).

Example payload

All webhooks are sent as POST with JSON. Signature and event type are in the headers, so you can route and verify before parsing the payload.

  • Stayo-Event — the event type.
  • Stayo-Signature — timestamp + HMAC-SHA256.
  • Stayo-Delivery — unique ID per delivery (for idempotency).
POST https://din-app.example.com/stayo/webhook
Content-Type: application/json
Stayo-Event: booking.created
Stayo-Signature: t=1737200000,v1=9f2c...ab12
Stayo-Delivery: whd_01HXYZ...

{
  "id": "evt_01HXYZ...",
  "type": "booking.created",
  "created": "2026-08-12T09:14:22Z",
  "data": {
    "booking": {
      "id": "bk_01HXYZ...",
      "status": "confirmed",
      "channel": "direct",
      "arrival": "2026-08-20",
      "departure": "2026-08-23",
      "guest": { "name": "Anna Andersson", "email": "anna@example.com" },
      "total": { "amount": 4200, "currency": "SEK" }
    }
  }
}

Verify the signature

Compute HMAC-SHA256 over {timestamp}.{rawBody} with your signing secret and compare with v1 in Stayo-Signature. Use a constant-time comparison.

Reject requests where the timestamp is older than a few minutes to protect against replay.

import crypto from "node:crypto";

export function verifyStayoSignature(
  rawBody: string,
  header: string,
  secret: string,
) {
  const [tPart, v1Part] = header.split(",");
  const timestamp = tPart.split("=")[1];
  const signature = v1Part.split("=")[1];

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex"),
  );
}

Manage webhooks in Stayo

Under Settings → Webhooks in Stayo (/settings/webhooks) you can:

  • Add and remove endpoints per event.
  • View and rotate the signing secret.
  • Send a test delivery to an endpoint.
  • Browse delivery history with status and payload.
  • Replay failed deliveries.
  • Pause an endpoint temporarily without losing its configuration.

Want to build an integration with Stayo?

Combine webhooks with our public API — we'll help you get started and give you access to the OpenAPI specification and a test environment.