Subscription
Subscriptions notify your integration when data changes for a municipality. Your integration creates a subscription through the FHIR API, and a municipality administrator approves it in Self Service. Once active, the subscription sends notifications to your webhook endpoint.
Open Aidn uses FHIR R4 with the R4 profiles from the
Subscriptions R5 Backport Implementation Guide.
This is not the FHIR R5 Subscription resource. Notifications contain resource references, not the
changed clinical resources.
Before you start
- Set up an approved OAuth client for the correct municipality and environment. See Authentication and access.
- Request
subscription.writeto create, delete, and query subscription status. Requestsubscription.readto read a Subscription resource. - Prepare an HTTPS webhook endpoint that can receive HTTP POST requests with FHIR JSON and return
a successful HTTP status (
2xx). It must be reachable from Aidn, not just from your workstation. - Arrange approval with a municipality administrator who can manage FHIR subscriptions.
Subscription access is scoped to the municipality associated with your authenticated client. You cannot create or manage subscriptions for another municipality by including an identifier in the request body.
Supported topics
Use a topic’s canonical URL as Subscription.criteria. Do not use a FHIR search expression such as
Patient?active=true. Create a separate subscription for each topic you need.
| Topic | Canonical URL | Notification focus |
|---|---|---|
| Patient changes | https://aidn.no/fhir/SubscriptionTopic/patient-changed |
Patient/{id} |
| EpisodeOfCare changes | https://aidn.no/fhir/SubscriptionTopic/episode-of-care-changed |
EpisodeOfCare/{id} |
Subscriptions receive matching events for their municipality. Patient, department, and other search filters are not supported. A notification signals a change; it does not describe which fields changed or whether the event represents creation, an update, or deletion.
Endpoints
Paths below are relative to your environment’s FHIR base URL, for example
https://open.demo.aidn.no/fhir in DEMO.
| Method | Path | Required scope | Description |
|---|---|---|---|
POST |
/Subscription |
subscription.write |
Request a new subscription. |
GET |
/Subscription/{id} |
subscription.read |
Read a subscription in your municipality. |
GET |
/Subscription/$status |
subscription.write |
Query subscription statuses. |
GET |
/Subscription/{id}/$status |
subscription.write |
Query one subscription’s status. |
DELETE |
/Subscription/{id} |
subscription.write |
Delete a subscription. |
The public FHIR API does not support Subscription search, update, or approval operations. Approval is performed by the municipality administrator in Self Service.
Create a subscription
Send the following resource to POST /Subscription. Replace the webhook URL with your endpoint
and choose the topic for your use case.
{
"resourceType": "Subscription",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription"
]
},
"status": "requested",
"reason": "Notify our integration about patient changes",
"criteria": "https://aidn.no/fhir/SubscriptionTopic/patient-changed",
"channel": {
"type": "rest-hook",
"endpoint": "https://receiver.example.com/aidn-notifications",
"payload": "application/fhir+json",
"_payload": {
"extension": [
{
"url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-payload-content",
"valueCode": "id-only"
}
]
}
}
}
Include these headers:
Authorization: Bearer <ACCESS_TOKEN>
Accept: application/fhir+json
Content-Type: application/fhir+json
The backport profile, a non-empty reason, supported topic, rest-hook channel, and id-only
payload extension are required. Full-resource payloads and Subscription.end are not supported.
A successful request returns 201 Created and the stored Subscription. Save its id for future
read, status, and delete requests. A new subscription is always stored as requested; submitting
active does not bypass approval.
If your receiver requires authentication, you can add channel.header entries, for example
"header": ["Authorization: Bearer <WEBHOOK_TOKEN>"]. These headers are sent with both the
handshake and event notifications. Use a dedicated receiver credential, not your Open Aidn API
access token. Store it securely and avoid logging the Subscription body. Malformed headers,
hop-by-hop headers, and Content-* headers are rejected.
Approve in Self Service
- Sign in to the municipality’s Self Service portal in the same environment as the subscription.
- Open FHIR-abonnementer. The administrator needs Administrere FHIR-abonnementer
(
fhir-subscription.manage) for the municipality. This administrative permission is separate from your integration’s OAuth scopes. - Check the requested topic, reason, and webhook endpoint before activating the subscription.
- Select Aktiver for the requested subscription and confirm.
- Refresh the list and check the resulting status.
Activation sends a handshake to your webhook. If the receiver returns 2xx, the subscription
becomes active. If the handshake fails, its status becomes error. Only active subscriptions
receive change notifications. Prepare the receiver before asking the administrator to activate.
If activation fails, correct the receiver and contact the administrator or Aidn to arrange a retry. The public FHIR API cannot activate a subscription. To change its topic, URL, or headers, delete it and create a replacement that the administrator can approve.
Receive notifications
Your receiver gets HTTP POST requests with Content-Type: application/fhir+json. Both handshakes
and event notifications are FHIR Bundle resources with type set to history and profile:
http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription-notification-r4
The Bundle contains a Parameters resource with the backport status profile:
http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription-status-r4
Read the named parameters rather than relying on their positions:
| Parameter | Meaning |
|---|---|
subscription |
A reference such as Subscription/{id}. |
topic |
The subscribed topic’s canonical URL. |
status |
Subscription status. The activation handshake reports active. |
type |
handshake or event-notification. |
events-since-subscription-start |
Subscription event counter, encoded as valueString. |
notification-event |
Present on event notifications, with event-number, timestamp, and focus parts. |
A handshake has event count "0" and no changed-resource focus. A change notification includes an
id-only focus reference such as EpisodeOfCare/{id}. Its event number is also a string. The
resource itself is not included, and receiving a notification does not grant access to clinical
data. Reading a resource requires its own OAuth scope and approved access.
Patient ID limitation: current Patient notifications use the ID from the underlying Health
person event. This is not guaranteed to be the municipality-specific FHIR Patient ID. Do not assume
that GET /Patient/{id} will resolve the reference. Confirm Patient identifier mapping with Aidn
before depending on this topic for resource retrieval.
Authenticate incoming requests using the receiver credentials you configured, and return 2xx
only after accepting the notification. Protect resource references and credentials as sensitive
data. Design processing to tolerate duplicates and do not rely on delivery ordering.
The service does not currently provide webhook delivery retries or a replay endpoint. The event counter advances before delivery, so it is not a count of successfully received notifications. Do not use notifications as the only source of truth for a complete data synchronization.
Check status
For one subscription:
GET /Subscription/<SUBSCRIPTION_ID>/$status HTTP/1.1
Authorization: Bearer <ACCESS_TOKEN>
Accept: application/fhir+json
The response is a FHIR Bundle with type set to searchset. Each entry contains profiled
Parameters with type=query-status, the subscription reference, topic, status, and event count.
An error parameter is included when an error has been recorded.
To query several subscriptions, use repeated parameters, for example
/Subscription/$status?id=<ID_1>&id=<ID_2>&status=active. Both the ID and status filters apply when
provided. Without filters, the operation returns statuses for your municipality’s subscriptions.
Stop notifications
Send DELETE /Subscription/{id} with a token that has subscription.write. A successful deletion
returns 204 No Content. The administrator can also delete a subscription in FHIR-abonnementer.
Allow for notifications already in progress when deleting a subscription.
Troubleshooting
| Symptom | What to check |
|---|---|
400 Bad Request on creation |
Read the FHIR OperationOutcome. Check the profile, topic, channel, payload extension, reason, and headers. Omit end. |
401 or 403 |
Check token validity, environment, configured client scopes, and municipality access. $status currently requires subscription.write. |
404 when reading or deleting |
Check the subscription ID and municipality. A subscription in another municipality is not accessible. |
| The approval page is missing | Check the administrator’s municipality-level fhir-subscription.manage permission. |
Status stays requested |
Ask the municipality administrator to approve it. Creation alone does not activate delivery. |
Activation results in error |
Check webhook reachability, TLS, receiver authentication, and the receiver’s HTTP response. |
| An active subscription receives no notifications | Confirm that changes match its topic and municipality, then inspect receiver logs. Notifications are not an initial data export. |
When contacting Aidn, provide the environment, subscription ID, status, and approximate time of the failure. Do not include access tokens, webhook credentials, or patient data.