Publisert - 15.09.2026

API Reference

The API is served on two versions with different authentication:

  • /api/v1/* — Data endpoints authenticated with the X-API-KEY header.
  • /api/v2/* — The same data endpoints authenticated with a HelseID access token (DPoP).

The health check (/api/internal/health) requires no authentication. See Authentication.

GET /api/v1/treatment-group

Returns treatment group data. Supports filtering and version-based diff queries.

Parameters

Parameter Type Required Description
since-version long No If provided, returns only items changed since this version. If omitted, returns all active items.
name string No Returns active treatment groups with matching name.
disease-group string No Returns active treatment groups that contains the disease group.
jurisdiction string No Returns active treatment groups that contains the jurisdiction code.
indication string No Returns active treatment groups that contains the indication code.
vare-nr string No Returns active treatment groups that contains the FEST/Varenummer.
effective-date string YYYY-MM-DD No Returns treatment groups that is active on the given date.

Response

{
  "currentVersion": 5,
  "entries": [
    {
      "data": { ... },
      "version": 5,
      "lastChanged": "2025-04-10T08:30:00Z",
      "isDeleted": false
    }
  ]
}

Without since-version: Returns all non-deleted items. isDeleted is always false.

With since-version: Returns items with version > N, including deleted items. isDeleted may be true for items that were removed from the source system.

Example

# Get all
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/treatment-group

# Get changes since version 3
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/treatment-group?since-version=3

# Filter on indication code
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/treatment-group?indication=G35

GET /api/v1/treatment-group/

Returns a treatment group.

Parameters

Parameter Type Required Description
id string Yes Returns an active treatment group with matching id.

Response

{
  "data": {
    "id": "...",
    "name": "...",
    "description": "...",
    "diseaseGroup": "...",
    "jurisdictions": [ { "system": "...", "code": "100022", "display": "Helse Nord RHF" } ],
    "validityPeriod": { "start": "...", "end": "..." },
    "reviewDate": "...",
    "indications": [ { "coding": [ {"system": "...", "code": "C500","display": "..."}], "text": null } ],
    "treatmentAlternatives": [
      {
        "rank": 1,
        "treatmentId": "...",
        "name": "Atezolizumab (Tecentriq)",
        "description": "...",
        "products": [
          {
            "identifiers": [
              { "system": "FEST/LegemiddelPakning/Varenummer", "value": "448992" },
              { "system": "FEST/LegemiddelPakning/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
              { "system": "FEST/LegemiddelMerkevare/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
              { "system": "FEST/LegemiddelVirkestoff/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" }
            ]
          }
        ]
      }
    ]
  },
  "version": 1,
  "lastChanged": "2026-06-23T09:17:13.113Z",
  "isDeleted": false
}

GET /api/v1/reimbursement-group

Returns reimbursement group data (legal basis, indications, covered products). Supports filtering and version-based diff queries.

Parameters

Parameter Type Required Description
since-version long No If provided, returns only items changed since this version. If omitted, returns all active items.
indication string No Returns active reimbursement groups that contains the indication code.

Response

{
  "currentVersion": 5,
  "entries": [
    {
      "data": {
        "id": "...",
        "legalBasis": { "coding": [ { "system": "...", "code": "950", "display": "H-resept" } ] },
        "indications": [ { "coding": [ { "system": "...", "code": "G35", "display": "Multiple sclerosis" } ] } ],
        "products": [
          {
            "identifiers": [
              { "system": "FEST/LegemiddelPakning/Varenummer", "value": "166028" },
          { "system": "FEST/LegemiddelPakning/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
          { "system": "FEST/LegemiddelMerkevare/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
          { "system": "FEST/LegemiddelVirkestoff/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
              { "system": "FEST/LegemiddelPakning/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
              { "system": "FEST/LegemiddelMerkevare/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" },
              { "system": "FEST/LegemiddelVirkestoff/Id", "value": "ADDED_WHEN_FEST_FILE_IS_READ" }
            ]
          }
        ]
      },
      "version": 5,
      "lastChanged": "2025-04-10T08:30:00Z",
      "isDeleted": false
    }
  ]
}

Behavior is identical to the treatment-group endpoint. The products array is empty if upstream provides no article number for the authorization.

Example

# Get all
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/reimbursement-group

# Get changes since version 3
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/reimbursement-group?since-version=3

# Filter on indication code
curl -H "X-API-KEY: key" \
  https://api.example.com/api/v1/reimbursement-group?indication=G35

GET /api/v1/reimbursement-group/

Returns a reimbursement group (legal basis, indications, covered products).

Parameters

Parameter Type Required Description
id string Yes Returns an active reimbursement group with matching id.

Response

{
  "data": {
    "id": "...",
    "legalBasis": { "coding": [ { "system": "...", "code": "950", "display": "H-resept" } ] },
    "indications": [ { "coding": [ { "system": "...", "code": "G35", "display": "Multiple sclerosis" } ] } ],
    "products": [
      {
        "identifiers": [
          { "system": "FEST/LegemiddelPakning/Varenummer", "value": "166028" }
        ]
      }
    ]
  },
  "version": 5,
  "lastChanged": "2025-04-10T08:30:00Z",
  "isDeleted": false
}

HelseID (v2) endpoints

The v2 endpoints expose the same data and behave identically to their v1 counterparts. The differences are:

  • Authentication — a HelseID access token sent with a DPoP proof, instead of the X-API-KEY header. See HelseID (DPoP).
  • No rate limiting — v2 endpoints are not part of the per-API-key rate limiter described below.

Response shapes, query parameters, and versioned-diff semantics are identical to the v1 endpoints above.

GET /api/v2/treatment-group

Returns treatment group data. Supports the same filtering and version-based diff queries as GET /api/v1/treatment-group.

Parameters

Identical to GET /api/v1/treatment-group (since-version, name, disease-group, jurisdiction, indication, vare-nr, effective-date).

Response

Same envelope and entry shape as GET /api/v1/treatment-group.

Example

# Get all (authenticated with a HelseID DPoP access token + proof)
curl -H "Authorization: DPoP <access-token>" \
     -H "DPoP: <proof-jwt>" \
     https://api.example.com/api/v2/treatment-group

# Get changes since version 3
curl -H "Authorization: DPoP <access-token>" \
     -H "DPoP: <proof-jwt>" \
     https://api.example.com/api/v2/treatment-group?since-version=3

GET /api/v2/treatment-group/

Returns a single treatment group. Same id parameter and response shape as GET /api/v1/treatment-group/{id}.

GET /api/v2/reimbursement-group

Returns reimbursement group data. Supports the same filtering and version-based diff queries as GET /api/v1/reimbursement-group.

Parameters

Identical to GET /api/v1/reimbursement-group (since-version, indication).

Response

Same envelope and entry shape as GET /api/v1/reimbursement-group.

Example

curl -H "Authorization: DPoP <access-token>" \
     -H "DPoP: <proof-jwt>" \
     https://api.example.com/api/v2/reimbursement-group?indication=G35

GET /api/v2/reimbursement-group/

Returns a single reimbursement group. Same id parameter and response shape as GET /api/v1/reimbursement-group/{id}.


Response Envelope

All endpoints return data in the same envelope:

{
  currentVersion: number;     // The server's current data version
  entries: Array<{
    data: T;                  // The actual data object
    version: number;          // Version when this entry last changed
    lastChanged: string;      // ISO-8601 timestamp of last change
    isDeleted: boolean;       // Whether this entry has been removed
  }>;
}

GET /api/internal/health

Returns the health status of the API and its dependencies. This endpoint does not require authentication and is intended for load balancer and Kubernetes liveness/readiness probes.

Response

{
  "status": "healthy",
  "timestamp": "2025-04-10T08:30:00Z",
  "components": {
    "postgres": "healthy"
  }
}

When a dependency is unhealthy:

{
  "status": "unhealthy",
  "timestamp": "2025-04-10T08:30:00Z",
  "components": {
    "postgres": {
      "status": "unhealthy",
      "error": "Connection refused"
    }
  }
}

Status Codes

Code Meaning
200 OK All dependencies are healthy
503 ServiceUnavailable One or more dependencies are unhealthy

Example

curl http://localhost:5069/api/internal/health

HTTP Status Codes

Code Meaning
200 OK Success
400 Bad Request Missing or invalid parameter
401 Unauthorized Missing or invalid API key, or invalid/expired/replayed HelseID token or DPoP proof
403 Forbidden Authenticated via HelseID, but the access token is missing the required nhn:nompd/api scope
404 Not found Data not found in DB
429 Too Many Requests Rate limit exceeded (v1 endpoints only, see Rate Limiting)
500 Internal Server Error Server error
503 ServiceUnavailable Health check detected unhealthy dependency

Error Format

Unhandled server errors return 500 Internal Server Error with the following JSON body:

{
  "correlationId": "3f2b1c9a-4d5e-6f70-8192-a3b4c5d6e7f8"
}

In the Development environment, the body also includes message and stackTrace.

Every response — successful or error — includes an X-Correlation-Id response header. On 500 responses the same value is included in the body as correlationId. Clients may pass their own correlation ID via the X-Correlation-Id request header; it will be reused in the response and in server logs.

If the client aborts the request, no error response is written.

Rate Limiting

The data endpoints (/api/v1/treatment-group, /api/v1/reimbursement-group, /api/internal/sync) are rate limited to 120 requests per minute per API key (sliding window). The limit is configurable via the RateLimiting__PermitLimit, RateLimiting__WindowSeconds, and RateLimiting__QueueLimit environment variables. Rate limiting can be disabled entirely with RateLimiting__Enabled=false (default true).

The v2 (HelseID) endpoints are not rate limited.

When the limit is exceeded, the API responds with 429 Too Many Requests:

{ "error": "Rate limit exceeded. Try again later." }

The response includes a Retry-After header with the length of the rate-limit window in seconds. Waiting that long guarantees the request budget has fully replenished.

Notes:

  • Requests without a valid API key (missing or unknown) share a single anonymous bucket, which also prevents API-key brute-forcing.
  • The limit is enforced per replica (in-memory). With 3 replicas in production, the effective fleet-wide limit is ~3x the configured value.
  • RateLimiting__Enabled=false disables rate limiting on the data endpoints (requests pass through unthrottled). The flag is read at startup.
  • GET /api/internal/health and the Swagger UI are not rate limited.

Søk i Utviklerportalen

Søket er fullført!