LivionKey API v2 provides dedicated endpoints for mechanical keys and mechanical key contracts. Use these endpoints for new integrations. If your integration already uses the devices, keys, and contracts endpoints in API v1, see Legacy LivionKey API v1: Devices, keys, and contracts instead.
API v2 is the recommended version for new integrations. It uses service-account request signing, not the JWT authentication used by API v1.
Before you begin
Make sure that you have:
A LivionKey organization with API v2 enabled.
A service account ID and its private key. The private key is shown only once when the service account is created, so store it securely.
The relevant organization unit or key automat IDs, or a description of the manual storage location, as applicable.
Read the LivionKey API v2 reference for the complete request and response schemas.
Contact Livion Support if you need API access or service-account credentials.
Base URL and authentication
The production base URL is:
https://api.livionkey.com/v2/
Every API v2 request must be sent over HTTPS and signed with your service account. A signed request includes these headers:
x-service-account-id: your service account ID.x-timestamp: the current timestamp in milliseconds.x-signature: the signature created with your service account's private key.
Follow the authentication instructions and code examples. Never send your private key to Livion or include it in support requests.
Core concepts
Mechanical keys
A mechanical key has its own ID and can be stored in either:
A LivionKey automat, identified by
automatId.A manual storage location, described with
manualStorageInfo.
When creating a key, set away to indicate whether the key is already away from its storage location. Automat keys can also be marked as shared when overlapping contracts are needed; manual-storage keys cannot be shared.
A key response distinguishes three storage states:
selectedStorage: the key's configured home location.storage: the key's current location.targetStorage: its destination during a move or return flow.
Mechanical key contracts
A mechanical key contract grants a contact access to one or more keys for a defined period. A contract contains the contact, start and optional end time, keys, storage information, and optional notification and verification settings.
API v2 supports three contract flows:
Default: hand over keys and expect them to be returned.
Fetch only: hand over automat-stored keys without requiring a return.
Return only: receive keys back without a prior handover contract.
Recommended workflow
1. Create or locate the key
Use POST /mechanical/keys to create a key. For example, this request body creates a key stored in an automat:
{ "id": "APARTMENT-A12", "name": "Apartment A12", "selectedStorage": { "automatId": "AUTOMAT_ID" }, "shared": false, "away": false }For a manually stored key, replace selectedStorage with a manual storage description:
{ "id": "OFFICE-MASTER", "name": "Office master key", "selectedStorage": { "manualStorageInfo": "Reception, drawer 2" }, "shared": false, "away": false }Use these endpoints to inspect and maintain keys:
GET /mechanical/keys— list keys with pagination and filters.GET /mechanical/keys/{id}— get one key.PATCH /mechanical/keys/{id}— update a key.DELETE /mechanical/keys/{id}— delete a key.
2. Create a key contract
Use POST /mechanical/keycontracts for the normal handover-and-return flow. This example assigns one automat-stored key to a contact:
{ "id": "BOOKING-1042", "start": "2027-02-16T08:20:00.000Z", "end": "2027-02-20T08:20:00.000Z", "contact": { "name": "John Doe", "email": "[email protected]", "phoneNumber": "+358401234567", "sendSms": true, "sendEmail": true, "language": "en" }, "keys": [{ "id": "APARTMENT-A12", "storageInfo": { "automatId": "AUTOMAT_ID", "pincode": "654321" } }], "freeLockerAfterFetch": false }The API can generate a PIN code when one is not supplied. See the API reference for current validation rules, contact fields, notification settings, user verification, group-based automat selection, and manual-storage contracts.
3. Read, update, or remove the contract
Use these endpoints throughout the contract lifecycle:
GET /mechanical/keycontracts— list contracts with pagination and filters.GET /mechanical/keycontracts/{id}— get one contract.PATCH /mechanical/keycontracts/{id}— update a contract.DELETE /mechanical/keycontracts/{id}— delete a contract.
When updating contact information, send the complete contact object, not only the individual field that changed. A contract cannot be deleted while one of its keys has been fetched and not yet returned.
Refresh PIN codes
Use POST /mechanical/keycontracts/{id}/refreshPincodes to give the automat-stored keys of a contract new PIN codes. The request body is optional:
Send no body, or an empty
pincodesarray, to generate a new PIN code for every automat-stored key in the contract.To choose the PIN code of a key, add the key to
pincodes. A PIN code is a string of 4–9 digits. Leading zeros are kept. The other automat-stored keys in the contract still get new generated PIN codes. If you send the PIN code that the key already has, a new one is generated instead.
{ "pincodes": [{ "keyId": "APARTMENT-A12", "pincode": "001234" }] }The response is the updated contract with the new PIN codes. The API returns 400 Bad Request if the contract has no automat-stored keys, if a key ID is listed twice, or if a listed key does not belong to the contract or is not stored in an automat. It returns 404 Not Found if the contract does not exist.
One-way contract flows
Use the specialized endpoints only when the physical key flow is one-way:
POST /mechanical/keycontracts/fetch-only— hand over a key without requiring a return. This endpoint supports automat-stored keys only.POST /mechanical/keycontracts/return-only— accept the return of a key without a prior handover.
The contract response includes a contractType value: 1 for default, 2 for fetch only, and 3 for return only.
Automats
Use the automat endpoints to read your key automats and their lockers:
GET /automats— list automats. By default, the list includes Key30, Key20, and KeyX automats. To filter, use theproductsquery parameter, for example?products=key30.GET /automats/{id}— get one automat with its lockers. For each locker,lockers[].key.idis the assigned key andlockers[].isKeyInsidetells whether the key is in the locker.
KeyX automats can be listed and read, but they can't be installed, uninstalled, or replaced through the API. POST /automats/install, POST /automats/{id}/uninstall, and POST /automats/{id}/replace return 400 Bad Request for KeyX automats.
Open a locker
Use POST /automats/{id}/openLocker to open the locker that holds, or is reserved for, a key. Use it to put a new key into an automat or to take a key out without creating a key contract.
{ "keyId": "APARTMENT-A12", "proximityCheck": true }The key must be assigned to a locker of this automat, for example a key created with
selectedStorage.automatIdset to this automat.The automat must be online and must already have received the key. Right after you create the key, this can take about a minute.
When
proximityCheckistrue(the default), the locker opens only if someone presses # on the automat within 30 seconds. Set it tofalseto open the locker at once. An automat without a keypad requiresfalse.For an iLOQ key, opening the locker this way removes the key's access rights.
A 200 OK response means that the automat received the command. It does not mean that the locker opened: the locker stays closed if the automat is busy with another user or if # is not pressed in time. The response contains the lockerIndex of the locker and the proximityCheck value used. To check the result, read lockers[].isKeyInside from GET /automats/{id}.
Each request is recorded as a Locker opening requested event, which you can see in Event history in LivionKey Register.
Errors:
400— the automat does not support opening lockers, or it has no keypad for the proximity check. In the second case, setproximityChecktofalse.403— the service account's role is not allowed to open automat lockers.404— the automat was not found.409— the key is not assigned to a locker of this automat, or it is assigned to several lockers; the automat is offline; the automat has not received the key yet (try again shortly); the automat software does not support this command (contact Livion Support); or the automat could not confirm the key in the locker, so the locker was not opened.504— the automat did not confirm the command. The locker may or may not open. Checklockers[].isKeyInsidebefore you try again.
Moving from API v1
API v2 is not a field-for-field rename of API v1. Plan migration work for these differences:
API v1 uses a login and bearer token; API v2 signs every request with a service account.
API v1 couples keys to devices and lockers; API v2 models keys separately from their selected, current, and target storage.
API v2 uses different paths, HTTP methods, identifiers, paginated list responses, contact structures, and per-key PIN codes.
The API v1 endpoint
POST /contracts/{contractId}/pincodecorresponds toPOST /mechanical/keycontracts/{id}/refreshPincodesin API v2. In API v2, PIN codes are per key, not per contract. See Refresh PIN codes above.
Keep an existing API v1 integration on the legacy v1 workflow until its migration has been designed and tested.
Important validation and operational notes
Use ISO 8601 date-time values, including a timezone, for
startandend.A contract must contain at least one key.
Automat and manual-storage keys cannot be mixed in one contract.
Key IDs cannot contain spaces. Contract IDs accept letters, numbers, underscores, periods, and hyphens.
If SMS notifications are enabled, provide a valid phone number. If email notifications are enabled, provide a valid email address.
API v2 is rate limited to 1,000 requests per minute per client. If the API returns
429 Too Many Requests, retry with exponential backoff.Consult the live API reference before implementation because it is the source of truth for fields, validation, responses, and newly added functionality.
Access grants and keypads
If your organization uses LivionKey keypads, you can also manage keypad access with API v2. These endpoints require keypad access management to be enabled for your organization. Without it, the access grant endpoints and the keypad list, details, and unlock endpoints return 403 Forbidden. Contact Livion Support if you need the feature.
/access-grants— create, list, read, update, and revoke access grants. An access grant gives one or more contacts a PIN code for selected keypads or keypad groups, for a set period or permanently.DELETE /access-grants/{id}revokes a grant, andPOST /access-grants/{id}/credential/rotategives it a new PIN code./keypads— list keypads, read a keypad with the access grants that reach it, update its settings, unlock it remotely, and install, uninstall, or replace a keypad./groups/{id}/members— add keypads to a group or remove them withPOSTandDELETEand amemberIdslist. An access grant that targets a group reaches every keypad in it.
For request and response schemas, see the Access Grants, Keypads, and Groups endpoints in the API reference.
Full API reference
Use the LivionKey API v2 reference for complete schemas and examples:
Need help?
Contact Livion Support and include your organization, service account ID, endpoint, HTTP status, approximate time and timezone, and request ID if available. Do not send your private key, signatures, PIN codes, or other credentials.
