> ## Documentation Index
> Fetch the complete documentation index at: https://verifner.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Verdict et score

> Comment VerifNer passe de cinq contrôles à un verdict.

Chaque vérification produit **cinq contrôles**, un **score** entre 0 et 1, et un **verdict** déduit du score.

| Verdict | Score | Ce que vous faites |
| - | - | - |
| `verified` | 0,90 et plus | Poursuivre le parcours |
| `review` | de 0,60 à 0,89 | Faire regarder par un humain |
| `rejected` | moins de 0,60 | Refuser, ou demander un autre document |

## Les trois verdicts en détail

<AccordionGroup>
  <Accordion title="verified : identité vérifiée" icon="circle-check">
    **Valeur** : `"verified"`, score de 0,90 ou plus.

    Aucun contrôle n'a échoué et l'ensemble est solide. Vous pouvez poursuivre le parcours (ouverture de compte, prêt, retrait) sans intervention humaine.

    **Définitif** : oui.
  </Accordion>

  <Accordion title="review : à examiner" icon="user-magnifying-glass">
    **Valeur** : `"review"`, score de 0,60 à 0,89.

    Un doute sérieux mais pas de fraude évidente : un contrôle en échec (qui plafonne le score sous 0,90), un visage moyennement ressemblant, une carte sans MRZ, des champs illisibles. La vérification apparaît dans la **File de revue** de la console.

    **Ce que vous faites** : mettez le dossier en attente. Un relecteur tranche, et un second webhook vous apporte `final_verdict`.
  </Accordion>

  <Accordion title="rejected : refusée" icon="circle-xmark">
    **Valeur** : `"rejected"`, score sous 0,60.

    Un échec grave : MRZ falsifiée, nom ou date de naissance qui divergent, document expiré, visage différent. Refusez, ou proposez à la personne de recommencer avec un autre document.

    **Définitif** : oui. Si la photo était simplement ratée, faites recommencer la vérification.
  </Accordion>
</AccordionGroup>

```mermaid theme={null}
flowchart LR
  S[Score] -->|"≥ 0,90"| V[verified]
  S -->|"0,60 à 0,89"| R[review]
  S -->|"< 0,60"| X[rejected]
  R -->|relecteur, une seule fois| F[final_verdict]
```

## Traiter le verdict

Décidez toujours sur `final_verdict` quand il existe, sinon sur `verdict` :

```javascript theme={null}
function decide(v) {
  const verdict = v.final_verdict ?? v.verdict;
  switch (verdict) {
    case 'verified':
      return approve(v.id);
    case 'review':
      return hold(v.id); // un second webhook apportera final_verdict
    case 'rejected':
      return decline(v.id, v.checks.filter((c) => c.status === 'fail').map((c) => c.evidence.fr));
  }
}
```

Les valeurs sont en minuscules, sans espace. Le champ `status` (`VERIFIED`, `REVIEW`, `REJECTED`) répète `verdict` en majuscules pour compatibilité : préférez `verdict`.

## Comment le score est calculé

Chaque contrôle donne un score entre 0 et 1, pondéré ainsi :

| Contrôle | Poids |
| - | - |
| `face_match` | 35 % |
| `mrz_checksum` | 20 % |
| `viz_mrz_consistency` | 20 % |
| `tamper` | 15 % |
| `expiry` | 10 % |

Un contrôle **ignoré** (`skipped`), par exemple la comparaison faciale quand vous n'envoyez pas de selfie, ne coûte rien : les poids des autres contrôles sont redistribués.

Deux règles passent avant la moyenne :

* **Un contrôle en échec plafonne le score sous 0,90.** Un document dont un seul contrôle échoue ne peut jamais être `verified` : au mieux, il part en revue.
* **Un échec grave plafonne le score à 0,50 au plus.** Chiffre de contrôle MRZ faux, nom ou date de naissance différents entre la zone imprimée et la MRZ, date d'expiration illisible, portrait introuvable : score plafonné à 0,50. Document expiré ou visage nettement différent (similarité sous 0,30) : score ramené à 0. Dans tous ces cas, le verdict est `rejected`, quel que soit le reste.

Un document sans MRZ est plafonné à 0,85, donc envoyé en revue. Seule exception : la carte d'identité papier du Niger, qui peut être `verified` quand le visage concorde nettement, qu'elle n'est pas expirée, sans signe d'altération et bien lue. Voir [Documents](/concepts/documents).

<Note>
  Les seuils et les poids seront ajustés sur notre jeu d'évaluation de documents réels. Le principe, lui, ne changera pas : un échec grave ne peut jamais être compensé par les autres contrôles.
</Note>

## La réponse

```json theme={null}
{
  "id": "vrf_w6e35w8a9iehsf6shzuw",
  "status": "VERIFIED",
  "verdict": "verified",
  "score": 1,
  "document_type": "passport",
  "document": {
    "type": "passport",
    "country": "NER",
    "fields": {
      "surname": "Eriksson",
      "given_names": "Anna Maria",
      "date_of_birth": "1974-08-12",
      "sex": "F",
      "nationality": "NER",
      "place_of_birth": "Zinder",
      "document_number": "L898902C3",
      "date_of_issue": null,
      "date_of_expiry": "2031-04-15",
      "issuing_authority": null
    },
    "mrz": {
      "lines": [
        "P<NERERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<",
        "L898902C36NER7408122F3104150ZE184226B<<<<<16"
      ],
      "valid": true
    },
    "legibility": 0.97
  },
  "face_match": { "similarity": 0.82, "matched": true, "faces_in_document": 1, "faces_in_selfie": 1 },
  "checks": [ "..." ],
  "timings": { "prep": 101, "extract": 4820, "rules": 3 },
  "latency_ms": 5840,
  "created_at": "2026-09-26T10:00:00.000Z"
}
```

| Champ | Description |
| - | - |
| `id` | Identifiant `vrf_…`, à conserver avec votre dossier client |
| `verdict` | `verified`, `review` ou `rejected` |
| `status` | Le même verdict en majuscules, pour compatibilité |
| `score` | Entre 0 et 1, arrondi au millième |
| `document_type` | `passport`, `cni` ou `unknown` |
| `document.fields` | Les champs lus sur la zone imprimée. Dates au format `AAAA-MM-JJ`, `null` quand un champ est absent ou illisible |
| `document.mrz` | Les lignes de la MRZ telles que lues, et `valid` quand tous les chiffres de contrôle passent |
| `document.legibility` | Confiance de lecture, de 0 à 1 |
| `face_match` | Similarité entre le portrait du document et le selfie, `null` sans selfie |
| `checks` | Les cinq contrôles. Voir [Contrôles](/concepts/checks) |
| `latency_ms` | Durée totale du traitement |

## Revue humaine

Une vérification en `review` apparaît dans la console. Un membre avec le rôle **relecteur**, **admin** ou **propriétaire** l'examine, voit les photos et les contrôles, et tranche. La décision est enregistrée dans `final_verdict`, qui apparaît :

* dans `GET /v1/verifications/{id}` ;
* dans un second webhook `verification.completed`, avec `final_verdict` renseigné.

Le `verdict` d'origine n'est jamais modifié : vous gardez la trace de ce que le système avait décidé et de ce que l'humain a tranché.
