API Endpoints v2
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, supports optimistic concurrency control to prevent lost updates, and includes an approval and publication workflow.
Table of Contents
- Environment
- Status Lifecycle
- Approval Lifecycle
- Publication Lifecycle
- How Versioning Works
- Endpoints
- Error Response
- Implementation Notes
Environment
Development environment URL (no HelseID): https://planer.dev.nhn.no/
Swagger UI: https://planer.dev.nhn.no/api/swagger/
All requests and responses use Content-Type: application/json.
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
Status transitions and who made them are recorded in the version history via updated_by, updated_at, and comment.
Approval Lifecycle
Separate from status, each plan tracks an approval state:
- (none) — no approval process has been initiated
approval_requested— approval has been requestedapproval_given— approval has been grantedapproval_rejected— approval has been rejected
The rejection_reason field is populated on the response when approval is rejected.
Publication Lifecycle
Separate from status and approval, each plan tracks per-provider publication state in the publication_status array. This allows different providers to independently publish or unpublish the plan to their own patient-facing systems.
published— the plan is available to view by the patient in this provider's systemunpublished— the plan is not available to view by the patient in this provider's system
When a provider publishes a plan, they specify which content_version to publish. The publication_status array contains one entry per provider that has published or unpublished the plan.
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 mutation.
GETendpoints always return the latest version.- Old versions are immutable — once created, a version never changes. Retrieve any past version via
GET /api/v2/plan/{id}/version/{version}. - Every mutation (except create) requires the current
versionin the request body. 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 (content_version):
- Tracks changes to the clinical content independently of plan metadata.
- Incremented when clinical content is updated via
$update-content. - Referenced by
$publishand$unpublishto specify which content snapshot to publish.
Endpoints
For request/response schemas, parameters, and status codes, use the Swagger UI.
| Method | Path | Description |
|---|---|---|
POST |
/api/v2/plan |
Create a new plan |
GET |
/api/v2/plan/{id}/$latest |
Latest version from write-side event store |
GET |
/api/v2/plan/{id} |
Latest version from read-side projection |
GET |
/api/v2/plan/{id}/version/{version} |
Specific historical version |
GET |
/api/v2/plan/{id}/history |
Version history (audit trail) |
GET |
/api/v2/plan?patient={nin} |
Search plans by patient |
POST |
/api/v2/plan/{id}/$update-content |
Update clinical content |
POST |
/api/v2/plan/{id}/$draft |
Set status to draft |
POST |
/api/v2/plan/{id}/$activate |
Set status to active |
POST |
/api/v2/plan/{id}/$revoke |
Set status to revoked |
POST |
/api/v2/plan/{id}/$approval-requested |
Request approval |
POST |
/api/v2/plan/{id}/$approval-given |
Grant approval |
POST |
/api/v2/plan/{id}/$approval-rejected |
Reject approval |
POST |
/api/v2/plan/{id}/$publish |
Mark as published in provider's patient system |
POST |
/api/v2/plan/{id}/$unpublish |
Mark as unpublished in provider's patient system |
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 |
Implementation Notes
This API uses CQRS (Command Query Responsibility Segregation) and event sourcing under the hood. The CQRS separation is internal; externally all v2 endpoints are unified under /api/v2/. This provides scalability and consistency guarantees without exposing the CQRS pattern to API consumers.