For AI agents: the documentation index is at /docs/mdmbox/llms.txt. A Markdown version of this page is available at /docs/mdmbox/unmerge-operation.md or by requesting it with the Accept: text/markdown header.
MDMbox Docs

Unmerge operation

MDMbox provides two modes of $unmerge: server-managed $unmerge/v2, which reconstructs the reversal from the merge audit trail, and client-plan $unmerge, which executes a reverse transaction supplied by the caller. Both modes create an unmerge Task, Provenance, and AuditEvent, change the original merge Task to businessStatus=unmerged, and commit all changes atomically.

Use $unmerge when a merge was accepted by mistake and the affected resources must be restored or reassigned.

Server-managed unmerge

Pass the Task ID returned by the merge. MDMbox uses the recorded resource history to build a reverse plan. The example previews that plan with the default restore algorithm:

POST https://<mdmbox-host>/api/fhir/$unmerge/v2
Content-Type: application/fhir+json
{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "task",
      "valueReference": { "reference": "Task/merge-task-123" }
    },
    { "name": "unmerge-algorithm", "valueString": "restore" },
    { "name": "preview", "valueBoolean": true }
  ]
}
NameTypeRequiredDescription
taskvalueReferenceYesReference to the active pair-merge Task to reverse
unmerge-algorithmvalueStringNoServer-side algorithm id: built-in restore (default), strict, or a custom Git/database algorithm
previewvalueBooleanNoCompute and return the audited transaction plan without executing it (default: false)

Algorithms

Choose the policy for changes made after the merge:

AlgorithmLater changes
restore (default)Restores recorded pre-merge content, overwriting later edits with warnings
strictRefuses conflicting changes and reverses compatible reference updates

Restore restores the source, target, and resources changed by the merge. It deletes resources created by the merge, even if they were edited later. Overwritten or deleted resources are reported as warnings. Review the preview outcome before executing.

Strict returns HTTP 409 if the target changed, the source was recreated, or a merge-created resource was edited. For existing related resources changed by the merge, it restores references only at their original paths and preserves a later deletion of the entire resource.

Strict has an additional rule for references inside arrays: every containing array must still match its expected post-merge state. Reordering, adding or removing elements, or editing a field inside such an array causes a conflict. Changes outside those arrays are preserved. For a scalar Reference, only its reference value changes; later edits to fields such as display are kept.

Strict supports the reference changes made by the built-in simple merge algorithm. It is not a general inverse of arbitrary custom merge scripts.

Both built-ins preserve resources outside the original merge changes and warn about remaining references to the target. This search covers the related-resource-type scope saved by the merge Task.

Custom algorithms

Select a custom script with unmerge-algorithm and pass additional parameters through input.parameters. Scripts may change resources outside the original merge, including records created later, and validate their own assignment rules. All changes require version or absence preconditions and are audited.

See Algorithm management for built-in settings, database scripts, and Git sources. The JavaScript algorithm API describes inputs, helpers, result shapes, and plan restrictions.

Later merge chain

Reverse merges into the same target in reverse order, starting with the latest. If a later merge is still active, MDMbox returns HTTP 409 with an OperationOutcome listing the Task chain and the Task to unmerge first.

Preview and response

For preview, the response is a Parameters resource containing outcome (OperationOutcome) and plan (the complete audited transaction Bundle). Preview performs no writes.

Set preview=false to execute. Success returns HTTP 200 with outcome and the new unmerge task. Warnings do not block execution. The reversal and its successful audit records commit together; failed attempts are audited separately. See Audit.

Concurrent changes during unmerge return HTTP 409 and roll back the operation. This protects new writes even when using restore to replace earlier edits.

StatusMeaning
400Invalid request or unavailable algorithm
404Merge Task or original target is missing; unmerge does not recreate a deleted target
409Later merge in the chain, algorithm conflict, or concurrent change
422Missing or inconsistent audit/history evidence, or invalid FHIR transaction data
500Algorithm or storage failure

Errors return an OperationOutcome and make no partial business changes.

Required history

Keep the original Task, Provenance, pre-merge snapshots, and recorded post-merge versions, including creation versions of resources added by the merge. An edited audit record or another resource version cannot replace missing evidence. Missing or inconsistent history returns HTTP 422 without partial restoration.

The Task also retains the target version when merge left it unchanged, and the original related-resource-type search scope.

Client-plan unmerge

The $unmerge operation reverses a previous merge by executing a client-provided FHIR transaction Bundle. The client decides exactly how to restore resources; MDMbox validates the referenced merge Task, adds audit resources, flips the original merge Task to unmerged, and executes everything atomically.

How it works

  1. Read the merge Task and its Provenance with GET https://<aidbox-host>/fhir/Provenance?target=Task/<task-id>.
  2. Build a reverse transaction Bundle and send it to $unmerge with the Task reference.
  3. MDMbox adds audit records, marks the original Task unmerged, and commits or rolls back the transaction as a whole.

