FrontDesk API & webhooks
Plug your hotel PMS into your revenue management system, BI dashboards, accounting, channel tools or automations (n8n, Zapier, Make). One REST API per property, JSON in and out, signed webhooks on every reservation change. Using Claude, ChatGPT or Cursor? Connect them through our MCP server.
Authentication
Create a key in Settings → Integrations → API & webhooks (owner or manager). Keys are scoped to one property and shown once; we only store a hash. Send it as a bearer token on every request to https://frontdesk.lumnika.com/api/v1. For groups, create one key per property.
Errors are JSON { "error": "…" } with status 401 (bad key), 402 (trial expired), 404, 409 (room taken), 422 (validation, with issues) or 500. Money is always in cents of the property currency.
Endpoints
The full contract is an OpenAPI 3.1 document at /openapi.json: import it into Postman, Insomnia or a code generator.
GET/api/v1/reservations
List reservations, ordered by check-in. Stays overlapping [from, to) when dates are given.
from, to (YYYY-MM-DD) · status (tentative, confirmed, checked_in, checked_out, cancelled, no_show) · updated_since (ISO timestamp, for incremental sync) · limit (1-500, default 100) · offset
curl "https://frontdesk.lumnika.com/api/v1/reservations?from=2026-10-01&to=2026-10-31" \ -H "Authorization: Bearer fd_live_…"
POST/api/v1/reservations
Create a reservation. Pass an existing guest_id or an inline guest. Returns 201, or 409 if the room is already booked for those dates.
unit_id, check_in, check_out (required) · status (confirmed | tentative) · adults · children · total_cents · notes · source (default "api") · guest_id or guest { first_name, last_name, email, phone }
curl -X POST "https://frontdesk.lumnika.com/api/v1/reservations" \
-H "Authorization: Bearer fd_live_…" -H "Content-Type: application/json" \
-d '{"unit_id":"…","check_in":"2026-10-10","check_out":"2026-10-12","adults":2,
"total_cents":24000,"guest":{"first_name":"Ada","last_name":"Lovelace","email":"ada@example.com"}}'GET/api/v1/availability
Which rooms are free for the whole range [from, to), plus a count per room type. Active reservations and room blocks count as occupied.
from, to (YYYY-MM-DD, required, max 366 days)
curl "https://frontdesk.lumnika.com/api/v1/availability?from=2026-10-10&to=2026-10-12" \ -H "Authorization: Bearer fd_live_…"
GET/api/v1/guests
Guest directory: id, name, email, phone, nationality. Identity documents are never exposed.
email (exact, case-insensitive) · limit · offset
curl "https://frontdesk.lumnika.com/api/v1/guests?email=ada@example.com" \ -H "Authorization: Bearer fd_live_…"
POST/api/v1/charges
Post a charge from your POS, restaurant, bar or spa onto the guest folio, by reservation id or by room number (the checked-in stay). Safe to retry: the same idempotency key never charges twice (201 new, 200 replay). Emits charge.created.
reservation_id or room · description · amount_cents · type (service|extra) · department · idempotency_key (or Idempotency-Key header)
curl -X POST "https://frontdesk.lumnika.com/api/v1/charges" \
-H "Authorization: Bearer fd_live_…" -H "Idempotency-Key: pos-check-4812" \
-H "content-type: application/json" \
-d '{"room":"101","description":"Dinner, table 7","amount_cents":6400,"department":"restaurant"}'GET/api/v1/charges
Service and extra lines posted on folios, newest first, to reconcile what your POS sent.
reservation_id · since (ISO timestamp) · limit · offset
curl "https://frontdesk.lumnika.com/api/v1/charges?since=2026-10-10T00:00:00Z" \ -H "Authorization: Bearer fd_live_…"
Webhooks
Add an HTTPS URL in the same settings panel and we POST an event whenever a reservation is created, updated or cancelled from the front desk or through the API, and whenever a charge lands on a folio: reservation.created, reservation.updated, reservation.cancelled, charge.created.
{
"id": "5b0f…",
"type": "reservation.created",
"created_at": "2026-10-01T09:12:44.120Z",
"data": {
"id": "…", "unit_id": "…", "guest_id": "…",
"check_in": "2026-10-10", "check_out": "2026-10-12",
"status": "confirmed", "adults": 2, "children": 0,
"total_cents": 24000, "source": "api", "rate_plan_id": null, "group_id": null,
"created_at": "…", "updated_at": "…"
}
}Every request carries a frontdesk-signature: t=<unix>,v1=<hex> header, an HMAC-SHA256 of <t>.<raw body> with your endpoint secret. Verify it and reject timestamps older than five minutes:
import crypto from 'node:crypto';
// header: the "frontdesk-signature" request header, body: the raw request body
function verify(secret, header, body) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // replay window
const expected = crypto.createHmac('sha256', secret).update(`${t}.${body}`).digest('hex');
return crypto.timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'));
}Delivery is attempted once with an 8-second timeout; the last HTTP status is shown in settings. To stay in sync after downtime, poll GET /reservations?updated_since=….
Build on FrontDesk
The API is included in every plan, trial included. 14 days free, no credit card.
Try FrontDesk free