Link operation
The $link operation links related FHIR resources without merging their data. The client provides a FHIR transaction Bundle that creates or patches a profiled Linkage; MDMbox validates cluster membership (one external record can belong to only one active MDM Linkage), adds audit resources, and executes the Bundle atomically.
Use $link when records should remain separate resources but should be tracked as belonging to the same identity cluster or review decision.
How it works
- Build a transaction Bundle that creates or extends a profiled
Linkage, optionally including a golden view. - Send the plan to
$link. MDMbox checks cluster membership and adds audit records. - Save the returned Task ID to unlink later. The transaction commits or rolls back as a whole.
Request
POST https://<mdmbox-host>/api/fhir/$link
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "preview", "valueBoolean": false },
{
"name": "plan",
"resource": {
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:11111111-1111-1111-1111-111111111111",
"request": { "method": "POST", "url": "Linkage" },
"resource": {
"resourceType": "Linkage",
"meta": {
"profile": [
"https://mdm.health-samurai.io/fhir/StructureDefinition/mdm-linkage"
]
},
"active": true,
"item": [
{
"type": "source",
"resource": { "reference": "Patient/golden" }
},
{
"type": "alternate",
"resource": { "reference": "Patient/duplicate" }
}
]
}
}
]
}
}
]
}
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
preview | valueBoolean | No | If true, return the assembled Bundle without executing (default: false) |
plan | resource (Bundle) | Yes | FHIR transaction Bundle that creates or patches a profiled Linkage |
Linkage profile
New Linkage resources must include this profile:
https://mdm.health-samurai.io/fhir/StructureDefinition/mdm-linkage
The Linkage is expected to be active. MDMbox uses the profile namespace when checking whether a resource is already linked.
Plan Bundle
The plan must be a transaction Bundle and must create or patch at least one Linkage.
Use POST to create a profiled Linkage, or PATCH to extend one with FHIRPath Patch add or insert operations. Other methods and patch operations are rejected.
Golden view
A Linkage may include a contained "golden view" resource: a client-built canonical view of the linked records stored inside Linkage.contained. The Linkage then references it with a local contained reference such as #golden:
{
"resourceType": "Linkage",
"contained": [
{
"resourceType": "Patient",
"id": "golden",
"name": [{ "given": ["John"], "family": "Smith" }]
}
],
"item": [
{ "type": "source", "resource": { "reference": "#golden" } },
{ "type": "alternate", "resource": { "reference": "Patient/pat-1" } },
{ "type": "alternate", "resource": { "reference": "Patient/pat-2" } }
]
}
The golden view is stored inside the Linkage. Membership checks and the audit Task include only external record references.
Search
If you know the Linkage.id, retrieve the MDM Linkage and its Patient members:
GET https://<aidbox-host>/fhir/Linkage?_id=linkage-123&_profile=https://mdm.health-samurai.io/fhir/StructureDefinition/mdm-linkage&_include=Linkage:item:Patient
Accept: application/json
To find a cluster by a known Patient and include its members and Encounters:
GET https://<aidbox-host>/fhir/Linkage?item=Patient/pat-1&_profile=https://mdm.health-samurai.io/fhir/StructureDefinition/mdm-linkage&_include=Linkage:item:Patient&_revinclude:iterate=Encounter:subject:Patient
Accept: application/json
For include parameters and other resource types, see Aidbox FHIR search.
Preview mode
In the request above, change preview to true and keep the complete plan. The response is FHIR Parameters containing outcome and bundle, the assembled transaction including audit resources.
Preview does not persist the Linkage, Task, Provenance, or operation AuditEvent. See Audit for authentication failures and malformed requests.
Response
On success, the response is a Parameters resource containing:
{
"resourceType": "Parameters",
"parameter": [
{
"name": "outcome",
"resource": {
"resourceType": "OperationOutcome",
"issue": [{ "severity": "information", "code": "informational" }]
}
},
{
"name": "input-parameters",
"resource": {
"resourceType": "Parameters",
"parameter": [{ "name": "preview", "valueBoolean": false }]
}
},
{
"name": "task",
"resource": {
"resourceType": "Task",
"id": "generated-link-task-id",
"status": "completed",
"intent": "order",
"code": { "coding": [{ "code": "link" }] },
"businessStatus": { "coding": [{ "code": "linked" }] },
"input": [
{
"type": { "text": "linked-record" },
"valueReference": { "reference": "Patient/golden" }
},
{
"type": { "text": "linked-record" },
"valueReference": { "reference": "Patient/duplicate" }
}
]
}
}
]
}
The input-parameters echo omits the potentially large plan parameter.
Audit trail
Every executed link creates audit resources in the same transaction:
Task
code-linkbusinessStatus-linkedinput[]- linked external record references
Provenance
activity-linkfromhttp://terminology.hl7.org/CodeSystem/iso-21089-lifecycletarget- the Linkage plan targets plus the link Taskentity[]- pre-change revisions for patched Linkages when availableagent-Device/mdmbox
AuditEvent records the initiating user or client when available, outcome, service, correlation, and references to the Task, Provenance, linked records, and plan targets. If it cannot be written, the link rolls back. See Audit for queries and failure handling.
Unlink
A completed link can be reversed with $unlink. The unlink request points to the original link Task and supplies a client-built reverse transaction Bundle, usually deleting the profiled Linkage. MDMbox executes that reverse plan atomically, creates its own Task, Provenance, and AuditEvent, and updates the original link Task to businessStatus=unlinked.
See Unlink operation.
Validation
MDMbox validates the link request before execution:
Structural validation (400 Bad Request):
- Request body must be a FHIR
Parametersresource planmust be a transaction Bundle with at least one entry- The plan must create or patch at least one Linkage
- Linkage
POSTentries must include the MDM Linkage profile - Plan methods must be
POSTorPATCH - FHIRPath Patch entries may only use
addorinsert
State validation (409 Conflict or 422 Unprocessable Entity):
- A PATCH target must already carry the MDM Linkage profile (
422) - A record must not join multiple active Linkages inside the same plan (
409) - A record must not already belong to another active profiled Linkage (
409)
FHIR transaction validation (422 or 500):
- If FHIR validation or persistence fails, the whole transaction rolls back
- Client-side transaction failures return
422with anOperationOutcome - Server-side transaction failures return
500