IKJ-API overview
Informasjon fra Kommunal Journal (IKJ) provides endpoints for submitting and retrieving patient information. Patient resources are represented using the FHIR standard, version R4.
Available environments
| Environment | FQDN |
|---|---|
| Test | api.ikj.test.nhn.no |
Access control
Accessing the IKJ API requires clients to be authenticated using HelseID and DPoP (Demonstrating Proof-of-Possession):
- Scope: Clients must request the appropriate scope (
nhn:ikj/api.readornhn:ikj/api.write). - Claim: Access token must include claim
helseid://claims/client/claims/orgnr_parent. - DPoP required: Only requests including DPoP tokens are accepted.
- Authorization header: Access token must be sent using the
DPoPprefix (i.e., notBearer). - DPoP-Proof: Requests must include a
DPoPheader with a signed proof generated by the client.
See HelseID Dokumentasjon - DPoP for implementation details.
Supported resource types
IKJ currently supports two resource types: Patient and EpisodeOfCare. The supported functionality is described for each resource type in separate sections below.
Patient resources
IKJ supports submitting, updating and retrieving Patient resources. The behavior is elaborated below.
Submitting patient resources
Patient resources are submitted by making POST requests to the Patient endpoint.
Endpoint format: POST /v1/Patient
A successful submission returns 202 Accepted. Processing is asynchronous — the resource is queued for
internal processing after being accepted. The server assigns the resource ID, but it is not included in this
initial response — it only becomes available once the Task resource reports the processing as successfully
completed. The Location header contains the URL of the Task resource that can be polled to check the processing
status; this URL is identified by an internal event ID that the server generates for this specific request, not
by the (not yet known) resource ID.
Note
There is a request size limit of approximately 900 KB for this endpoint.
Updating patient resources
Existing patient resources are replaced by making PUT requests to the Patient endpoint.
Endpoint format: PUT /v1/Patient/{resourceId}
The {resourceId} must be the system-generated resource ID of a previously submitted Patient resource, obtained
from the Task resource of an earlier successful POST (or PUT) once its processing completed — it cannot be
chosen by the client. The value in the URL is authoritative; if the request body includes an id field that
differs from the URL value, the request is rejected with 400 Bad Request immediately.
A successful request returns 202 Accepted. Processing is asynchronous — the same status mechanism used for
POST applies here: the Location header contains the URL of the Task resource, identified by a new internal
event ID generated for this request (distinct from the {resourceId} being updated). Because processing is
asynchronous, the outcome (success or failure) must be checked via the Task endpoint using that event ID. A PUT
to a resource that does not exist will result in a failed processing status.
A PUT replaces the stored resource in full — it is not a merge. This applies to the patient's identifiers as
well: the stored set of identifiers becomes exactly the set present in the request body, so an identifier that
was stored earlier but is omitted from the body is removed. A removed identifier also stops working as a
lookup key for GET /v1/Patient?identifier={system}|{value} and PUT /v1/Patient?identifier={system}|{value}.
Conversely, if an identifier in the body is already registered to a different patient in your organization,
processing fails — two existing patients are never merged into one.
Note
There is a request size limit of approximately 900 KB for this endpoint.
Updating by identifier
Existing patient resources can also be updated by FHIR identifier instead of resource ID.
Endpoint format: PUT /v1/Patient?identifier={system}|{value}
The identifier query parameter must be in the format system|value and must match one of the identifiers in
the request body — the request is rejected with 400 Bad Request if the body does not include a matching
identifier. Because the query identifier must also be present in the body, it is the one identifier this
endpoint cannot change; to change it, use another of the patient's identifiers as the query parameter, or use
the resource-ID-based PUT. This endpoint only updates existing patients: if no patient matching the identifier
exists in your organization, the request is still accepted (202), but processing fails — the resource is
not updated.
The id field in the request body is optional here. When it is omitted, the server fills in the resource ID of
the patient found by identifier, so the stored resource always carries its server-assigned ID; that ID is also
reported by the Task resource once processing completes. If an id is present, it is compared to the
resource ID of the patient found by identifier once processing runs; a mismatch fails processing.
Everything else — asynchronous processing, the Location/status-polling mechanism, and the 900 KB request
size limit — is identical to the resource-ID-based PUT described above.
Retrieving patient resources
Patient resources are retrieved by making GET requests to the Patient endpoint.
Endpoint format: GET /v1/Patient
There are three ways of invoking this endpoint:
- By submitting the resource id in the URL, e.g.
GET /v1/Patient/12345 - By submitting a single query parameter indicating the requested identifier to search for, e.g.
GET /v1/Patient?identifier=a|b - By submitting a set of search parameters restricting the result set, e.g.
GET /v1/Patient?_lastUpdated=ge2024-01-01T12:00Z
The three use cases will be elaborated in the subsections below. Note that the three use cases are mutually exclusive: It is not allowed to combine query parameters from the three use cases in a single query, this will result in an OperationOutcome with the appropriate error message.
Search for a single patient by resource id
The response is single FHIR Patient if there is a match, or otherwise, an OperationOutcome.
When a Patient is submitted, the returned content location can be used to query the status of the submission. Eventually,
upon successful completion, the Task returned will contain a value reference indicating the resource id of the submitted Patient,
e.g. Patient/12345. This resource id can then be submitted using the GET /v1/Patient/12345 endpoint to retrieve the Patient resource.
Search for a single patient by identifier
The response is single FHIR Patient if there is a match, or otherwise, an OperationOutcome.
A Patient resource is submitted with one or more identifiers, which are composed by a system and a value. The combination of
parentOrgNo, system and value is unique, and since a query will only be able to access data belonging to the parentOrgNo
for which the client is authorized, there will never be more than one match for a requested identifier.
The Patient endpoint can be used to search for a Patient with a given identifier by accessing the endpoint like GET /v1/Patient?identifier=a|b.
Search for a set of patients by query parameters
The response is a FHIR Bundle containing matching Patient resources, possibly none.
Filtering
_lastUpdatedlimits results based on when resources were last updated in IKJ. Requires a prefix (gt,ge,lt,le) with at least minute precision. Example:ge2024-01-01T12:00Z.
Pagination
Keyset pagination (also known as seek pagination) limits the number of resources returned per request.
An opaque cursor parameter is used to retrieve the next page of results. The response Bundle includes a next
link containing the cursor value.
_countcontrols the page size (1–50, default 20)._sortcontrols the sort order:_lastUpdatedfor ascending (default) or-_lastUpdatedfor descending.
Cursor constraints:
- Treat the
cursorvalue as completely opaque — do not attempt to decode or modify it. - Combining filter parameters (
_lastUpdated) with a cursor is not allowed and will result in a400error. - When a cursor is provided, the
_sortparameter is ignored.
Pagination example
GET /v1/Patient?_count=10&_sort=-_lastUpdated
The response Bundle includes self and next link elements:
{
"resourceType": "Bundle",
"type": "searchset",
"link": [
{
"relation": "self",
"url": "https://api.ikj.test.nhn.no/v1/Patient?_count=10&_sort=-_lastUpdated"
},
{
"relation": "next",
"url": "https://api.ikj.test.nhn.no/v1/Patient?cursor=ZXlKTVlYTjB..."
}
]
}
To fetch the next page, follow the next link via GET.
EpisodeOfCare resources
IKJ supports submitting and retrieving EpisodeOfCare resources. The behavior is elaborated below.
Submitting EpisodeOfCare resources
EpisodeOfCare resources are submitted by making POST requests to the EpisodeOfCare endpoint.
Endpoint format: POST /v1/EpisodeOfCare
A successful submission returns 202 Accepted. Processing is asynchronous — the resource is queued for
internal processing after being accepted. The server assigns the resource ID, but it is not included in this
initial response — it only becomes available once the Task resource reports the processing as successfully
completed. The Location header contains the URL of the Task resource that can be polled to check the processing
status; this URL is identified by an internal event ID that the server generates for this specific request, not
by the (not yet known) resource ID.
Note
There is a request size limit of approximately 900 KB for this endpoint.
Retrieving EpisodeOfCare resources
EpisodeOfCare resources are retrieved by making GET requests to the EpisodeOfCare endpoint.
Endpoint format: GET /v1/EpisodeOfCare
The only one way of invoking this endpoint is by submitting the resource id in the URL, e.g. GET /v1/EpisodeOfCare/12345.
The response is a single FHIR EpisodeOfCare if there is a match, or otherwise, an OperationOutcome.
When an EpisodeOfCare is submitted, the returned content location can be used to query the status of the submission. Eventually,
upon successful completion, the Task returned will contain a value reference indicating the resource id of the submitted EpisodeOfCare,
e.g. EpisodeOfCare/12345. This resource id can then be submitted using the GET /v1/EpisodeOfCare/12345 endpoint to retrieve the EpisodeOfCare resource.