API reference
Base URL: https://lango.localtel.tech/api/v1. The machine-readable OpenAPI spec is at /api/v1/openapi.json.
Authentication
Create keys in your portal under PMS & API → API keys. Send the key as a bearer token:
Authorization: Bearer cpk_live_xxxxxxxxxxxxxxxx
- Keys are shown once and stored hashed. Revoke them at any time.
- A key can be limited to a single site.
- Rate limit: 600 requests per minute per key. Exceeding it returns
429.
| Scope | Allows | Package |
|---|---|---|
guests:write | check-in, update, move, check-out, full resync | all |
guests:read | list in-house guests / directory | all |
portal:read | list sites and plans | all |
sessions:read | list Wi-Fi sessions | Professional+ |
sessions:write | disconnect sessions | Professional+ |
vouchers:write | create access codes | Professional+ |
{site} in paths accepts either the site ID (sit_…) or the site key shown in your portal.
Guests / directory
The guest model is generic across sectors. room is whatever people type as their identifier: a room, bed, unit, student ID or ticket number. last_name is the second factor: a surname, PIN or date of birth.
| Field | Type | Notes |
|---|---|---|
reservation_id | string, required | Stable key from your system (reservation, admission, enrolment, ticket ID) |
room | string, required | Identifier typed at login |
last_name | string, required | Second factor typed at login (accent- and case-insensitive) |
first_name, email, language, vip | string | Optional |
arrival, departure | date (YYYY-MM-DD) | departure caps Wi-Fi access at checkout time + grace |
no_post | boolean | Blocks charge-to-room upgrades |
Check in
POST /sites/{site}/guests/checkin
{"reservation_id":"884213","room":"1204","last_name":"Otieno","first_name":"Amani","arrival":"2026-11-13","departure":"2026-11-16"}
→ 201 {"data":{"id":"gst_…","room":"1204","status":"in_house",…}}
Update, move, check out
POST /sites/{site}/guests/update {"reservation_id":"884213","departure":"2026-11-18"}
POST /sites/{site}/guests/move {"reservation_id":"884213","new_room":"1402"}
POST /sites/{site}/guests/checkout {"reservation_id":"884213"} → disconnects the guest's devices
Full resync (nightly)
PUT /sites/{site}/guests
{"guests":[{"reservation_id":"884213","room":"1204","last_name":"Otieno"}, …]}
→ {"data":{"upserted":212,"checked_out":7}}
Anyone not in the list is checked out. Each call accepts up to 5,000 guests.
List
GET /sites/{site}/guests?status=in_house|checked_out
Sessions
GET /sites/{site}/sessions?status=live|all
DELETE /sites/{site}/sessions/{id} → disconnect now (RADIUS Disconnect / controller API)
Access codes
POST /sites/{site}/vouchers
{"plan_id":"pln_…","count":50,"max_uses":1,"valid_hours":72,"note":"Conference hall B"}
Send "code":"SUMMIT2026" to create one shared code.
Plans & sites
GET /sites → sites this key can access, with splash URLs
GET /sites/{site}/plans → active plans (free tiers and paid upgrades)
Errors
Errors come back as JSON: {"error":"message","details":{…}}.
| Status | Meaning |
|---|---|
| 401 | Missing or invalid key |
| 403 | Missing scope, wrong site, tenant suspended, or feature not in package |
| 404 | Not found |
| 422 | Validation failed (details lists the fields) |
| 429 | Rate limited |
Webhooks
Configure them under PMS & API → Outbound webhook (Professional and above). Each delivery is a POST with:
X-Portal-Event: session.created
X-Portal-Timestamp: 1763030400
X-Portal-Signature: sha256=<hex HMAC_SHA256(secret, timestamp + "." + body)>
{"id":"evt_…","event":"session.created","created_at":"…","tenant_id":"…","site_id":"…","data":{…}}
Events:
session.created,session.endedguest.checked_in,guest.checked_outposting.requested(charge-to-room without a FIAS link)payment.paid,payment.failedping
Device integration endpoints
These are used by your network equipment, not by your code:
| Purpose | Endpoint |
|---|---|
| Splash page | GET /p/{site-key} (+ vendor parameters) |
| UniFi external portal | GET /guest/s/{unifi-site}/ |
| Welcome page | GET /p/{site-key}/welcome |
| RADIUS | UDP 1812 (auth), 1813 (accounting); the platform sends CoA/Disconnect to UDP 3799 |