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.
/v1/webhooksRegister an endpointAdd 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 -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"
}'{
"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"
}/v1/webhooksList endpointsReturn all registered endpoints for the property.
/v1/webhooks/{id}Update an endpointChange the URL, events filter, or active state.
Path / Query Parameters
idstringrequiredEndpoint ID (whe_...).Request Body
urlstringNew URL.eventsstringNew event filter.is_activebooleanEnable or disable./v1/webhooks/{id}Delete an endpointRemove an endpoint. Pending deliveries are abandoned.
Path / Query Parameters
idstringrequiredEndpoint ID (whe_...)./v1/webhooks/{id}/deliveriesDelivery logReturn the delivery history for a specific endpoint.
Path / Query Parameters
idstringrequiredEndpoint ID (whe_...).limitintegerMax results (1–200). Default 50.offsetintegerPagination offset.Event structure
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.
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");
}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
30 seconds per attemptImmediately, then 1 min, 5 min, 30 min, 2 hr, 8 hr, 24 hr7Any 2xx response codeBest-effort. Do not rely on order for business logic.Event catalog
guest.createdP2New guest profile added to the property.
guest.intent.createdP2AI detected a guest intent (booking, service request, etc.).
booking.createdP3A booking was confirmed.
booking.modifiedP3A booking was updated (dates, room type, add-ons).
booking.cancelledP3A booking was cancelled.
payment.completedP3A payment was successfully processed.
request.submittedP2A guest submitted a service request.
request.resolvedP2A service request was marked complete.
upsell.triggeredP4An upsell offer was surfaced to a guest.
upsell.convertedP4A guest accepted an upsell offer.
yield.alertP4Revenue co-pilot surfaced a pricing or inventory alert.
workflow.completedP5An automation workflow finished executing.
agent.action.takenP5An agentic AI task was completed autonomously.