> 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/features/verification.md).

# Verification portal

The Oomus CampaignID verification portal allows any health worker to verify the authenticity of a card, **without an Internet connection**, in any field context.

***

## Fundamental principle: Offline-first

The portal design is radically different from traditional verification systems that require a server call with every scan. Oomus CampaignID uses an **offline-first** :

1. The portal is a **static artifact** (HTML + JavaScript + JSON) generated at the end of each generation job
2. It is downloaded **only once** by the health worker (or distributed on a USB stick)
3. All verifications are performed **locally in the browser**, with no data transmitted to the server
4. The portal works on any device with a browser (smartphone, tablet, computer)

***

## What is verified (and what is not)

### What the portal verifies

| Information            | Method                               |
| ---------------------- | ------------------------------------ |
| Card code authenticity | SHA-256 lookup in the local registry |
| Campaign membership    | Prefix and registry verification     |
| Card status            | `valid` / `revoked` / `not_found`    |
| Issue date             | Registry content                     |

### What the portal does NOT transmit

* No beneficiary personal data is transmitted to the server
* No verification log is sent (worker confidentiality)
* No network connection is established during verification

***

## Verification modes

### 1. Manual code entry

The worker manually enters the code printed on the card (format: `DKR-VAC-9XQ7LM2A`). The portal performs an immediate lookup in the local registry.

### 2. Scan QR code

The worker points their smartphone camera at the card's QR code. The portal uses the browser's WebRTC API to decode the QR and performs the cryptographic verification.

**QR verification flow:**

```
Scan QR code
     │
     ▼
Decode the opaque token
     │
     ▼
Lookup in registry.json (SHA-256)
     │
     ├─ Found + valid → ✓ Authentic card
     │
     ├─ Found + revoked → ✗ Revoked card
     │
     └─ Not found → ✗ Unknown / forged card
```

### 3. Bulk verification — CSV

For field operations involving many cards to verify (census, distribution), the worker can import a CSV file containing the card codes. The portal processes the entire list in a few seconds and generates a verification report.

Accepted CSV format:

```csv
code
DKR-VAC-9XQ7LM2A
DKR-VAC-3KPQ8NX1
DKR-VAC-7FZM2TYB
```

***

## Portal structure (artifacts)

At the end of each successful generation job, the portal contains:

```
verification-portal/
├── index.html          # Verification interface (compiled React)
├── registry.json       # Code registry (SHA-256 hashed, non-PII)
├── manifest.json       # Campaign metadata
└── assets/
    ├── app.js          # WebCrypto verification logic
    └── styles.css      # User interface
```

### Structure of registry.json

```json
{
  "campaign": "DKR-VAC",
  "generated_at": "2026-05-15T09:10:48Z",
  "total_cards": 1000,
  "entries": {
    "a3f8c2e1d4b7...": {
      "status": "valid",
      "issued_at": "2026-05-15"
    },
    "9b2e4a7f1c8d...": {
      "status": "valid",
      "issued_at": "2026-05-15"
    }
  }
}
```

> The registry keys are **SHA-256 hashes** of QR tokens — they contain no personal information about the beneficiary.

***

## Cryptographic verification (WebCrypto)

Verification is performed via the browser's**WebCrypto API** — available in any modern browser without a plugin or app:

```javascript
// Illustrative excerpt — executed in the browser
const tokenHash = await crypto.subtle.digest(
  "SHA-256",
  new TextEncoder().encode(scannedToken)
);
const hashHex = toHexString(tokenHash);
const result = registry.entries[hashHex];
// result.status === "valid" → authentic card
```

**WebCrypto advantages:**

* Built into all modern browsers (Chrome, Firefox, Safari, Edge)
* No data leaves the device
* Tamper-resistant (executed in the secure browser context)

***

## Multilingual support

The verification portal is available in three languages:

| Language | Code | Availability          |
| -------- | ---- | --------------------- |
| French   | `fr` | All campaigns         |
| English  | `en` | All campaigns         |
| Wolof    | `wo` | West Africa campaigns |

The language can be selected in the portal interface. The default language corresponds to the one configured when the campaign is created.

***

## Public MPI endpoint (no PII)

For online verifications, a public endpoint makes it possible to verify a QR token without exposing personal data:

```bash
# Public verification — no auth token required
curl -X GET https://api.oomus.health/mpi/verify/TOKEN_QR_HERE
```

**Response:**

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

The response confirms only:

* Token validity (`valid` / `invalid` / `revoked`)
* Number of programs associated with this beneficiary (without naming the programs)
* Verification timestamp

**No personal data (name, date of birth, MPI ID) is ever returned by this endpoint.**

***

## Security model

### Cryptographic chain

Each verification portal is linked to the generation audit trail:

```
Card generation → SHA-256 hash of the code → registry.json entry
                 → SHA-256 hash of the registry → Stored in audit_log
```

### Anti-forgery evidence

* The `registry.json` is signed at generation — any post-generation modification invalidates verification
* The SHA-256 hash chain links the registry to the server's immutable audit trail
* Any attempt to modify the registry can be detected

### Secure portal distribution

It is recommended to distribute verification portals via:

* Direct download from the Oomus interface (signed link, limited duration)
* Organization's internal HTTPS web server
* USB stick for areas without Internet access

***

## Next steps

* [Cryptographic guarantees](/security/cryptographic-guarantees.md) — Technical security details
* [Offline verification](/security/offline-verification.md) — Field deployment guide
* [Sovereign MPI identity](/features/mpi-sovereign-identity.md) — MPI and QR tokens


---

# 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/features/verification.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.
