EscapeLifeDocs
Reference

Webhooks

EscapeLife sends webhook events to your configured endpoints when important platform actions occur. All events use a consistent resource.action naming pattern and are delivered with HMAC-SHA256 signatures.

Managing endpoints

Register, list, update, and delete webhook endpoints via the API. Each endpoint gets a unique HMAC secret generated automatically.

POST/v1/webhooksRegister an endpoint

Add a new webhook endpoint to receive event deliveries.

Request Body

urlstringrequiredHTTPS URL to deliver events to.
eventsstringComma-separated event types, or * for all events. Defaults to *.
descriptionstringInternal label for this endpoint.
cURL
curl -X POST https://api.escapelife.ai/v1/webhooks \
  -H "X-API-Key: sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/escapelife",
    "events": "*",
    "description": "Production webhook"
  }'
Response
{
  "id": "whe_a1b2c3d4e5f6",
  "property_id": "pty_xyz",
  "url": "https://your-server.com/webhooks/escapelife",
  "secret": "3f8a2b1c9d4e...",
  "events": "*",
  "is_active": true,
  "created_at": "2026-03-16T12:00:00Z"
}
GET/v1/webhooksList endpoints

Return all registered endpoints for the property.

PATCH/v1/webhooks/{id}Update an endpoint

Change the URL, events filter, or active state.

Path / Query Parameters

idstringrequiredEndpoint ID (whe_...).

Request Body

urlstringNew URL.
eventsstringNew event filter.
is_activebooleanEnable or disable.
DELETE/v1/webhooks/{id}Delete an endpoint

Remove an endpoint. Pending deliveries are abandoned.

Path / Query Parameters

idstringrequiredEndpoint ID (whe_...).
GET/v1/webhooks/{id}/deliveriesDelivery log

Return the delivery history for a specific endpoint.

Path / Query Parameters

idstringrequiredEndpoint ID (whe_...).
limitintegerMax results (1–200). Default 50.
offsetintegerPagination offset.

Event structure

Example webhook payload
POST https://your-server.com/webhooks/escapelife
Content-Type: application/json
EscapeLife-Signature: t=1710000000,v1=abc123...

{
  "id": "evt_9xk2mp7q",
  "type": "guest.intent.created",
  "property_id": "pty_xyz123",
  "created_at": "2026-03-15T10:00:00Z",
  "data": {
    "guest_id": "gst_01H",
    "channel": "voice",
    "intent": "book_experience",
    "context": {
      "property_id": "pty_xyz123",
      "preferred_time": "2026-03-20T20:00:00Z"
    }
  }
}

Signature verification

Every webhook request includes an EscapeLife-Signature header. Verify it before processing the event.

Verify in TypeScript (Next.js)
import crypto from "crypto";

export async function POST(req: Request) {
  const body = await req.text();
  const sig = req.headers.get("EscapeLife-Signature") ?? "";
  const secret = process.env.ESCAPELIFE_WEBHOOK_SECRET!;

  const [tPart, v1Part] = sig.split(",");
  const timestamp = tPart.replace("t=", "");
  const received = v1Part.replace("v1=", "");

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

  if (!crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))) {
    return new Response("Invalid signature", { status: 400 });
  }

  const event = JSON.parse(body);
  // handle event...
  return new Response("OK");
}
Verify in Python (FastAPI)
import hmac, hashlib
from fastapi import Request, HTTPException

async def verify_webhook(request: Request, secret: str) -> dict:
    body = await request.body()
    sig = request.headers.get("EscapeLife-Signature", "")

    parts = dict(p.split("=", 1) for p in sig.split(","))
    timestamp = parts.get("t", "")
    received = parts.get("v1", "")

    payload = f"{timestamp}.{body.decode()}"
    expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

    if not hmac.compare_digest(received, expected):
        raise HTTPException(status_code=400, detail="Invalid signature")

    return json.loads(body)

Delivery & retry

Timeout30 seconds per attempt
Retry scheduleImmediately, then 1 min, 5 min, 30 min, 2 hr, 8 hr, 24 hr
Max attempts7
Success conditionAny 2xx response code
OrderingBest-effort. Do not rely on order for business logic.

Event catalog

EventPhaseDescription
guest.createdP2

New guest profile added to the property.

guest.intent.createdP2

AI detected a guest intent (booking, service request, etc.).

booking.createdP3

A booking was confirmed.

booking.modifiedP3

A booking was updated (dates, room type, add-ons).

booking.cancelledP3

A booking was cancelled.

payment.completedP3

A payment was successfully processed.

request.submittedP2

A guest submitted a service request.

request.resolvedP2

A service request was marked complete.

upsell.triggeredP4

An upsell offer was surfaced to a guest.

upsell.convertedP4

A guest accepted an upsell offer.

yield.alertP4

Revenue co-pilot surfaced a pricing or inventory alert.

workflow.completedP5

An automation workflow finished executing.

agent.action.takenP5

An agentic AI task was completed autonomously.