# Lodgix Webhooks

Lodgix is vacation-rental property management software. Account webhooks
(**Modules > Integrations > Webhooks**) send an HTTP `POST` with a JSON payload to
your HTTPS endpoint when a subscribed event occurs. Every delivery is signed with
the endpoint's secret.

## When to Use This Skill

* How do I receive Lodgix webhooks?
* How do I verify the Lodgix `X-Lodgix-Signature` header?
* How do I handle `message.received` events from Lodgix?
* Why is my Lodgix webhook signature verification failing?
* How do I use the `X-Lodgix-Timestamp` header for replay protection?

## Verification (core)

Lodgix sends `X-Lodgix-Signature: sha256=<hex>`, where the digest is
`HMAC_SHA256(secret, "{X-Lodgix-Timestamp}.{raw request body}")` as lowercase hex.
The key is the endpoint secret used as-is (UTF-8, not decoded). Sign the **raw body
bytes** exactly as received: parsing and re-serializing the JSON breaks the
signature. This is not Standard Webhooks.

```javascript
const crypto = require('crypto');

function verifyLodgixSignature(rawBody, timestamp, signature, secret) {
  if (!timestamp || !signature) return false;
  const hex = signature.startsWith('sha256=') ? signature.slice(7) : signature;
  if (!/^[0-9a-fA-F]{64}$/.test(hex)) return false;   // validate before decoding

  const message = Buffer.concat([
    Buffer.from(timestamp, 'latin1'),   // header value exactly as received
    Buffer.from('.', 'utf8'),
    rawBody,                            // Buffer of the raw HTTP body
  ]);
  const expected = crypto.createHmac('sha256', secret).update(message).digest();
  const provided = Buffer.from(hex.toLowerCase(), 'hex');
  return provided.length === expected.length && crypto.timingSafeEqual(provided, expected);
}

```

Respond `401` when the signature or timestamp header is missing, malformed, or does
not match.

**Timestamp window (opt-in).** `X-Lodgix-Timestamp` is Unix seconds. Lodgix
recommends rejecting requests older than 5 minutes, but Hookdeck retries and
replays resend the original headers and timestamp, so a fixed window would reject
legitimate retries. The examples therefore skip the check by default and enable it
only when `LODGIX_WEBHOOK_TOLERANCE_SECONDS` is set above `0` (for example `300`).
Pair it with idempotency on `X-Lodgix-Delivery` instead.

> **For complete handlers with tests**, see [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/lodgix-webhooks/examples/express/), [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/lodgix-webhooks/examples/nextjs/), [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/lodgix-webhooks/examples/fastapi/).

## Request Headers

| Header | Meaning |
| --- | --- |
| `X-Lodgix-Event` | Event type, e.g. `message.received` |
| `X-Lodgix-Delivery` | Unique ID for this delivery (use for idempotency) |
| `X-Lodgix-Timestamp` | Unix time (seconds) when the request was signed |
| `X-Lodgix-Signature` | `sha256=<hex>` signature of the payload |

## Common Event Types

| Event | Triggered When |
| --- | --- |
| `message.received` | A guest message is received |

`message.received` is the only event Lodgix documents so far. Read the event name
from the `X-Lodgix-Event` header. The payload shape is not documented, so the
examples use a clearly labelled illustrative body.

## Environment Variables

```bash
LODGIX_WEBHOOK_SECRET=your_endpoint_secret        # Secret from your Lodgix webhook endpoint
LODGIX_WEBHOOK_TOLERANCE_SECONDS=0                # Optional replay window in seconds; unset or 0 = off

```

## Local Development

```bash
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 lodgix --path /webhooks/lodgix

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/lodgix-webhooks/references/overview.md) - Lodgix webhook concepts, headers, events
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/lodgix-webhooks/references/setup.md) - Create a webhook endpoint in Lodgix
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/lodgix-webhooks/references/verification.md) - Signature verification details and gotchas