Hoppa till innehållet

API-referens

Planering

Personalschemat i Planering: pass per period, avdelningar och publiceringar.

Lista schemat för en period

GET /planning/shifts listPlanningShifts

Passen i schemat som börjar dag från–till, högst 93 dagar. Som standard det publicerade schemat, så som de anställda fick se det; med include_drafts=true planen som den ser ut nu. Inställda pass visas aldrig, och kostnadsuppskattningar ingår inte.

Mer i detalj (på engelska)

The shifts of the schedule (Planering) starting on the days from–to, at most 93 days, oldest first. By default the published schedule: what the employees were shown, so a shift changed since it was published is given as it was published (`has_unpublished_changes` is true) and a draft never published is left out. With `include_drafts=true` the plan as it stands now. Cancelled shifts are never listed. Times are ISO 8601 with the offset of Europe/Stockholm. Labour cost estimates are not part of the API. Needs planning:view, which no one has while the module is off.

Behörighet

planning:view

Parametrar

  • from string (date) fråga krävs

    First day, YYYY-MM-DD.

    Exempel: 2026-11-09

  • to string (date) fråga krävs

    Last day, YYYY-MM-DD; at most 93 days after from, counting both.

    Exempel: 2026-11-15

  • employee_id integer fråga

    Only this employee's shifts.

  • area_id integer fråga

    Only shifts in this area (avdelning).

  • include_drafts boolean fråga

    true for the plan as it stands now, drafts included; false (default) for the published schedule.

Svar

200 OK – The shifts of the period.

application/jsonobject

  • data array<PlanningShift> krävs
    15 fält · varje post
    • id string (uuid)
    • day string (date)

      The day the shift belongs to: the day it starts, in Sweden.

    • employee_id integer kan vara null

      Null for an open shift.

    • employee_name string kan vara null
    • area_id integer kan vara null
    • skill_id integer kan vara null
    • starts_at string (date-time)
    • ends_at string (date-time)
    • break_minutes integer
    • worked_minutes integer

      From start to end less the break, in real minutes (also across a summer-time change).

    • note string kan vara null
    • is_open boolean
    • status string

      Värden: published, draft

    • has_unpublished_changes boolean

      The shift was changed after it was published. In the published schedule it is given as published.

    • published_at string (date-time) kan vara null
  • meta object krävs
    4 fält
    • from string (date)
    • to string (date)
    • include_drafts boolean
    • count integer

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

Kodexempel

curl
curl "https://nonox.app/api/v1/planning/shifts?from=2026-11-09&to=2026-11-15" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/planning/shifts', [
        'from' => '2026-11-09',
        'to' => '2026-11-15',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/planning/shifts', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'from' => '2026-11-09',
        'to' => '2026-11-15',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/planning/shifts');
url.searchParams.set('from', '2026-11-09');
url.searchParams.set('to', '2026-11-15');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/planning/shifts",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "from": "2026-11-09",
        "to": "2026-11-15",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": "9b1e2c4d-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
      "day": "2026-11-10",
      "employee_id": 7,
      "employee_name": "Anna Kock",
      "area_id": 2,
      "skill_id": null,
      "starts_at": "2026-11-10T08:00:00+01:00",
      "ends_at": "2026-11-10T16:00:00+01:00",
      "break_minutes": 30,
      "worked_minutes": 450,
      "note": null,
      "is_open": false,
      "status": "published",
      "has_unpublished_changes": false,
      "published_at": "2026-11-04T10:00:00+01:00"
    }
  ],
  "meta": {
    "from": "2026-11-09",
    "to": "2026-11-15",
    "include_drafts": false,
    "count": 1
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Lista avdelningar

GET /planning/areas listPlanningAreas

Schemats avdelningar, till exempel kök eller bar.

Mer i detalj (på engelska)

The areas (avdelningar) of the schedule, such as kitchen or bar, with their colour and staff-ledger location. Needs planning:view.

Behörighet

planning:view

Parametrar

  • limit integer fråga

    Page size, 1–200.

    Standard: 50 · minst 1 · högst 200

  • cursor string fråga

    Opaque cursor from meta.next_cursor of the previous page.

    högst 2000 tecken

  • updated_since string (date-time) fråga

    Bara poster som ändrats efter den här tiden (ISO 8601). Listor sorteras på updated_at och id.

    Exempel: 2026-03-01T00:00:00+01:00

Svar

200 OK – A page of areas.

application/jsonobject

  • data array<PlanningArea> krävs
    8 fält · varje post
    • id integer
    • name string
    • colour string
    • location_id integer kan vara null

      The staff-ledger location the area is tied to, if any.

    • sort integer
    • is_archived boolean
    • created_at string (date-time)
    • updated_at string (date-time)
  • meta ListMeta krävs
    3 fält
    • limit integer krävs
    • next_cursor string krävs kan vara null

      Opaque; pass as `cursor` for the next page. null on the last page.

    • has_more boolean krävs

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/planning/areas?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/planning/areas', [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/planning/areas', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/planning/areas');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/planning/areas",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "limit": 50,
        "updated_since": "2026-03-01T00:00:00+01:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": 2,
      "name": "Kök",
      "colour": "#2e86ab",
      "location_id": null,
      "sort": 0,
      "is_archived": false,
      "created_at": "2026-11-02T09:00:00+01:00",
      "updated_at": "2026-11-02T09:00:00+01:00"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": null,
    "has_more": false
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Lista publiceringar av schemat

GET /planning/publications listPlanningPublications

Varje gång en period av schemat har publicerats: perioden, när, hur många pass och hur många som fick besked.

Mer i detalj (på engelska)

Every time a period of the schedule was published: the period, when, how many shifts and how many people were told. The planning.published webhook carries the same id. Needs planning:view.

Behörighet

planning:view

Parametrar

  • limit integer fråga

    Page size, 1–200.

    Standard: 50 · minst 1 · högst 200

  • cursor string fråga

    Opaque cursor from meta.next_cursor of the previous page.

    högst 2000 tecken

  • updated_since string (date-time) fråga

    Bara poster som ändrats efter den här tiden (ISO 8601). Listor sorteras på updated_at och id.

    Exempel: 2026-03-01T00:00:00+01:00

Svar

200 OK – A page of publications.

application/jsonobject

  • data array<PlanningPublication> krävs
    8 fält · varje post
    • id integer
    • from string (date)
    • to string (date)
    • published_at string (date-time)
    • shift_count integer
    • notified_count integer

      How many employees were sent their schedule.

    • created_at string (date-time)
    • updated_at string (date-time)
  • meta ListMeta krävs
    3 fält
    • limit integer krävs
    • next_cursor string krävs kan vara null

      Opaque; pass as `cursor` for the next page. null on the last page.

    • has_more boolean krävs

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/planning/publications?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/planning/publications', [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/planning/publications', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/planning/publications');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/planning/publications",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "limit": 50,
        "updated_since": "2026-03-01T00:00:00+01:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": 5,
      "from": "2026-11-09",
      "to": "2026-11-15",
      "published_at": "2026-11-04T10:00:00+01:00",
      "shift_count": 24,
      "notified_count": 6,
      "created_at": "2026-11-04T10:00:00+01:00",
      "updated_at": "2026-11-04T10:00:00+01:00"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": null,
    "has_more": false
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}