Skip to content

Digital Identity Update & Merge Integration Guide

PIS Interoperability Layer


1. Purpose of This Document

This document defines how consuming systems MUST process identity update events published by the Population Information System (PIS).

It applies to systems that:

  • Persist identity data locally, and
  • Reference identities from domain records such as payroll, benefits, licensing, or payments.

The objective is to ensure:

  • Correctness of downstream domain data
  • Protection against duplicate identities
  • Safe, deterministic handling of identity merges

2. Event Model Overview

PIS publishes a single event type for all identity changes:

biographic-api.persons.updated

Each event contains:

  1. A canonical identity snapshot
  2. An optional merge instruction

ℹ️ Note
There are no separate merge events.
Snapshot updates, UPN changes, and identity merges are all delivered through the same update stream.


3. Canonical Identity Snapshot

Each event contains the full current state of the identity after all updates and merges.

Key fields

FieldDescription
identity.idStable primary identity identifier
identity.versionIdentity version
identity.currentUPNCurrent UPN
identity.UPNsAll historical UPNs
Biographic attributesNames, DOB, sex, etc.

ℹ️ Important
The snapshot represents future truth, not a diff.
It already reflects the final state after merges and updates.


4. Merge Instruction (merge)

If present, the merge object MUST be interpreted as an instruction to reconcile downstream state.

Merge schema

json
{
  "version": 1,
  "fromIdentityIds": ["IDENTITY_ID"],
  "fromIdentityUpns": ["UPN"]
}

Semantics

  • merge.version
    A monotonically increasing value per identity.
    Used to detect whether a new merge must be handled.

  • fromIdentityIds
    The complete list of absorbed identity IDs.

  • fromIdentityUpns
    Optional convenience for legacy systems that still index by UPN.

⚠️ Warning
The merge object is the only authoritative merge signal.
Audit or historical fields MUST NOT be used to infer merges.


5. Sample Payload

The following example illustrates the canonical update event structure and where the merge instruction appears. This is a representative example based on the published event schema.

json
{
  "id": "694a7258e2d01b431f89afcc",
  "type": "biographic-api.persons.updated",
  "data": {
    "id": "607417dcd6527600122216ee",
    "group": "citizen",
    "status": "active",
    "version": 2,
    "currentUPN": "4850110280892",
    "UPNs": ["4850110280892", "4850110730110"],
    "dateOfBirth": "1985-01-10T00:00:00.000Z",
    "sexAtBirth": "female",
    "names": {
      "asOnId": {
        "first": "نادیە",
        "second": "توفیق",
        "third": "محمد",
        "fourth": ""
      },
      "first": {
        "original": "نادیە",
        "in_english_characters": "",
        "in_latin_characters": "نادیە",
        "in_arabic_characters": "نادیە"
      },
      "middle": {
        "original": "توفیق",
        "in_english_characters": "",
        "in_latin_characters": "توفیق",
        "in_arabic_characters": "توفیق"
      },
      "last": {
        "original": "محمد",
        "in_english_characters": "",
        "in_latin_characters": "محمد",
        "in_arabic_characters": "محمد"
      },
      "surname": {
        "original": "",
        "in_english_characters": "",
        "in_latin_characters": "",
        "in_arabic_characters": ""
      }
    },
    "merge": {
      "version": 1,
      "fromIdentityIds": ["607418bc4e0a4a0012f55fd4"],
      "fromIdentityUpns": ["4850110730110"]
    }
  },
  "datacontenttype": "application/json",
  "time": "2025-12-23T10:43:37.010Z",
  "source": "pis-biographic-api"
}

ℹ️ Note
Fields such as auditSettings may exist in some producer implementations but are considered internal and non-contractual. Integrators MUST rely only on the merge instruction and the canonical snapshot fields documented above.

⚠️ Warning
Note how the UPNs field already contains the UPN of the discarded identity (referenced in merge.fromIdentityUpns). This is a crucial distinction as you must not update the snapshot before removing the other identity. This is because in case you have a DB uniqueness constraint on UPN, updating the snapshot before removing the other identity will cause a unique constraint error.
Therefore, it's is crucial to transactionally remove the discarded identity THEN update the current identity with the snapshot update.


6. Mandatory Processing Order (CRITICAL)

For every event, consumers MUST follow the steps below in the exact order.


Step 1 — Idempotency

Deduplicate events using the event identifier.

ℹ️ Note
Duplicate events may occur due to at-least-once delivery semantics.

Duplicate events MUST be ignored.


Step 2 — Check Merge Version FIRST

Before updating any identity snapshot:

if incoming merge.version > local merge_version:
    merge handling is required

🚨 CRITICAL
This check MUST occur before applying any snapshot update.
Skipping or reordering this step will result in inconsistent domain data.


Step 3 — Merge Resolution

If merge handling is required, consumers MUST choose one of the following paths.


Option A — Automatic Merge

Use this option if your domain rules allow automatic reconciliation.

Steps:

  • Reassign all domain records referencing fromIdentityIds
  • Deactivate or delete absorbed identities
  • Update the locally stored merge_version

⚠️ Warning
All steps above MUST be executed transactionally.


Option B — Manual Merge Review

Use this option if domain rules require human approval.

Steps:

  • Create a merge review case
  • Suspend identity snapshot updates
  • Apply merge only after human approval

If a new event is received:

  • If merge.version is greater than the stored version:
    • Discard the previously queued merge review
    • Restart the process using the new event
  • If equal or lower:
    • Ignore the event

🚨 CRITICAL
Identity snapshots MUST NOT be updated while a merge review is pending.


Step 4 — Snapshot Update

The identity snapshot MUST be applied:

  • After automatic merge completion, or
  • After manual merge approval

DO NOT
Apply snapshot updates before merge resolution.
This WILL cause data corruption and irrecoverable inconsistencies.


7. Design Guarantees

PIS guarantees that:

  • Each update contains the full canonical identity state
  • Merge instructions are complete and monotonic
  • Absorbed identities will never reappear as survivors
  • Event replay is safe
  • Consumers never need to reconstruct merge chains

8. Summary for Integrators

To integrate safely:

  1. Subscribe to identity update events
  2. Store identities by identity.id
  3. Reference identities by ID, not UPN
  4. Always check merge.version first
  5. Resolve merges before applying snapshots

Following this order is mandatory to ensure correctness, auditability, and long-term system integrity.