Welcome to the FlexyKey REST API.
This API allows third-party developers to integrate booking systems, access control systems, and automation platforms with FlexyKey and Evva AirKey units.
The API provides:
This document explains how to authenticate, how to call the endpoints, and how to interpret responses.
The FlexyKey API uses HTTP Basic Authentication.
Your FlexyWeb username and password (API-enabled user) must be sent via the Authorization header:
Swagger and tools like Postman handle this automatically.
Access Requirement
All API calls are executed in the context of the authenticated user.
To use any API function (units, control, status, webhooks, bookings, logs), the user must belong to the same company that owns the target unit or booking object.
If a user does not have rights, the API returns an access error.
Production
https://api.flexykey.se/v1/
Swagger documentation
https://api.flexykey.se/v1/swagger
Example:
FlexyKey uses a consistent IO model across the API.
These identifiers are used 1:1 across the API:
GET /Units)POST /Control)GET /Control)
This means that IO returned from GET /Units can be used directly for:
Use globalNumber when referring to IO in integrations.
Examples:
F1 and F2 are the two relays on the main unitX1 may be relay 1 on expansion module 1X5 may be relay 1 on expansion module 2IX1 may be input 1 on expansion module 1The Unit API returns both:
localNumber – physical/local position on that board or expansionglobalNumber – API-wide identifier used in Control and StatusFor example:
Here:
localNumber = 1 means it is relay 1 on that specific expansion moduleglobalNumber = X5 means this is the identifier your integration uses in the APIGET /Units to discover the available IO structure for the unitglobalNumber values you needPOST /ControlGET /Control or webhooks
Always use globalNumber when interacting with IO.
Use localNumber only for display or mapping to physical terminals and labels.
Do not assume that all units have expansion modules. Some units only expose main relays and main inputs, while others may include WEXP or other expansion types.
The Unit API allows applications to:
This endpoint should normally be the first step in an integration, because it tells you which IO names are valid for each unit.
The Unit API may also include sensors and counters collections.
These are metadata/discovery structures and should be used to understand which sensors and counters are available for a unit, how they are identified, and how values should be interpreted.
GET
Response example
Units without expansion modules will have an empty expansions array.
Different expansion types may expose different capabilities. For example, a WEXP module may contain relays and inputs, while another module type may contain no IO at all.
The Unit API may also include sensors and counters collections.
These are metadata/discovery structures and should be used to understand which sensors and counters are available for a unit, how they are identified, and how values should be interpreted.
GET
The response structure is the same as in the list endpoint, but for one unit only.
The Control API allows developers to:
F1, F2) on the main unitX1–X64)ON / OFF / pulse commandsunitId or serialNumber
POST /Control
Send a control command to a FlexyKey unit.
URL:
Request body (JSON)
Specify either unitId or serialNumber.
outputNumber can be F1, F2 or X1–X64.
outputAction can be ON, OFF or a pulse value in seconds, 1–99999 (only number, no unit).
Example 1 — Control F1 ON
Example 2 — Pulse X33 for 60 seconds
Response:
GET /Control
Retrieve the current IO state of a unit.
By unitId:
By serial:
Response example:
The status response uses the same global IO identifiers as the Unit API.
Some unit information is retrieved by sending approved CHECK commands to the physical unit.
These commands perform a roundtrip through the unit communication path and the database.
The API therefore does not wait for the unit response.
Recommended flow:
GET /RequestUnitInfoTypes to discover approved command types and profilesPOST /RequestUnitInfo to queue one command or one pre-built profileGET /UnitMessages or the relevant status endpoint, for example GET /ControlAll endpoints use the same Basic Authentication and company/unit access control as the rest of the API.
GET /v1/RequestUnitInfoTypes
Returns the public command catalog: approved individual commands and pre-built profiles.
Only commands that are visible and enabled in the catalog are returned.
URL:
Example response:
Current public command types:
CHECKASTAT - input and output status, older compatibility formatCHECKSTATUS - FKV2 input and output statusCHECKCOUNTERS - input countersCHECKTEMP - current temperature responseCHECKSYS - system informationCHECKTIME - unit time and uptime informationCHECKEXP - expansion unit information; may return several response messagesCHECKCALSTAT - calendar statusCHECKSALOFFICEMODE - Sallis lock office mode statusCHECKOUTPUTCAL - calendars connected to outputs/locksCHECKINPUTCAL - calendars connected to inputsCHECKESPNOWMAC - ESP-NOW MAC address informationCHECKWEXP - WEXP unit informationCurrent public profiles:
controlStatusFull - CHECKASTAT, CHECKCOUNTERS, CHECKTEMP, CHECKSYScontrolStatusMedium - CHECKASTAT, CHECKCOUNTERS, CHECKTEMP
POST /v1/RequestUnitInfo
Queues one approved command or one approved profile for a unit.
Use either unitId or serialNumber, and either typeName or profile.
The endpoint is asynchronous. A successful response means the command was accepted for queuing, not that the unit has already answered.
Request body - one command:
Request body - profile:
Example response:
Commands and profiles have configurable cache and rate limits to protect the unit communication path. If a command is skipped because of cache or rate limiting, the command result status indicates that instead of queuing a new command.
GET /v1/UnitMessages
Returns latest approved incoming unit information messages for a unit.
Leave typeName empty to return all approved response types, or set typeName to filter by a specific command.
Only responses matching visible and enabled commands in the public command catalog are returned. Outgoing commands, internal log messages and unsupported raw device reports are not returned.
Default behavior is latest 20 rows, newest first.
Maximum limit is 100.
Examples:
Example response:
The timestamp field reflects the database timestamp in Swedish/local database time.
Use timestampIso for machine storage, comparison and integration logic.
ID entries are the unit access list: phone numbers, PIN codes or tag numbers that can be synchronized to a unit. Use these endpoints to read, create, update or mark entries for deletion on the server.
A changed ID entry is not sent to the physical unit immediately.
After changing entries, call POST /UnitSync/PushChanges to push the pending changes to the unit.
Use GET /UnitSync/Status afterwards to follow progress, for example in a progress bar.
Important field rules:
unitId is required for all operationsidNumber max length is 20 charactersname and description max length is 25 charactersaction must be a valid relay/action value, for example R1, R2 or a valid access group such as G13codeTag must be 4-7 digits when usedcodeTagCalendar may only be set when codeTag contains a valid PINvalidFromIso and validToIso use ISO 8601, for example 2026-04-22T14:00:00+02:00 or 2026-04-22T12:00:00Z
GET /v1/UnitIdEntries
Returns ID entries for a unit. Supports paging and search.
Search matches idNumber, name, description and action.
Partial text is accepted. Leave search empty to return all ID entries for the unit.
limit controls page size. offset is the number of rows to skip.
Example: first page offset=0, second page offset=limit.
POST /v1/UnitIdEntries
Creates one ID entry for a unit. Duplicate idNumber values on the same unit return 409 Conflict.
PUT /v1/UnitIdEntries/{id}
Updates one ID entry. The unitId in the body must match the existing row.
Changes to idNumber, action, codeTag, codeTagCalendar, validFromIso or validToIso mark the entry as changed for sync.
Changes to name or description do not mark the entry as changed, because those fields are not sent to the unit.
DELETE /v1/UnitIdEntries/{id}
Marks one ID entry for deletion on the server. The deletion is sent to the physical unit by calling POST /UnitSync/PushChanges.
Unit settings are approved customer-facing settings that can be read and updated on the server. Only settings approved by the public catalog are visible through this API.
A changed setting is not sent to the physical unit immediately.
After changing settings, call POST /UnitSync/PushChanges to push pending changes to the unit.
Current public settings include:
DefaultRelayPulseWifiModeWifiNameWifiPassword
GET /v1/UnitSettings/Definitions
Returns the approved public settings and their input rules.
Example response:
GET /v1/UnitSettings
Returns the approved settings rows that currently exist for the selected unit.
Example response:
PUT /v1/UnitSettings
Creates or updates one approved setting for the selected unit.
The body format is one setting at a time.
Examples:
If a setting is not approved by the public catalog, the API returns 400 Bad Request.
After a successful update, call POST /UnitSync/PushChanges to send pending changes to the unit.
Unit Sync sends changed customer data from the server to the physical unit.
Recommended flow:
/UnitIdEntries, and update settings using /UnitSettingsPOST /UnitSync/PushChangesGET /UnitSync/Status until the sync is completed, failed or timed outPOST /UnitSync/Abort to stop the active sync and clean pending packets
POST /v1/UnitSync/PushChanges
Packages changed customer data and queues communication packets to the unit.
The endpoint returns immediately and does not wait for the unit to answer.
Example response:
GET /v1/UnitSync/Status
Returns the current sync status for a unit. Status responses have a short cache guard, normally 2 seconds.
If there is no active sync, the API returns a normal response with message No active unit programming.
POST /v1/UnitSync/Abort
Aborts the active unit sync for the unit and clears pending programming packets.
Use this when a sync has failed, timed out or must be restarted.
Tools are server-side maintenance endpoints. They do not communicate with the physical unit. Use them only when you intentionally need to adjust what the server considers synchronized or changed.
POST /v1/Tools/IdEntriesSyncState
Changes the server-side unit sync state for ID entries on one unit.
Send id if you want to affect one row. Leave id out if you want to affect all ID entries for the selected unit.
POST /v1/Tools/UnitSettingsSyncState
Changes the server-side unit sync state for approved public settings on one unit.
Send setting plus params if you want to affect one approved setting.
Leave them out if you want to affect all approved settings for the selected unit.
POST /v1/Tools/AllUnitDataSyncState
Macro endpoint that changes the server-side unit sync state for both ID entries and settings on one unit.
This endpoint only needs unitId and unitSyncState.
The Webhooks API allows your system to receive HTTP callbacks when a unit reports a status update.
Currently supported event:
control.statusChanged
Important
The event control.statusChanged is triggered when an ASTAT status message is received from the unit.
To receive updates on IO changes, the FlexyKey unit must be configured to report IO changes.
Important
Webhooks require secure communication to be enabled on the FlexyKey unit.
This may or may not be the default setting depending on the unit version and may need to be enabled manually.
A webhook is configured per unitId and event type.
The webhook payload for control.statusChanged uses the same JSON object structure as:
This means you can use the same parsing logic for:
GET /v1/Control
When the event control.statusChanged is sent, the payload matches the Control status response and may contain:
unitIdserialNumberstatusTimestampstatusTimestampIsorawStatusinputsfOutputsxOutputsxInputsStatusTimestampxInputsStatusTimestampIsorawXInputsStatusxInputsisCachedExample webhook payload
If a unit has no expansion inputs, or if no X-input status is available, the X-input fields may be empty or null:
GET /v1/Webhooks/Events
Returns the currently supported webhook event types.
Example request
Example response
PUT /v1/Webhooks
Creates or updates a webhook configuration for a specific unitId and event.
This endpoint uses an upsert model:
Request body fields
unitId – requiredevent – requiredcallbackUrl – required, absolute HTTP/HTTPS URLhttpMethod – optional, POST, PUT or PATCHsecret – optional, used for HMAC signatureapiKey – optional, sent as X-Api-KeyisActive – optional, 1 or 0Example request
Example response (created)
Notes
isActive=0 to temporarily disable a webhook without deleting itGET /v1/Webhooks/Events
GET /v1/Webhooks
Returns webhook configuration for a unit.
Required query parameter
unitIdOptional query parameter
event – if provided, returns only the webhook for this eventExample – get all webhooks for a unit
Example – get one webhook
Example response
DELETE /v1/Webhooks
Deletes a webhook for a specific unitId and event.
Required query parameters
unitIdeventExample request
Response
Returns 204 No Content if the webhook was deleted.
POST /v1/Webhooks/Test
Sends a direct HTTP test call to the configured webhook endpoint for the specified unit and event.
This is useful for:
Request body
Example request
Example response
Important
The test call sends the same payload structure as GET /v1/Control / status webhook payload.
Recommended test flow
PUT /v1/WebhooksGET /v1/WebhooksPOST /v1/Webhooks/TestExample test using webhook.site
https://webhook.site and copy the generated URLcallbackUrl in PUT /v1/WebhooksPOST /v1/Webhooks/TestHeaders sent with webhook requests
X-Event – event name, for example control.statusChangedX-UnitId – unit IDX-Webhook-Test: 1 – present on test deliveriesX-Api-Key – present if configuredX-Signature – present if a secret is configured
Signature
If a webhook secret is configured, the payload is signed and sent in:
The HMAC is calculated over the raw JSON request body using the configured secret.
2xx as quickly as possibleGET /v1/ControlstatusTimestampIso and xInputsStatusTimestampIso for storage and orderingxInputs is always present; units without expansion inputs may return empty X-input fieldsGET /v1/Control only when polling is necessaryFlexyKey logs are available via API for:
(Evva logs are not available.)
GET
Response example
The Booking API allows applications to:
Example — Create a booking
Successful responses include a unique bookingId.
statusTimestampIso, xInputsStatusTimestampIso) for storage and orderingGET /Units to discover and cache unit metadata such as IO, sensors and counters; do not call it before every Control or Status commandglobalNumber values such as F1, X33 or IX2 in your integration logicGET /Control when polling is necessaryPOST /RequestUnitInfo to request approved CHECK information from the unit, then read the later response using GET /UnitMessages or the relevant status endpointPOST /UnitSync/PushChanges and poll GET /UnitSync/Status until the sync is completed/Tools endpoints only for server-side maintenance, for example when replacing a unit or resending entries
FlexAccess AB
https://flexaccess.se
support@flexaccess.se
Please provide: