Employees

Manage the employee records for your tenant. An employee is assigned to locations and uses a 6-digit access code to attest a manual verification. An employee is also the Verifier you name in verifiedBy on every verification.

Employee Enrollment

A POS pushes its staff without a kennitala: create the employee with your own externalId and a phoneNumber, and no ssn. The employee then enrolls once, from the terminal: POST /api/v1/employees/{id}/enrollment sends an eID request to their phone, and you poll GET /api/v1/employees/{id}/enrollment every 2 to 3 seconds until it is enrolled, rejected or timeout (after 5 minutes). Enrollment stays with the employee when you change their phone number; a manager who enrolled the wrong person resets it with DELETE /api/v1/employees/{id}/enrollment.

One person is at most one employee of your tenant: an eID that belongs to someone who is already another employee (enrolled, or entered with that kennitala) is rejected with reason: "identity_in_use", and one that does not match the kennitala the employee was entered with is rejected with reason: "identity_mismatch". Deleting an employee frees the person. Enrollment stores the kennitala only as a salted hash, never in plain text: matching a person needs only the hash, and a stored kennitala would be PII with no use to us.

Only enrolled employees may verify. Once this is enforced, verifiedBy is required on POST /api/v1/verifications and an unenrolled Verifier gets 403 with type https://api.aldursvottun.is/errors/verifier-not-enrolled.

Note: The SSN (kennitala) is hashed server-side and never stored or returned in plain text. The accessCode is returned once, in the POST response, and can't be read back through the API: whoever holds it can attest verifications as that employee.

The employee object

  • id, createdAt (ISO 8601), updatedAt (epoch ms)
  • name, phoneNumber
  • externalId: your own identifier, unique among your tenant's live employees (deleting an employee frees it)
  • origin: "api" for an employee a service client created; left out otherwise
  • enrollmentStatus: not_enrolled, pending, enrolled, rejected or timeout
  • eidName: the name the eID reported, once enrolled
  • locationIds: the locations the employee is assigned to. List responses also include locations, the full location objects

Fields that aren't set are left out. locationIds and locations list only locations that haven't been deleted. Pagination, sorting and field formats follow the shared conventions.

GET/api/v1/employees

List the employees in your tenant. Callers: service client (Bearer) and device (DPoP). Sorted by createdAt descending unless you pass sortBy. Without limit, every employee is returned in one response; with limit, the response is a page with nextCursor and hasMore (nextCursor is null on the last page).

Headers

AuthorizationstringRequired

Bearer <access_token> (service client) or DPoP <access_token> (device). Requires employees:read.

DPoPstringOptional

Device callers only: the DPoP proof for this request, including ath.

Query Parameters

locationIdstringOptional

Only employees assigned to this location. A malformed ID returns 400; an ID that matches nothing, or a deleted location, returns an empty list

namestringOptional

Case-insensitive substring match on the name

externalIdstringOptional

Exact match on externalId

sortBystringOptional

"name" | "createdAt" | "updatedAt". Default "createdAt"

sortOrderstringOptional

"asc" | "desc". Default "desc"

limitintegerOptional

Page size, a positive integer

cursorstringOptional

nextCursor from the previous page

Examples

cURL

curl "https://abyrgverslun.is/api/v1/employees?locationId=jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra&sortBy=name&sortOrder=asc" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

{
  "data": [
    {
      "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
      "createdAt": "2026-04-11T13:02:45.906Z",
      "name": "Guðrún Jónsdóttir",
      "phoneNumber": "6912345",
      "externalId": "HR-0042",
      "locationIds": ["jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra"],
      "updatedAt": 1778063472044,
      "locations": [
        {
          "id": "jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra",
          "createdAt": "2026-03-02T09:14:27.512Z",
          "name": "Laugavegur",
          "address": "Laugavegur 26",
          "city": "Reykjavík",
          "postcode": "101",
          "updatedAt": 1772442867512
        }
      ]
    }
  ]
}

Errors

  • 400 locationId is not a valid location ID.
  • 401 Missing, invalid or expired token, or a device token sent as Bearer.
  • 403 The token lacks employees:read.
  • 422 A query parameter failed validation (limit, sortBy or sortOrder).

Response format: Errors.

POST/api/v1/employees

Create an employee. Callers: service client (Bearer) only; a device (DPoP) call gets 403. externalId is required. Without ssn, the employee is created pending Employee Enrollment. Returns 201 with the new employee's ID and access code, not the full record. Store the access code now: it is not returned again.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:write.

Content-TypestringRequired

application/json

Request Body

namestringRequired

Full name, 1-100 characters

externalIdstringRequired

Your own identifier for the employee, 1-100 characters. Must be unique among your tenant's live employees (a duplicate returns 409); deleting an employee frees it

ssnstringOptional

Kennitala, exactly 10 characters. Leave it out to have the employee enroll with eID instead. Hashed before it is stored. Must be unique among your tenant's active employees (a duplicate returns 409). If it belongs to a deleted employee, that employee is restored with the new details and keeps its ID

phoneNumberstringRequired

An Icelandic phone number: 7 digits, optionally after 354, 00354 or +354, in ASCII digits with optional spaces, "-", ".", "(" and ")"; at most 20 characters (trimmed). This is the phone part of the eID Identifier format (see eID verification). A kennitala, a foreign number or any other length fails validation (422)

accessCodestringOptional

Exactly 6 digits. Generated if you leave it out. Must be unique among your tenant's active employees (a duplicate returns 409); a deleted employee's code is free to reuse

locationIdsstring[]Optional

Locations to assign the employee to. Each must be a location in your tenant that hasn't been deleted, or the call returns 400

Examples

cURL

curl -X POST https://abyrgverslun.is/api/v1/employees \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Guðrún Jónsdóttir",
    "externalId": "HR-0042",
    "phoneNumber": "6912345",
    "locationIds": ["jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra"]
  }'

Response

// 201 Created
{
  "employeeId": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
  "accessCode": "482913"
}

// 409 Conflict
{
  "type": "https://api.aldursvottun.is/errors/conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "An employee with this externalId already exists"
}

Errors

  • 400 Body is not valid JSON, or a locationIds entry is not a live location in your tenant.
  • 401 Missing, invalid or expired token.
  • 403 The token lacks employees:write, or the caller is a device.
  • 409 The externalId, SSN or access code is already used by an active employee in your tenant.
  • 422 The body failed validation, e.g. externalId was left out.

Response format: Errors.

GET/api/v1/employees/{id}

Read one employee. Callers: service client (Bearer) and device (DPoP). Includes locationIds but not locations, and the enrollment status and eID name.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client) or DPoP <access_token> (device). Requires employees:read.

DPoPstringOptional

Device callers only: the DPoP proof for this request, including ath.

Response

{
  "data": {
    "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
    "createdAt": "2026-04-11T13:02:45.906Z",
    "name": "Guðrún Jónsdóttir",
    "phoneNumber": "6912345",
    "externalId": "HR-0042",
    "origin": "api",
    "enrollmentStatus": "enrolled",
    "eidName": "Guðrún Jónsdóttir",
    "locationIds": ["jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra"],
    "updatedAt": 1778063472044
  }
}

Errors

  • 401 Missing, invalid or expired token, or a device token sent as Bearer.
  • 403 The token lacks employees:read.
  • 404 No employee with this ID in your tenant: unknown, malformed, deleted, or another tenant's.

Response format: Errors.

GET/api/v1/employees/code

Find the employee who holds an access code, e.g. to show the employee's name on a device before a manual verification. Callers: service client (Bearer) and device (DPoP); dashboard user tokens get 403. Returns only id, name, updatedAt and createdAt.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client) or DPoP <access_token> (device). Requires employees:read.

DPoPstringOptional

Device callers only: the DPoP proof for this request, including ath.

Query Parameters

codestringRequired

The employee's 6-digit access code

Examples

cURL

curl "https://abyrgverslun.is/api/v1/employees/code?code=482913" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response

{
  "data": {
    "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
    "name": "Guðrún Jónsdóttir",
    "updatedAt": 1778063472044,
    "createdAt": "2026-04-11T13:02:45.906Z"
  }
}

Errors

  • 401 Missing, invalid or expired token, or a device token sent as Bearer.
  • 403 The token lacks employees:read, or it is a dashboard user token.
  • 404 No current employee in your tenant has this code.
  • 422 code is missing or empty.

Response format: Errors.

PATCH/api/v1/employees/{id}

Update an employee. Callers: service client (Bearer) only; a device (DPoP) call gets 403. Send only the fields you want to change; fields you leave out keep their values. The access code and location assignments can't be changed through this endpoint. Changing the phone number keeps the employee's enrollment. Returns the updated employee in the same shape as GET /api/v1/employees/{id}.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:write.

Content-TypestringRequired

application/json

Request Body

namestringOptional

1-100 characters

phoneNumberstringOptional

An Icelandic phone number: 7 digits, optionally after 354, 00354 or +354, in ASCII digits with optional spaces, "-", ".", "(" and ")"; at most 20 characters (trimmed). This is the phone part of the eID Identifier format (see eID verification). A kennitala, a foreign number or any other length fails validation (422)

externalIdstringOptional

Your own identifier, e.g. an HR system ID. Up to 100 characters. Must be unique among your tenant's live employees (a duplicate returns 409); deleting an employee frees it

Examples

cURL

curl -X PATCH https://abyrgverslun.is/api/v1/employees/m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "externalId": "HR-0042" }'

Response

{
  "data": {
    "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
    "createdAt": "2026-04-11T13:02:45.906Z",
    "name": "Guðrún Jónsdóttir",
    "phoneNumber": "6912345",
    "externalId": "HR-0042",
    "locationIds": ["jh72m4q9x1c8n3v5b6z0k2d7f4g9t1ra"],
    "updatedAt": 1778063472301
  }
}

Errors

  • 400 Body is not valid JSON, or on a test tenant phoneNumber is not a test eID identifier (see Test mode).
  • 401 Missing, invalid or expired token.
  • 403 The token lacks employees:write, the caller is a device, or the ID belongs to another tenant.
  • 404 Unknown, malformed or deleted employee ID.
  • 409 The externalId is already used by another employee in your tenant.
  • 422 The body failed validation.

Response format: Errors.

DELETE/api/v1/employees/{id}

Delete an employee. Callers: service client (Bearer) only; a device (DPoP) call gets 403. This is a soft delete: the employee disappears from lists and reads and can no longer attest manual verifications, but the location assignments are not removed. The deleted employee's access code and externalId are freed, and creating an employee with the same SSN restores the deleted one (same ID) instead of making a new one. Deleting the same employee again returns 404.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:delete or employees:write.

Response

{ "deleted": true }

Errors

  • 401 Missing, invalid or expired token.
  • 403 The token lacks both employees:delete and employees:write, the caller is a device, or the ID belongs to another tenant.
  • 404 Unknown, malformed or already deleted employee ID.

Response format: Errors.

POST/api/v1/employees/{id}/enrollment

Start Employee Enrollment: sends an eID request to the employee's phone. Callers: service client (Bearer). Show the returned code on the terminal so the employee can match it on their phone, then poll GET /api/v1/employees/{id}/enrollment. Starting again replaces a pending, rejected or timed-out request; an enrolled employee must be reset first (409). An employee entered with a kennitala whose person is already another employee of your tenant gets 409 enrollment-identity-in-use, and no eID request is sent.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:write.

Content-TypestringRequired

application/json

Request Body

phoneNumberstringRequired

The phone to send the eID request to. An Icelandic phone number: 7 digits, optionally after 354, 00354 or +354, in ASCII digits with optional spaces, "-", ".", "(" and ")"; at most 20 characters (trimmed). This is the phone part of the eID Identifier format (see eID verification). A kennitala, a foreign number or any other length fails validation (422)

Examples

cURL

curl -X POST https://abyrgverslun.is/api/v1/employees/m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w/enrollment \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "phoneNumber": "6912345" }'

Response

{
  "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
  "status": "pending",
  "code": "4821",
  "livemode": true
}

Errors

  • 400 Body is not valid JSON, or on a test tenant phoneNumber is not a test eID identifier (see Test mode).
  • 401 Missing, invalid or expired token.
  • 403 The token lacks employees:write, or the ID belongs to another tenant.
  • 404 Unknown, malformed or deleted employee ID.
  • 409 The employee is already enrolled (type conflict), or was entered with a kennitala whose person is already another employee of your tenant (type enrollment-identity-in-use).
  • 422 phoneNumber is missing or invalid.
  • 500 The eID Provider could not start the request.

Response format: Errors.

GET/api/v1/employees/{id}/enrollment

Poll Employee Enrollment every 2 to 3 seconds while status is pending. Callers: service client (Bearer). status is pending, enrolled, rejected or timeout (no answer within 5 minutes). A rejected eID that succeeded carries a reason: identity_mismatch (the eID belongs to someone other than the kennitala on file) or identity_in_use (the person is already another employee of your tenant); without a reason, the employee declined. Once enrolled, eidName is the name the eID reported; the kennitala itself is stored only hashed and is never returned.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:write.

Response

// Pending
{ "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w", "status": "pending", "livemode": true }

// Enrolled
{
  "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
  "status": "enrolled",
  "eidName": "Guðrún Jónsdóttir",
  "livemode": true
}

// Already another employee
{
  "id": "m17d4f6g8h2j3k5l7z9x1c3v5b7n9q2w",
  "status": "rejected",
  "reason": "identity_in_use",
  "livemode": true
}

Errors

  • 401 Missing, invalid or expired token.
  • 403 The token lacks employees:write.
  • 404 Unknown, malformed, deleted or another tenant's employee, or the employee has never started enrolling.

Response format: Errors.

DELETE/api/v1/employees/{id}/enrollment

Reset Employee Enrollment, e.g. when the wrong person enrolled. Callers: service client (Bearer). The employee is no longer enrolled and can enroll again. Resetting an employee who is not enrolled also returns 204.

Headers

AuthorizationstringRequired

Bearer <access_token> (service client). Requires employees:write.

Response

// 204 No Content

Errors

  • 401 Missing, invalid or expired token.
  • 403 The token lacks employees:write, or the ID belongs to another tenant.
  • 404 Unknown, malformed or deleted employee ID.

Response format: Errors.