Ábyrg verslun API Documentation

Welcome to the Ábyrg verslun API documentation. Here you'll find everything you need to integrate age verification into your applications.

Overview

The Ábyrg verslun API lets you check a customer's age before selling age-restricted goods such as tobacco and nicotine products. A customer shows a wallet pass, authenticates with eID, or an employee confirms their age manually. Every verification returns a pass or fail result and, in most cases, a transaction record you can read back later.

Base URL

https://abyrgverslun.is

Every endpoint path in these docs starts with /api/, so POST /api/v1/verifications means https://abyrgverslun.is/api/v1/verifications.

There is no sandbox or test environment. Every call goes to production and every verification is recorded against your tenant.

Authentication

There are two ways for an integration to authenticate:

  • Service client, for a server-side integration such as a POS backend. An admin creates the client under Integrations → API Clients and gets a client_id and client_secret. Your server exchanges them for a short-lived token with the OAuth client_credentials grant and sends it as Authorization: Bearer. See Authentication.
  • Device, for a scanner, tablet or till app. The device starts the OAuth device flow, an admin approves it in the dashboard, and the device gets a token bound to its own key with DPoP. See Device authentication.

Getting started

  1. Get a tenant account. Register your business at signup. The contact person gets an email invite to become the tenant's first admin.
  2. Create a service client or link a device. In the dashboard, create an API client under Integrations → API Clients, or start the device flow on your device and approve it under Devices → Link Device (or open the verification_uri_complete link the device shows).
  3. Get a token. Service clients call POST /api/oauth/token with grant_type=client_credentials. Devices poll the same endpoint with the device code they were given.
  4. Run your first verification. Send the customer's Pass Token to POST /api/v1/verifications with "method": "pass". See Verify Pass.

Conventions

These rules apply to every /api/v1/* endpoint.

Requests and responses

  • Request bodies are JSON (Content-Type: application/json). The OAuth token endpoint is the exception: it takes application/x-www-form-urlencoded.
  • The tenant API (locations, devices, employees, transactions) returns a single resource as { "data": { ... } } and a list as { "data": [ ... ] }. Two exceptions answer without a wrapper: POST /api/v1/employees ({ "employeeId", "accessCode" }) and the verification endpoints. A create returns 201; a delete returns { "deleted": true }.
  • IDs are opaque strings, for example k57a3m9qz4x8c1n2v6b0d5f7gh1j2k3l. Don't parse them.
  • createdAt is an ISO 8601 string ("2026-09-29T10:15:00.000Z"). updatedAt and lastActiveAt are numbers: milliseconds since the Unix epoch (1790676900000).
  • An optional field that isn't set is left out of the response rather than returned as null. The exceptions are documented where they occur: a transaction's failReason is null on a pass, and nextCursor is null on the last page.
  • Errors use RFC 7807 Problem Details. See Errors.

Pagination

The list endpoints (locations, devices, employees, transactions) are paginated only when you pass limit (a positive integer). The response then carries nextCursor and hasMore:

{
  "data": [ ... ],
  "nextCursor": "k57a3m9qz4x8c1n2v6b0d5f7gh1j2k3l",
  "hasMore": true
}
  • To get the next page, repeat the request with the same filters and cursor=<nextCursor>. The cursor is the ID of the last item on the page.
  • On the last page nextCursor is null and hasMore is false.
  • A cursor that doesn't match an item in the list (for example, one that was deleted in the meantime) is not an error: the list starts again from the first page.
  • Without limit, locations, devices and employees return every row, with no nextCursor or hasMore. Transactions return only the newest 100.
  • The default order is newest first (createdAt descending). Locations, devices and employees accept sortBy (name, createdAt, updatedAt) and sortOrder (asc, desc). Transactions are always newest first.
  • An invalid limit, sortBy, sortOrder or other enumerated query parameter gets a 422 naming the parameter.

Quick links

Support

If you have questions or need assistance, please contact our support team at support@abyrgverslun.is