Authentication

Service Client Authentication using OAuth 2.0 Client Credentials with client_secret. Authenticate by exchanging your client credentials for a short-lived access token.

How it works

  1. Register a service client in the admin dashboard and receive a client_id and client_secret
  2. Get an access token — POST your client_id and client_secret to /api/oauth/token, then call any API endpoint using the token as a Bearer token

Register a service client

A tenant admin registers service clients through the admin dashboard. Navigate to Integrations → API Clients and click Create Client.

During registration you provide:

  • Name — a human-readable label for this integration
  • Description — optional description of the integration
  • Permissions — the scopes this client may request

The system generates a client_id (format: svc_<hex>) and a client_secret (format: scs_<48 hex chars>). Save the client secret immediately — it is a single-line string shown only once and cannot be retrieved again. The server stores only a SHA-256 hash of the secret.

Step 1 — Get an access token

POST your client_id and client_secret to the token endpoint to receive a short-lived access token. Use application/x-www-form-urlencoded encoding (not JSON).

Store your client secret as an environment variable — it is a single-line string that is natively .env-friendly:

CLIENT_ID='svc_a1b2c3d4e5f6'
CLIENT_SECRET='scs_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6'

Avoid committing secrets to source control.

curl -s -X POST https://abyrgverslun.is/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials\
&client_id=svc_a1b2c3d4e5f6\
&client_secret=scs_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6\
&scope=devices:read transactions:read" | jq .

Response

POST/api/oauth/token

Exchange client credentials for an access token.

Headers

Content-TypestringRequired

application/x-www-form-urlencoded

Request Body

grant_typestringRequired

Must be client_credentials

client_idstringRequired

Your service client ID (svc_xxx)

client_secretstringRequired

Your client secret (scs_xxx)

scopestringOptional

Space-separated list of requested scopes — must be a subset of registered scopes

Response

{
  "access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "devices:read transactions:read"
}

Step 2 — Use the access token

Include the token in the Authorization header of every API request. Tokens expire in 5 minutes. No refresh tokens are issued — when it expires, request a fresh token with your client credentials.

POST/api/verification/pass

Example authenticated request for age verification. Verification outcomes return HTTP 200 with result pass/fail.

Headers

AuthorizationstringRequired

Bearer <access_token>

Content-TypestringRequired

application/json

Request Body

passDatastringRequired

Base64-encoded 64-byte pass (legacy 64-char Latin-1 also accepted)

requiredAgenumberRequired

Minimum age threshold to check (for example, 18)

Examples

cURL

ACCESS_TOKEN="eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9..."

curl -s -X POST https://abyrgverslun.is/api/verification/pass \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "passData": "<base64-or-latin1-pass>",
    "requiredAge": 18
  }' | jq .

Response

{
  "result": "pass",
  "transactionId": "j57b2mNkR4e9..."
}

Available permissions

Request only the scopes your integration needs. All resources support both read and write operations.

PermissionDescription
devices:readList and read device details
devices:writeCreate, update, and delete devices
locations:readRead location information
locations:writeCreate, update, and delete locations
employees:readRead employee records
employees:writeCreate, update, and delete employee records
transactions:readRead verification transaction records (read-only)
transactions:writeCreate verification transactions (age verification)

Secret rotation

Rotate secrets without downtime using the Rotate Secret action on the client detail page in the dashboard. A new secret is generated automatically.

The old secret transitions to retiring status for a 24-hour grace window, during which both the old and new secrets are accepted. After the grace window the old secret is no longer valid. Update your CLIENT_SECRET environment variable during the grace window to avoid interruption.

Instant revocation

An admin can instantly invalidate all active tokens for a client via the Revoke All Tokens action in the dashboard. This sets tokensInvalidBefore to the current timestamp. Any token issued before that timestamp is immediately rejected on next use — no token blacklist required.