Request

POST https://<mdmbox-host>/api/fhir/$unmerge
Content-Type: application/json
{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "task",
      "valueReference": { "reference": "Task/merge-task-123" }
    },
    { "name": "preview", "valueBoolean": false },
    {
      "name": "plan",
      "resource": {
        "resourceType": "Bundle",
        "type": "transaction",
        "entry": [
          {
            "request": {
              "method": "PUT",
              "url": "Patient/primary-456",
              "ifMatch": "W/\"4\""
            },
            "resource": {
              "resourceType": "Patient",
              "id": "primary-456",
              "name": [{ "given": ["John"], "family": "Smith" }]
            }
          },
          {
            "request": { "method": "PUT", "url": "Patient/duplicate-123" },
            "resource": {
              "resourceType": "Patient",
              "id": "duplicate-123",
              "name": [{ "given": ["Jon"], "family": "Smyth" }]
            }
          },
          {
            "request": {
              "method": "PUT",
              "url": "Encounter/enc-789",
              "ifMatch": "W/\"2\""
            },
            "resource": {
              "resourceType": "Encounter",
              "id": "enc-789",
              "status": "finished",
              "class": { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB" },
              "subject": { "reference": "Patient/duplicate-123" }
            }
          }
        ]
      }
    }
  ]
}

Parameters

NameTypeRequiredDescription
taskvalueReferenceYesReference to the original merge Task
previewvalueBooleanNoIf true, return the assembled Bundle without executing (default: false)
planresource (Bundle)YesFHIR transaction Bundle with the reverse changes

Plan Bundle

The plan is a standard FHIR transaction Bundle. It commonly contains:

  • PUT entries that restore the target and related resources to the desired post-unmerge state
  • PUT entries that recreate resources deleted by the merge
  • PUT entries that reassign related resources back to the restored source
  • optional POST or DELETE entries if the client policy requires them

Allowed plan methods are PUT, POST, and DELETE. The plan must not contain duplicate PUT or DELETE URLs.

Use ifMatch for optimistic locking when updating live resources. If a resource changed after the client built the reverse plan, the FHIR transaction rolls back and $unmerge returns 422 Unprocessable Entity with an OperationOutcome code such as conflict.

Preview mode

In the request above, change preview to true and keep the complete reverse plan. The response is FHIR Parameters with outcome and bundle, including the proposed audit records and merge Task update. Preview writes nothing.

Client-plan preview checks request structure and current state. FHIR resource validation occurs during execution.

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": "task",
            "valueReference": { "reference": "Task/merge-task-123" }
          },
          { "name": "preview", "valueBoolean": false }
        ]
      }
    },
    {
      "name": "task",
      "resource": {
        "resourceType": "Task",
        "id": "generated-unmerge-task-id",
        "status": "completed",
        "intent": "order",
        "code": { "coding": [{ "code": "unmerge" }] },
        "businessStatus": { "coding": [{ "code": "completed" }] },
        "basedOn": [{ "reference": "Task/merge-task-123" }]
      }
    }
  ]
}

The input-parameters echo omits the potentially large plan parameter.

Audit trail

Every executed unmerge creates or updates these resources in the same transaction:

Unmerge Task

  • code - unmerge
  • businessStatus - completed
  • basedOn - the original merge Task
  • for and focus - copied from the original merge Task when present

Original merge Task

  • businessStatus changes from merged to unmerged
  • updated with ifMatch using the Task version read during validation

Provenance

  • activity - unmerge from http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle
  • target - every reverse-plan target plus the unmerge Task
  • entity[] - versioned references to pre-unmerge revisions when available
  • agent - Device/mdmbox

AuditEvent records the initiating user or client when available, outcome, service, correlation, and references to the original merge Task, new unmerge Task, Provenance, and domain resources. If this event cannot be written, the reversal rolls back. See Audit for failure and preview behavior.

After a successful unmerge, the original source can be merged again because the previous merge Task is no longer active.

Validation

MDMbox validates the unmerge request before execution:

Structural validation (400 Bad Request):

  • Request body must be a FHIR Parameters resource
  • task is required
  • plan must be a transaction Bundle with at least one entry
  • Plan methods must be PUT, POST, or DELETE
  • No duplicate PUT or DELETE URLs in the plan

State validation (422 Unprocessable Entity):

  • The referenced Task must exist
  • The Task must be a merge Task (code=merge)
  • The merge Task must still be active (businessStatus=merged)

FHIR transaction validation (422 or 500):

  • If any transaction entry fails validation or optimistic locking, the whole transaction rolls back
  • Client-side transaction failures return 422 with an OperationOutcome
  • Server-side transaction failures return 500

See also

Last updated: