DevelopersTablet version · pilot
HTTP route reference
Explicit Kelna routes, required identities and request schemas extracted from code.
Read the contract
Expand a route to view its path parameters and JSON schema when available. Schemas are extracted from Fastify validators at build time; a route missing from the catalog fails generation.
The OpenAPI 3.1 contract covers these Kelna routes, excluding the Better Auth proxy. Room responses and retry rules are explained in “Read the room and send an action”. A 200 response does not prove a later call will remain authorized: identities are checked again.
Vision routes are marked experimental. They only store settings; they do not activate detection during service.
GET/api/health
Check that the API process responds.
- Access
- No session required; other checks still apply
GET/api/ready
Check the connection to the initialized database. Returns 503 when unavailable.
- Access
- No session required; other checks still apply
GET/api/account
Read the signed-in account and its MFA requirement. The response contains account personal data.
- Access
- Human session; MFA depends on the route
GET/api/account/verified
Check that the human session has completed two-factor authentication.
- Access
- Human session; MFA depends on the route
POST/api/account/activate
Activate or recover an account using a one-hour invitation token. Password length is 12 to 128 characters.
- Access
- No session required; other checks still apply
JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"token",
"password"
],
"properties": {
"token": {
"type": "string",
"minLength": 43,
"maxLength": 43
},
"password": {
"type": "string",
"minLength": 12,
"maxLength": 128
}
}
}GET/api/access/organizations
List accessible organizations after MFA.
- Access
- Human session; MFA depends on the route
GET/api/organizations/{organizationId}/venues
List authorized venues and device-management and reporting capabilities.
- Access
- Human session; MFA depends on the route
Path parameters
{
"type": "object",
"required": [
"organizationId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
}
}
}GET/api/organizations/{organizationId}/roles
List roles and their permissions within the organization.
- Access
- Human session; MFA depends on the route
Path parameters
{
"type": "object",
"required": [
"organizationId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
}
}
}POST/api/organizations/{organizationId}/role-assignments
Assign a role to a member. venueId is null for organization-wide scope. SQL checks authorization and prevents escalation; a fresh session is required.
- Access
- Human session; MFA depends on the route
Path parameters
{
"type": "object",
"required": [
"organizationId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"memberId",
"roleId",
"venueId"
],
"properties": {
"memberId": {
"type": "string",
"format": "uuid"
},
"roleId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
]
}
}
}DELETE/api/organizations/{organizationId}/role-assignments/{assignmentId}
Revoke an assignment with authorization checks, a fresh session, and protection for the last Owner.
- Access
- Human session; MFA depends on the route
Path parameters
{
"type": "object",
"required": [
"organizationId",
"assignmentId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"assignmentId": {
"type": "string",
"format": "uuid"
}
}
}GET/api/organizations/{organizationId}/venues/{venueId}/devices
List devices, their last activity, expiration and revocation.
- Access
- Human session; MFA depends on the route
- Permission
devices.manage
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
}
}
}POST/api/organizations/{organizationId}/venues/{venueId}/pairing
Create a single-use code valid for five minutes, for a tablet or pass display.
- Access
- Human session; MFA depends on the route
- Permission
devices.manage
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"kind"
],
"properties": {
"kind": {
"enum": [
"tablet",
"pass"
]
}
}
}POST/api/organizations/{organizationId}/venues/{venueId}/devices/{deviceId}/revoke
Revoke a venue device.
- Access
- Human session; MFA depends on the route
- Permission
devices.manage
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId",
"deviceId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
},
"deviceId": {
"type": "string",
"format": "uuid"
}
}
}POST/api/device/pair
Exchange an eight-character code for the HttpOnly kelna.device cookie. Origin is checked and attempts are limited.
- Access
- No session required; other checks still apply
JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"code",
"kind"
],
"properties": {
"code": {
"type": "string",
"pattern": "^[A-HJ-NP-Z2-9]{8}$"
},
"kind": {
"enum": [
"tablet",
"pass"
]
}
}
}GET/api/device
Read the venue and view authorized for the current device.
- Access
- Paired device
GET/api/organizations/{organizationId}/venues/{venueId}/room
Read the room snapshot using a verified human session and the explicit venue context.
- Access
- Human session; MFA depends on the route
- Permission
venue.view
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
}
}
}GET/api/room
Read the plan, service, table and group snapshot for the paired device.
- Access
- Paired device
- Permission
venue.view
POST/api/room/services
Open a service with a caller-supplied UUID id. The plan and thresholds are fixed when it opens.
- Access
- Paired tablet with permission
- Permission
services.manage
JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
}
}
}POST/api/room/services/{serviceId}/close
Close a service with a command UUID id. Final states are preserved.
- Access
- Paired tablet with permission
- Permission
services.manage
Path parameters
{
"type": "object",
"required": [
"serviceId"
],
"properties": {
"serviceId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
}
}
}POST/api/room/services/{serviceId}/tables/{tableId}/commands
Apply a table action or undo using id and expectedVersion. A joined table also requires groupId and every member’s version.
- Access
- Paired tablet with permission
- Permission
tables.update
Path parameters
{
"type": "object",
"required": [
"serviceId",
"tableId"
],
"properties": {
"serviceId": {
"type": "string",
"format": "uuid"
},
"tableId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"id",
"type",
"expectedVersion"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"type": {
"enum": [
"seat",
"greet",
"order",
"serve",
"request_bill",
"deliver_bill",
"pay",
"depart",
"clear",
"undo"
]
},
"expectedVersion": {
"type": "integer",
"minimum": 0,
"maximum": 2147483646
},
"groupId": {
"type": "string",
"format": "uuid"
},
"members": {
"type": "array",
"minItems": 2,
"maxItems": 30,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"tableId",
"version"
],
"properties": {
"tableId": {
"type": "string",
"format": "uuid"
},
"version": {
"type": "integer",
"minimum": 0,
"maximum": 2147483646
}
}
}
}
}
}POST/api/room/services/{serviceId}/groups
Join, split or undo a group operation. Supply the current group and table versions.
- Access
- Paired tablet with permission
- Permission
tables.join
Path parameters
{
"type": "object",
"required": [
"serviceId"
],
"properties": {
"serviceId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"id",
"type",
"groupId",
"expectedVersion",
"primaryTableId",
"members"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"type": {
"enum": [
"join",
"split",
"undo_join",
"undo_split"
]
},
"groupId": {
"type": "string",
"format": "uuid"
},
"expectedVersion": {
"type": "integer",
"minimum": 0,
"maximum": 2147483646
},
"primaryTableId": {
"type": "string",
"format": "uuid"
},
"members": {
"type": "array",
"minItems": 2,
"maxItems": 30,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"tableId",
"version"
],
"properties": {
"tableId": {
"type": "string",
"format": "uuid"
},
"version": {
"type": "integer",
"minimum": 0,
"maximum": 2147483646
}
}
}
}
}
}GET/api/organizations/{organizationId}/venues/{venueId}/vision
Read preparatory settings for the camera test bench. Camera observations do not drive the service.
- Access
- Human session; MFA depends on the route
- Permission
venue.view
Experimental preparation
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
}
}
}POST/api/organizations/{organizationId}/venues/{venueId}/vision
Save experimental settings using planId, revision and config. No video stream or image is accepted.
- Access
- Human session; MFA depends on the route
- Permission
floorplan.edit
Experimental preparation
Path parameters
{
"type": "object",
"required": [
"organizationId",
"venueId"
],
"properties": {
"organizationId": {
"type": "string",
"format": "uuid"
},
"venueId": {
"type": "string",
"format": "uuid"
}
}
}JSON request body
{
"type": "object",
"additionalProperties": false,
"required": [
"planId",
"revision",
"config"
],
"properties": {
"planId": {
"type": "string",
"format": "uuid"
},
"revision": {
"type": "integer",
"minimum": 0,
"maximum": 2147483646
},
"config": {
"type": "object"
}
}
}Need a hand?
Describe the step that failed and the message shown. Keep passwords and sign-in codes private.
Contact the Kelna team