API Endpoints
This API allows healthcare providers to create, update, and manage patient care plans. Each plan tracks clinical zones with recommended actions, maintains a full version history, and supports optimistic concurrency control to prevent lost updates.
Table of Contents
Environment
Development environment URL (no HelseID): https://planer.dev.nhn.no/
All requests and responses use Content-Type: application/json.
Data Model
Create Request
| Field | Type | Description |
|---|---|---|
status |
string |
Set by client on create |
comment |
string |
Reason or note for the change |
subject |
object |
Patient the plan belongs to (read-only after create) |
updated_by |
object |
Who updated the plan |
clinical_content |
object |
Clinical content request |
Update Request
| Field | Type | Description |
|---|---|---|
version |
int |
Required, must match current server version |
status |
string |
Set by client on update |
updated_by |
object |
Who updated the plan |
comment |
string |
Reason or note for the change |
clinical_content |
object |
Clinical content request |
Clinical Content Request
| Field | Type | Description |
|---|---|---|
title |
string |
Plan title |
description |
string |
Plan description |
zones |
array |
List of clinical zones |
Response
| Field | Type | Description |
|---|---|---|
id |
string |
UUID, assigned by server on create (read-only) |
version |
int |
Incremented by server on each update |
status |
string |
Current status |
updated_at |
string |
ISO 8601 timestamp, set by server (read-only) |
updated_by |
object |
Who updated the plan |
comment |
string |
Reason or note for the change |
subject |
object |
Patient the plan belongs to |
clinical_content |
object |
Clinical content response, versioned independently |
Clinical Content Response
| Field | Type | Description |
|---|---|---|
version |
int |
Content version, incremented by server on content updates |
title |
string |
Plan title |
description |
string |
Plan description |
zones |
array |
List of clinical zones |
Zone
| Field | Type | Description |
|---|---|---|
condition |
string |
Clinical condition for this zone |
action |
string |
Recommended action |
level |
string |
One of: green, yellow, red |
History Response
Lightweight version of Response used by the History endpoint. Omits id, subject, and clinical_content. Tracks only audit trail metadata.
| Field | Type | Description |
|---|---|---|
version |
int |
Version number of this history entry |
status |
string |
Status at this version |
updated_at |
string |
ISO 8601 timestamp, when this version was created |
updated_by |
object |
Health personnel who created this version |
comment |
string |
Comment for this version |
Health Personnel
| Field | Type | Description |
|---|---|---|
hpr_number |
string |
HPR identifier |
display_name |
string |
Full name |
Patient
| Field | Type | Description |
|---|---|---|
nin |
string |
National identity number |
Status Lifecycle
A plan can have one of the following statuses:
draft— needs follow upactive— can be shown to the patient, does not say whether the plan is approved or notrevoked— the plan has been withdrawn
The API does not validate or enforce any specific transition patterns.
Status transitions and who made them are recorded in the version history via updated_by, updated_at, and comment.
How Versioning Works
Each plan has two version counters:
Plan-level version (version):
- Starts at
1when the plan is created. - Incremented by the server on every update.
GET /plan/{id}always returns the latest version — the most recent entry in the version history.- Old versions are immutable — once created, a version never changes, even as new versions are added. You can retrieve any past version via
GET /plan/{id}/version/{version}. - When updating, you must include the current
versionin your request. If it doesn't match the server's version, you'll get a409 Conflict. This prevents lost updates when multiple users edit the same plan simultaneously.
Content-level version (clinical_content.version):
- Intended to track changes to the clinical content independently of plan metadata.
- Currently always set to
0— this feature is not yet implemented.
Endpoints
Create Plan
Creates a new plan.
POST /plan
Request body:
{
"status": "draft",
"comment": "Initial draft",
"subject": {
"nin": "12345678901"
},
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"clinical_content": {
"title": "Behandlingsplan",
"description": "Plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
Responses:
| Code | Description |
|---|---|
201 Created |
Plan created, returns full plan object |
422 Unprocessable Entity |
Invalid JSON |
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": 1,
"status": "draft",
"updated_at": "2024-03-15T10:30:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Initial draft",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Behandlingsplan",
"description": "Plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
curl
curl -X POST https://planer.dev.nhn.no/plan \
-H "Content-Type: application/json" \
-d '{
"status": "draft",
"comment": "Initial draft",
"subject": {
"nin": "12345678901"
},
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"clinical_content": {
"title": "Behandlingsplan",
"description": "Plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}'
Get Plan
Returns the latest version of a plan by ID.
GET /plan/{id}
Path parameters:
| Parameter | Description |
|---|---|
id |
Plan UUID |
Responses:
| Code | Description |
|---|---|
200 OK |
Returns plan object |
400 Bad Request |
Invalid UUID |
404 Not Found |
Plan not found |
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": 3,
"status": "active",
"updated_at": "2024-03-15T12:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Approved after review",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Behandlingsplan",
"description": "Plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
curl
curl https://planer.dev.nhn.no/plan/550e8400-e29b-41d4-a716-446655440000
Get Plan Version
Returns a specific historical version of a plan by ID and version number. The returned version is immutable — it reflects the plan exactly as it was at that point in time.
GET /plan/{id}/version/{version}
Path parameters:
| Parameter | Description |
|---|---|
id |
Plan UUID |
version |
Version number (int) |
Responses:
| Code | Description |
|---|---|
200 OK |
Returns plan object at version |
400 Bad Request |
Invalid UUID or version format |
404 Not Found |
Plan or version not found |
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": 2,
"status": "draft",
"updated_at": "2024-03-15T11:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Updated treatment plan",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Updated Behandlingsplan",
"description": "Revised plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
curl
curl https://planer.dev.nhn.no/plan/550e8400-e29b-41d4-a716-446655440000/version/2
Update Plan
Updates a plan, creating a new version. The version field must match the current server version; otherwise a 409 Conflict is returned. The version field is required; omitting it results in a 422 Unprocessable Entity.
PUT /plan/{id}
Path parameters:
| Parameter | Description |
|---|---|
id |
Plan UUID |
Request body:
{
"version": 2,
"status": "active",
"comment": "Updated treatment plan",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"clinical_content": {
"title": "Updated Behandlingsplan",
"description": "Revised plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
Responses:
| Code | Description |
|---|---|
200 OK |
Returns updated plan object |
400 Bad Request |
Invalid UUID |
404 Not Found |
Plan not found |
409 Conflict |
Version mismatch — plan was modified by another user |
422 Unprocessable Entity |
Invalid JSON or missing version field |
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": 2,
"status": "active",
"updated_at": "2024-03-15T11:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Updated treatment plan",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Updated Behandlingsplan",
"description": "Revised plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}
curl
curl -X PUT https://planer.dev.nhn.no/plan/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-d '{
"version": 2,
"status": "active",
"comment": "Updated treatment plan",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"clinical_content": {
"title": "Updated Behandlingsplan",
"description": "Revised plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
}'
Delete Plan
Deletes a plan and all its versions.
DELETE /plan/{id}
Path parameters:
| Parameter | Description |
|---|---|
id |
Plan UUID |
Responses:
| Code | Description |
|---|---|
200 OK |
Plan deleted |
400 Bad Request |
Invalid UUID |
404 Not Found |
Plan not found |
curl
curl -X DELETE https://planer.dev.nhn.no/plan/50e8400-e29b-41d4-a716-446655440000
Search Plans
Search plans by patient NIN and/or status. Returns the latest version of each matching plan.
GET /plan?patient={nin}&status={status}
Query parameters:
| Parameter | Required | Description |
|---|---|---|
patient |
true | Patient NIN |
status |
false | One of: draft, active, revoked |
Responses:
| Code | Description |
|---|---|
200 OK |
Returns array of matching plans (empty array if no matches) |
400 Bad Request |
Missing patient parameter, or invalid status value |
Example response:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": 3,
"status": "active",
"updated_at": "2024-03-15T12:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Approved after review",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Behandlingsplan",
"description": "Plan for patient with chronic obstructive pulmonary disease",
"zones": [
{
"condition": "Peak flow > 80%",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Peak flow 50-80%",
"action": "Increase medication dosage and contact GP within 24 hours",
"level": "yellow"
},
{
"condition": "Peak flow < 50%",
"action": "Call emergency services immediately",
"level": "red"
}
]
}
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"version": 1,
"status": "draft",
"updated_at": "2024-03-14T09:00:00Z",
"updated_by": {
"hpr_number": "987654321",
"display_name": "Dr. Olsen"
},
"comment": "Initial draft for diabetes management",
"subject": {
"nin": "12345678901"
},
"clinical_content": {
"version": 0,
"title": "Diabetesplan",
"description": "Plan for patient with type 2 diabetes",
"zones": [
{
"condition": "Blood glucose 4-7 mmol/L",
"action": "Continue current treatment",
"level": "green"
},
{
"condition": "Blood glucose 7-11 mmol/L",
"action": "Adjust diet and monitor closely",
"level": "yellow"
},
{
"condition": "Blood glucose > 11 mmol/L",
"action": "Contact GP immediately",
"level": "red"
}
]
}
}
]
curl
# Get all plans for patient:
curl "https://planer.dev.nhn.no/plan?patient=12345678901"
# Get all plans for patient with status 'draft':
curl "https://planer.dev.nhn.no/plan?patient=12345678901&status=draft"
Get Plan History
Returns all historical versions of a plan by ID. Returns an empty array if the plan is not found.
GET /plan/{id}/history
Path parameters:
| Parameter | Description |
|---|---|
id |
Plan UUID |
Responses:
| Code | Description |
|---|---|
200 OK |
Returns array of HistoryResponse objects (empty array if no plan found) |
400 Bad Request |
Invalid UUID format |
Example response:
[
{
"version": 1,
"status": "draft",
"updated_at": "2024-03-15T10:30:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Initial draft"
},
{
"version": 2,
"status": "draft",
"updated_at": "2024-03-15T11:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Updated treatment plan"
},
{
"version": 3,
"status": "active",
"updated_at": "2024-03-15T12:00:00Z",
"updated_by": {
"hpr_number": "123456789",
"display_name": "Dr. Hansen"
},
"comment": "Approved after review"
}
]
curl
curl https://planer.dev.nhn.no/plan/550e8400-e29b-41d4-a716-446655440000/history
Error Response
All error responses use this structure:
{
"error": "plan not found",
"code": "NOT_FOUND",
"details": "extra context"
}
| Field | Type | Description |
|---|---|---|
error |
string |
Human-readable error message |
code |
string |
Machine-readable error code (optional) |
details |
any |
Optional extra context |