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#

Format
lok_{environment}_{prefix}_{secret}
PartValue
lokA fixed vendor tag, so a leaked key is easy to find with a secret scanner.
environmentsbx for a sandbox key, live for a production key. A key keeps its environment for life.
prefix8 characters from a–z and 2–9, without the look-alikes l, o, 0 and 1.
secret43 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:

Preferred
Authorization: Bearer lok_live_ab3kq7mz_…
Alternative
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:

Response · 401
{
  "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:

ScopeGrants
REGISTRATIONCreate or replace catalogue items.
UPDATEUpdate and delete catalogue items.
INVENTORYList and read catalogue items; list bookables.
PAYMENTRead 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:

Response · 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.

ActionWhat happens
CreateThe 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.
RotateIssues 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.
RevokeThe key stops working on its next request. Revoking cannot be undone.
ExpireAfter its expiry date a key is refused like a revoked one. You can change or clear the date.
Lost keyKeys 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.