> For the complete documentation index, see [llms.txt](https://docs.oomus.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.oomus.org/api-reference/mpi.md).

# MPI

This section documents the Oomus CampaignID MPI (Master Patient Index) API endpoints.

**Base URL:** `https://api.oomus.health`\
**Authentication:** Required except `GET /mpi/verify/{token}` (public endpoint)

***

## POST /mpi/register

Registers a new beneficiary in the sovereign MPI registry.

**Request body:**

```json
{
  "first_name": "Aminata",
  "last_name": "Diallo",
  "date_of_birth": "1995-03-15",
  "gender": "F",
  "region_code": "DKR",
  "country_code": "SN",
  "phone_number": "+221771234567",
  "external_ids": {
    "dhis2_uid": "abcDEF123gh"
  }
}
```

| Field           | Type   | Required    | Description                                       |
| --------------- | ------ | ----------- | ------------------------------------------------- |
| `first_name`    | string | Yes         | First name                                        |
| `last_name`     | string | Yes         | Last name                                         |
| `date_of_birth` | date   | Recommended | ISO 8601 format (YYYY-MM-DD)                      |
| `gender`        | string | Recommended | `M`, `F`, or `U` (unknown)                        |
| `region_code`   | string | Yes         | 3-letter region code (e.g.: `DKR`, `THI`, `ZIG`)  |
| `country_code`  | string | Yes         | ISO alpha-2 country code (e.g.: `SN`, `CI`, `ML`) |
| `phone_number`  | string | No          | Number in E.164 format                            |
| `external_ids`  | object | No          | Identifiers in other systems                      |

**Response 201 Created:**

```json
{
  "mpi_id": "SN-DKR-26-9XQ7LM2A",
  "status": "created",
  "confidence": "new_identity",
  "created_at": "2026-05-15T09:00:00Z"
}
```

### 409 response — Duplicate detected

If the probabilistic engine detects a likely duplicate (score ≥ 0.95), registration is blocked and the existing MPI is returned:

```json
{
  "status": "duplicate_detected",
  "error": "A matching beneficiary already exists in the registry.",
  "existing_mpi_id": "SN-DKR-25-4HBNM7KL",
  "similarity_score": 0.97,
  "matched_fields": ["first_name", "last_name", "date_of_birth"],
  "action": "use_existing_or_review"
}
```

**Duplicate resolution flow:**

1. Use `existing_mpi_id` to link the new system to the existing identity
2. Or call `POST /mpi/merge` if you are sure it is the same person
3. Or call `POST /mpi/register` with `force_create: true` if you are sure it is a different person

***

## GET /mpi/search

Search the MPI registry.

**Query parameters:**

| Parameter       | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| `q`             | string  | Text search (last name, first name) |
| `mpi_id`        | string  | Search by exact MPI identifier      |
| `region_code`   | string  | Filter by region                    |
| `date_of_birth` | date    | Filter by date of birth             |
| `program`       | string  | Filter by associated program        |
| `limit`         | integer | Number of results (default: 20)     |
| `offset`        | integer | Offset for pagination               |

**Response 200 OK:**

```json
{
  "total": 3,
  "items": [
    {
      "mpi_id": "SN-DKR-26-9XQ7LM2A",
      "first_name": "Aminata",
      "last_name": "Diallo",
      "date_of_birth": "1995-03-15",
      "gender": "F",
      "region_code": "DKR",
      "programme_count": 2,
      "created_at": "2026-05-15T09:00:00Z"
    }
  ]
}
```

***

## GET /mpi/{mpi\_id}

Returns the full details of an MPI identity.

**Response 200 OK:**

```json
{
  "mpi_id": "SN-DKR-26-9XQ7LM2A",
  "first_name": "Aminata",
  "last_name": "Diallo",
  "date_of_birth": "1995-03-15",
  "gender": "F",
  "region_code": "DKR",
  "country_code": "SN",
  "phone_number": "+221771234567",
  "programmes": [
    {
      "programme_type": "vaccination",
      "linked_at": "2026-01-10T00:00:00Z"
    },
    {
      "programme_type": "nutrition",
      "linked_at": "2026-03-05T00:00:00Z"
    }
  ],
  "external_ids": {
    "dhis2_uid": "abcDEF123gh"
  },
  "status": "active",
  "created_at": "2026-05-15T09:00:00Z",
  "updated_at": "2026-05-15T09:00:00Z"
}
```

***

## PATCH /mpi/{mpi\_id}

Updates the attributes of an MPI identity.

**Request body (optional fields):**

```json
{
  "phone_number": "+221779876543",
  "region_code": "THI"
}
```

**Response 200 OK:** Updated MPI identity (same schema as GET /mpi/{mpi\_id})

***

## POST /mpi/match

Checks the match of a set of attributes against the MPI registry and returns the similarity score.

**Request body:**

```json
{
  "first_name": "Aminata",
  "last_name": "Dialo",
  "date_of_birth": "1995-03-15",
  "gender": "F",
  "region_code": "DKR"
}
```

**Response 200 OK:**

```json
{
  "matches": [
    {
      "mpi_id": "SN-DKR-26-9XQ7LM2A",
      "similarity_score": 0.94,
      "matched_fields": ["last_name_fuzzy", "date_of_birth", "gender", "region_code"],
      "confidence": "probable"
    }
  ]
}
```

***

## POST /mpi/{mpi\_id}/link-dhis2

Links a DHIS2 UID to an existing MPI identity.

**Request body:**

```json
{
  "dhis2_uid": "abcDEF123gh",
  "dhis2_instance_url": "https://dhis2.sante.gov.sn"
}
```

**Response 200 OK:**

```json
{
  "mpi_id": "SN-DKR-26-9XQ7LM2A",
  "dhis2_uid": "abcDEF123gh",
  "linked_at": "2026-05-15T10:00:00Z"
}
```

***

## GET /mpi/resolve-dhis2/{dhis2\_uid}

Resolves a DHIS2 UID to the corresponding MPI identity.

**Response 200 OK:**

```json
{
  "dhis2_uid": "abcDEF123gh",
  "mpi_id": "SN-DKR-26-9XQ7LM2A",
  "resolved_at": "2026-05-15T10:00:00Z"
}
```

**404 response:** DHIS2 UID not linked to an MPI.

***

## POST /mpi/merge

Merges two MPI identities into one (manual duplicate resolution).

**Request body:**

```json
{
  "source_mpi_id": "SN-DKR-26-8ZPLK9NQ",
  "target_mpi_id": "SN-DKR-26-9XQ7LM2A",
  "reason": "Confirmed duplicate — same person, two records",
  "keep_target": true
}
```

`target_mpi_id` becomes the canonical identity. `source_mpi_id` is deactivated and redirects to the target.

**Response 200 OK:**

```json
{
  "canonical_mpi_id": "SN-DKR-26-9XQ7LM2A",
  "merged_mpi_id": "SN-DKR-26-8ZPLK9NQ",
  "merged_at": "2026-05-15T10:05:00Z",
  "programmes_migrated": 1
}
```

***

## GET /mpi/{mpi\_id}/card

Returns the card data associated with an MPI identity.

**Response 200 OK:**

```json
{
  "mpi_id": "SN-DKR-26-9XQ7LM2A",
  "card_code": "DKR-VAC-9XQ7LM2A",
  "campaign_id": "camp_01HXYZ456DEF",
  "status": "valid",
  "issued_at": "2026-05-15T09:10:48Z"
}
```

***

## GET /mpi/verify/{token} *(public — without authentication)*

Verifies a card QR token. This endpoint is **public** and does not require any authentication token.

```bash
# Example — no Authorization header required
curl -X GET https://api.oomus.health/mpi/verify/a3f8c2e1d4b7f9e2a1c3...
```

**200 OK response (valid):**

```json
{
  "status": "valid",
  "programme_count": 2,
  "verified_at": "2026-05-15T10:30:00Z"
}
```

**200 OK response (revoked):**

```json
{
  "status": "revoked",
  "verified_at": "2026-05-15T10:30:00Z"
}
```

**404 response (unknown):**

```json
{
  "status": "not_found",
  "message": "This token does not match any known card."
}
```

> This endpoint does not return **ever** personal data (name, MPI ID, date of birth). It only confirms the cryptographic validity of the token.

***

## GET /mpi/qr-config

Returns the active QR configuration (style, size, position).

**Response 200 OK:**

```json
{
  "enabled": true,
  "position": "bottom-right",
  "size": "standard",
  "token_type": "opaque_sha256"
}
```

***

## Next steps

* [MPI sovereign identity](/features/mpi-sovereign-identity.md) — Functional documentation
* [HL7 FHIR R4](/integrations/fhir-r4.md) — Interoperability
* [Data Protection](/security/data-protection.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.oomus.org/api-reference/mpi.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
