Authentication
How API keys are formatted, sent and verified, what each scope allows, and how to rotate or revoke a key.
Every Open Network API call except GET /health is authenticated with an
API key that you create in the Partner Portal.
Key format#
lok_{environment}_{prefix}_{secret}| Part | Value |
|---|---|
lok | A fixed vendor tag, so a leaked key is easy to find with a secret scanner. |
environment | sbx for a sandbox key, live for a production key. A key keeps its environment for life. |
prefix | 8 characters from a–z and 2–9, without the look-alikes l, o, 0 and 1. |
secret | 43 characters of URL-safe base64. It may itself contain _. |
A sandbox key is 60 characters long and a production key 61. The first three parts together —
lok_sbx_ab3kq7mz — are the key's public prefix. The Partner Portal shows it next to the key, and
GET /ping returns it, so you can tell keys apart without exposing the secret.
Sending the key#
Send the key in either header:
Authorization: Bearer lok_live_ab3kq7mz_…X-Api-Key: lok_live_ab3kq7mz_…If a request carries both headers, the Authorization header is used. Surrounding whitespace is
ignored.
When a key is refused#
Every authentication failure gets the same answer, whatever the reason:
{
"success": false,
"message": "Invalid or missing API key",
"code": "open_network_key_invalid",
"requestId": "3f0c9f8e-6a1d-4f5e-9b1a-2f1c0d9e7a41"
}The response never says why, so it cannot help someone guessing keys. The reason — missing, malformed, unknown, wrong secret, revoked or expired — is recorded in your request log, which you can read on the Partner Portal's Open Network → Activity page.
Scopes#
A key carries one or more scopes. Each endpoint needs exactly one of them:
| Scope | Grants |
|---|---|
REGISTRATION | Create or replace catalogue items. |
UPDATE | Update and delete catalogue items. |
INVENTORY | List and read catalogue items; list bookables. |
PAYMENT | Read payment sessions, report results and record refunds. |
GET /ping needs a valid key but no scope.
A fifth scope, BOOKINGS, is one you can grant only to a
Technology Provider: an API key cannot hold it, and asking for it on a
key answers 400 with scope_not_available_for_keys.
A key without the required scope gets 403:
{
"success": false,
"message": "This API key does not have the PAYMENT scope, which this endpoint requires.",
"code": "open_network_scope_required",
"details": {
"requiredScope": "PAYMENT",
"grantedScopes": ["REGISTRATION", "INVENTORY"]
},
"requestId": "…"
}Changing a key's scopes in the portal takes effect on its next request.
Least privilege
Give each system its own key with only the scopes it uses. A payment service needs PAYMENT; a stock
sync job needs REGISTRATION, UPDATE and INVENTORY.
Key lifecycle#
All of these are done in the Partner Portal under Open Network → API keys.
| Action | What happens |
|---|---|
| Create | The full key is shown once. Localoy keeps only its SHA-256 hash. You can hold up to 20 active keys. You can optionally set an expiry date. |
| Rotate | Issues a completely new key string — new prefix and new secret — under the same name and scopes. The old key stops working immediately; there is no overlap period. |
| Revoke | The key stops working on its next request. Revoking cannot be undone. |
| Expire | After its expiry date a key is refused like a revoked one. You can change or clear the date. |
| Lost key | Keys cannot be recovered. Rotate it and deploy the new one. |
Rotation has no grace period
Because the old key fails as soon as you rotate, deploy in this order: create a second key, deploy it everywhere, confirm traffic on the new key in the Activity page, then revoke the old one.
Calling from a server only#
The API sends no CORS headers to arbitrary origins, so a browser page cannot call it. Keep keys in your server's secret store or environment variables, and send every request from your backend.