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

# Vérifier un profil

> POST /v1/kyc/verify : la requête, les trois niveaux de vérifications, chaque id de vérification, et comment lire passed et flags.

`POST /v1/kyc/verify` renvoie le verdict pour un profil client et les documents qui l'accompagnent. Scope : `kyc:verify`. L'endpoint ne lit aucun fichier et ne coûte aucune lecture de document. `POST /v1/kyc/assess` prend le même corps, exécute ce même verdict, et ajoute une [évaluation du risque](/fr/guides/risk-assessment).

## Requête

Corps JSON. Tous les champs sont facultatifs, mais un corps vide ne vérifie rien.

| Champ | Type | Défaut | Signification |
| - | - | - | - |
| `reference` | string | aucun | Votre identifiant du client, de 1 à 64 caractères parmi `A-Z a-z 0-9 _ . : -`. Avec une référence, le verdict est classé sur le dossier et la réponse contient `case_id`. Une valeur invalide renvoie une 422. |
| `environment` | string | `sandbox` | `sandbox` ou `production`. |
| `subject` | string | aucun | Nom ou raison sociale du client, 255 caractères au maximum. |
| `values` | object | `{}` | Le profil du client : clés de champs et valeurs. Voir [values](#values). |
| `documents` | array | `[]` | Les entrées `documents[]` renvoyées par `/extract`, sans modification. |
| `kind` | string | aucun | `individual`, `corporation`, `partnership`, `charitable_org`, `trust`, `estate`. Alias : `entity`, `business`, `corporate` et `kyb` (corporation), `societe` (partnership), `charity` (charitable\_org), `fiducie` (trust), `succession` (estate). Toute autre valeur compte comme `individual`. |
| `entity` | boolean | `false` | Indicateur grossier utilisé quand `kind` est null. Vrai signifie une société. |
| `require_documents` | boolean | `true` | Demande la pièce d'identité. Voir [politique et options](#politique-et-options). |
| `screen` | boolean | `true` | Filtre chaque partie du dossier. Voir [filtrage](#filtrage). |
| `canadian_screening` | boolean ou null | null | Filtrage canadien supplémentaire pour un client canadien. Null laisse la politique de l'espace de travail décider. |
| `extra_checks` | array | `[]` | Vérifications que vous avez exécutées vous-même, ajoutées au verdict. Voir [vos propres vérifications](#vos-propres-vérifications). |
| `purpose` | string | `onboarding` | `onboarding` ou `periodic_review`. |

### `values`

`values` est un objet libre. Le moteur lit les clés ci-dessous et ignore les autres. Envoyez des chaînes. Les dates sont au format `YYYY-MM-DD`.

La vérification de complétude compte ces clés comme présentes lorsqu'elles ne sont pas vides.

| Type | Données requises |
| - | - |
| `individual` (26 clés, plus deux groupes au choix) | `first_name`, `last_name`, `date_of_birth`, `citizenship`, `id_type`, `id_number`, `id_expiry`, `street1`, `city`, `province`, `postal_code`, `country`, `phone`, `email`, `occupation`, `employer_name`, `annual_income`, `net_liquid_assets`, `total_net_worth`, `source_of_funds`, `objective`, `horizon`, `investment_knowledge`, `investment_experience`, `account_type`, `third_party`. Groupes au choix : `sin` ou `ssn` ; l'une des clés `pep_foreign`, `pep_domestic`, `pep_hio`, `pep`. |
| `corporation`, `partnership`, `charitable_org`, `estate` (21 clés) | `legal_name`, `business_number`, `incorporation_date`, `entity_address`, `entity_city`, `entity_province`, `entity_postal`, `industry`, `source_of_wealth`, `expected_activity`, `rp_first_name`, `rp_last_name`, `rp_id_type`, `rp_id_number`, `director_names`, `beneficial_owners`, `ownership_control_structure`, `bo_accuracy_measure`, `account_type`, `objective`, `horizon` |
| `trust` (17 clés) | `legal_name`, `entity_address`, `entity_city`, `entity_province`, `entity_postal`, `source_of_wealth`, `expected_activity`, `rp_first_name`, `rp_last_name`, `rp_id_type`, `rp_id_number`, `beneficiaries`, `ownership_control_structure`, `bo_accuracy_measure`, `account_type`, `objective`, `horizon` |

La liste requise vient d'un moteur d'abord conçu pour des dossiers nord-américains. Elle demande `province`, `postal_code` et un `sin` ou `ssn` : une personne marocaine atteint au mieux 27 sur 28 (96 %) et `sin/ssn` reste dans `missing`. À partir de 80 %, rien n'est signalé. Les exemples utilisent le pays `MA`, `id_type` `National ID` et un numéro de CIN comme `BK123456` ; `province` et `postal_code` acceptent n'importe quel texte pour une adresse marocaine, et le format postal canadien n'est vérifié que si `country` vaut `CA`.

Autres clés utilisées par les vérifications :

| Clés | Utilisées par |
| - | - |
| `sin`, `ssn`, `email`, `postal_code`, `province`, `date_of_birth` | Vérifications `format:` et `age:` |
| `id_expiry` | `expiry:recorded:id_expiry` et `expiry_soon:recorded:id_expiry` |
| `bank_number`, `bank_transit`, `bank_routing`, `bank_account` | Vérifications `bank:` et `format:bank_` |
| `other_names` | Noms supplémentaires à filtrer (anciens noms et noms de jeune fille) |
| `country`, `entity_country`, `incorporation_jurisdiction` | Règles par pays, consultation du registre, éligibilité eID |
| `ice`, `if_number`, `registration_number`, `tax_id`, `iban` | Vérifications de format des entités |
| `pep`, `pep_foreign`, `pep_domestic`, `pep_hio`, `third_party` | Vérifications de détermination et [risque](/fr/guides/risk-assessment) |
| `verified_in_person` | Une politique qui exige l'eID pour les clients non rencontrés en personne |
| `objective`, `horizon`, `investment_knowledge`, `investment_experience`, `uses_leverage`, `industry`, `high_risk_jurisdiction`, `citizenships` | [Évaluation du risque](/fr/guides/risk-assessment) |

## Réponse

```json theme={null}
{
  "passed": true,
  "checks": [
    { "id": "format:cin:national_id", "label": "national_id — CIN number is well-formed", "severity": "warning", "passed": true, "detail": "" },
    { "id": "screening", "label": "Sanctions screening — no matches; PEP not list-screened", "severity": "info", "passed": true, "detail": "screened against 23000 sanctions entries. The bundle carries no PEP list, so politically-exposed status rests on the client's declaration, not on a list check." },
    { "id": "completeness", "label": "KYC/KYB data completeness (61%)", "severity": "warning", "passed": false, "detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type" }
  ],
  "critical_failures": [],
  "flags": [
    { "id": "completeness", "label": "KYC/KYB data completeness (61%)", "severity": "warning", "passed": false, "detail": "missing 11 required data point(s): street1, city, province, postal_code, phone, email, source_of_funds, account_type" }
  ],
  "completeness": {
    "required": 28,
    "present": 17,
    "missing": ["street1", "city", "province", "postal_code", "phone", "email", "source_of_funds", "account_type", "third_party", "sin/ssn", "pep_foreign/pep_domestic/pep_hio/pep"],
    "percent": 61
  },
  "policy": { "id": null, "version": 0, "source": "legacy", "regime": "none", "regulator": null, "purpose": "onboarding", "overrides_refused": [] },
  "registry": null,
  "case_id": "00000000-0000-4000-8000-000000000001"
}
```

La liste `checks` ci-dessus est raccourcie à trois entrées ; une réponse complète en contient davantage. L'exemple est la sortie réelle du moteur pour des données fictives (une carte nationale d'identité marocaine et une fiche de paie pour `Test Client`).

| Clé | Signification |
| - | - |
| `passed` | `true` quand aucune vérification de sévérité `critical` n'a échoué. Les avertissements ne le modifient jamais. |
| `checks` | Chaque vérification exécutée, réussie ou non. |
| `critical_failures` | Les vérifications avec `passed: false` et une sévérité `critical`. Elles bloquent le dossier. |
| `flags` | Tout ce qui demande une personne : les vérifications critiques échouées et les avertissements échoués. Les vérifications `info` ne sont jamais des flags. |
| `completeness` | Les données `required`, le nombre de données `present`, les clés `missing` et le `percent`. |
| `policy` | La politique de l'espace de travail sous laquelle le verdict a été exécuté. Voir [politique](#politique-et-options). |
| `registry` | Ce que Corporations Canada indique pour une société fédérale (LCSA), normalisé. Null dans tous les autres cas. |
| `case_id` | Seulement avec une `reference`. |

Chaque vérification a cinq clés.

| Clé | Signification |
| - | - |
| `id` | Identifiant stable. Utilisez-le pour faire correspondre. Certains ids se terminent par un libellé de document (`expiry:national_id`) ou un nom de partie normalisé. |
| `label` | Une phrase destinée à une personne. |
| `severity` | `critical`, `warning` ou `info`. |
| `passed` | `true` ou `false`. |
| `detail` | La raison en cas d'échec. Vide en cas de réussite. |

Ne faites pas correspondre sur `label` : il peut changer. Faites correspondre sur `id`, et traitez la partie après le premier deux-points comme une variable.

## Comment lire le verdict

| Sévérité | `passed: false` signifie | Action suggérée |
| - | - | - |
| `critical` | Bloque. `passed` vaut `false` pour tout le dossier. | Arrêtez. Corrigez la cause ou envoyez à un réviseur. |
| `warning` | Un flag de conformité. Le dossier peut avancer. | Envoyez à une personne. Compte un point dans l'[évaluation du risque](/fr/guides/risk-assessment). |
| `info` | Conservé pour la piste d'audit. `passed` vaut généralement `true`. | Rien. |

Le dossier passe quand aucune vérification critique n'a échoué. Un dossier avec 30 avertissements passe quand même, donc regardez `flags` en plus de `passed`.

## Les trois niveaux

```mermaid theme={null}
flowchart TD
    D[documents[] entries] --> L1[Layer 1: per document]
    L1 --> L2[Layer 2: across documents and values]
    V[values] --> L2
    L2 --> L3[Layer 3: screening, determinations, completeness]
    P[Workspace policy] --> L3
    X[extra_checks] --> L3
    L3 --> R[passed, checks, flags, completeness]
```

1. Par document : les mêmes vérifications que `/extract` a déjà renvoyées pour chaque fichier (type, lisibilité, expiration, majorité, MRZ, ancienneté, provenance, spécimen).
2. Inter-documents et profil : le nom, la date de naissance et l'adresse concordent entre les documents et avec `values` ; les formats des numéros ; les coordonnées bancaires ; la pièce d'identité exigée figure parmi les fichiers envoyés.
3. Niveau dossier : filtrage des sanctions et des PEP, bénéficiaires effectifs pour les entités, vérifications de registre, déterminations propres à la politique, puis complétude.

La vérification est déterministe : la même entrée donne le même verdict, sauf pour le filtrage (qui dépend de la liste chargée) et la date, qui vient de l'horloge du serveur.

## Vérifications

Les ids sont listés avec la partie après le premier deux-points remplacée par `*`. « Document » désigne le libellé de l'étape ou l'indice `doc_type` (par exemple `passport`, ou `Government photo ID` quand un `step_key` est envoyé).

### Par document

| Id | Sévérité | Réussit quand | En cas d'échec |
| - | - | - | - |
| `doctype:*` | critical | Le `doc_type` du lecteur est accepté par l'étape. S'exécute seulement quand l'étape ou l'indice filtre. | Le détail nomme le document reçu et ce que l'étape accepte. Demandez le bon document. |
| `legible:*` | critical si tous les champs attendus manquent, sinon warning | Les champs clés du type ont été lus ([liste](/fr/guides/document-types)). | Le détail liste `could not read: ...`. Demandez un scan plus net. |
| `expiry:*` | critical | `id_expiry` est aujourd'hui ou plus tard. | `expired YYYY-MM-DD`. Demandez une pièce d'identité valide. |
| `expiry_soon:*` | warning | La pièce n'expire pas dans les 90 jours (politique `id_expiry_days`). | Échoue seulement dans ce cas. Pas un blocage. |
| `adult:*` | critical | Le titulaire d'une pièce d'identité a 18 ans ou plus. | `holder is N`. |
| `mrz:*` | critical | Les chiffres de contrôle de la MRZ sont valides (ICAO 9303, passeport 2 lignes de 44, carte d'identité 3 lignes de 30). | Falsification possible ou mauvaise lecture. |
| `mrz:unreadable:*` | warning | Ajouté seulement quand une MRZ de passeport a été lue mais n'a pas pu être analysée. | Les chiffres n'ont pas été vérifiés. |
| `mrz:dob:*`, `mrz:docnum:*` | warning | La date de naissance et le numéro de document de la MRZ correspondent aux champs imprimés. | La MRZ dit une chose, la carte une autre. |
| `recency:*` | critical sur une étape de justificatif de domicile, sinon warning | La plus ancienne des dates, imprimée ou du fichier, date de moins de 90 jours (politique `document_recency_days`). | `effective date X is N days old`. Seulement pour `utility_bill`, `proof_of_address`, `bank_statement`. |
| `recency:future:*` | critical | La date imprimée n'est pas dans le futur. | |
| `authenticity:*` | warning | La date du fichier n'est pas antérieure de plus de 14 jours à la date imprimée (politique `backdate_days`). | Modification ou antidatage possible. |
| `provenance:editor:*` | warning | Le fichier ne nomme pas un éditeur d'images ou de PDF (Photoshop, GIMP, Canva, Sejda, Smallpdf et similaires) comme logiciel. | Pas une preuve de fraude. Des gens masquent des informations dans leurs fichiers. Envoyez à un réviseur. |
| `provenance:revisions:*`, `provenance:modified:*`, `provenance:future:*` | warning | Émis une seule fois, non modifié après sa création, dates du fichier plausibles. | Idem. |
| `provenance:reprint:*` | info | Une impression depuis un navigateur ou un téléphone est notée et réussit. | |
| `authenticity:specimen:*` | critical | Le document n'est pas un spécimen, un échantillon ou un modèle. Déclenché par des mots comme SPECIMEN ou SAMPLE, un titulaire fictif (`John Doe`, `Customer`, `Specimen Test Card`), une adresse type (`123 Any St`), ou un numéro de spécimen (`P123456AA`, une suite d'un seul chiffre, `123456789`). | Utilisez un vrai document. |
| `format:cin:*`, `format:licence:*`, `consistency:licence:*`, `format:iban:*`, `format:national_id` | warning | Formats de numéros par pays. Voir [vérifications de format](/fr/guides/document-types). | Généralement une mauvaise lecture. |

### Inter-documents et profil

| Id | Sévérité | Réussit quand | En cas d'échec |
| - | - | - | - |
| `required:photo_id` | critical | Une pièce d'identité officielle avec photo et lisible figure parmi les documents (passeport, carte nationale d'identité, permis de conduire, carte de résident permanent, titre de séjour). Seulement quand `require_documents` est vrai. | `no readable government photo ID among the uploads`. |
| `required:incorporation`, `required:partnership_agreement`, `required:trust_deed`, `required:estate_authority` | critical | Le document qui établit une entité de ce type est présent. | Le détail nomme ce qui manque. |
| `consistency:name`, `consistency:name_unreadable` | critical | Chaque justificatif de domicile, relevé bancaire ou pièce d'entité appartient au demandeur ou à l'entité. Les noms de titulaires illisibles bloquent aussi. | La facture d'un tiers. |
| `consistency:poa_name_id`, `consistency:profile_name_id`, `consistency:id_name` | critical | Le justificatif de domicile est au nom figurant sur la pièce d'identité, le nom dans `values` est la personne de la pièce, deux pièces d'identité concernent la même personne. | |
| `consistency:dob` | critical | La date de naissance concorde entre les documents. | |
| `consistency:address`, `consistency:profile_address_docs`, `consistency:postal_province` | warning | L'adresse concorde entre les documents et avec `values` ; le code postal correspond à la province. | |
| `expiry:recorded:id_expiry` | critical | Le `id_expiry` de `values` n'est pas dépassé. | |
| `expiry_soon:recorded:id_expiry` | warning | Il n'expire pas dans les 90 jours. | |
| `format:sin` | critical | `sin` passe le contrôle de Luhn. | |
| `format:sin_series`, `format:sin_temporary` | warning | Un NAS ne commence pas par 0 ou 8, et un 9 est signalé comme série de résident temporaire. | |
| `format:ssn`, `format:email`, `format:postal` | warning | SSN, courriel et code postal canadien structurellement valides. | |
| `age:majority` | warning | Une personne de 18 ans est signalée dans une province où l'âge de la majorité est 19 ans. | |
| `bank:split` | warning | Les coordonnées bancaires sont dans les bons champs (un numéro de routage à 9 chiffres n'est pas dans `bank_number`). | |
| `format:bank_institution`, `format:bank_transit`, `format:bank_routing` | warning | Institution à 3 chiffres, transit à 5 chiffres, somme de contrôle ABA pour un routage à 9 chiffres. | |
| `consistency:bank_account` | warning | Un seul numéro de compte sur tous les relevés. | |

### Niveau dossier

| Id | Sévérité | Réussit quand | En cas d'échec |
| - | - | - | - |
| `screening` | info ou critical | Voir [filtrage](#filtrage). | |
| `screening:sanctions:*` | critical | La partie n'a aucune correspondance de sanctions. | `matches sanctions entry 'X' (source, N%) ... blocked pending manual review`. |
| `screening:pep:*` | warning | La partie n'a aucune correspondance PEP. | Diligence raisonnable renforcée. |
| `screening:review:*` | warning | Aucun antécédent défavorable ou réglementaire (ordonnance disciplinaire, ordonnance d'interdiction d'opérations, médias défavorables). | À examiner avant d'approuver. |
| `screening:canchek`, `screening:canchek_skipped`, `screening:canchek_unavailable` | info / info / warning | Le filtrage canadien a été exécuté / était souhaité mais l'espace de travail n'a pas de compte / le service n'a pas répondu. | Filtré seulement contre le jeu de listes. Filtrez de nouveau avant d'approuver. |
| `completeness` | warning | Au moins 80 % des données requises sont présentes. | Le détail liste les 8 premières clés manquantes. |
| `bo:none_recorded`, `bo:names_only`, `bo:addresses`, `bo:senior_officer`, `bo:unconfirmed_risk` | warning | Les bénéficiaires effectifs sont enregistrés comme des personnes avec adresses, un dirigeant principal est nommé, et la propriété est confirmée. Entités seulement. | |
| `discrepancy:*` | warning ou info | Sociétés fédérales : les bénéficiaires effectifs concordent avec Corporations Canada, et un écart a été signalé. | |
| `registry:found`, `registry:active`, `registry:directors` | warning, critical, info ou warning | Une société fédérale est trouvée, active, et ses administrateurs concordent avec le registre. Seulement pour les sociétés LCSA quand la politique active la consultation. | |
| `registry:*`, `registry:manual:*` | warning | Autres juridictions : nomme le registre qu'un réviseur doit consulter. | |
| `format:ice`, `format:if_number`, `format:rc`, `required:ma_identifiers`, `format:business_number`, `format:ein`, `format:registration_number`, `format:tax_id`, `required:*_identifiers` | warning | Les identifiants de société sont bien formés et enregistrés. | |
| `determination:pep_hio`, `determination:third_party` | warning | La politique demande que le dossier enregistre ces réponses et elles sont présentes. | |
| `policy:eid_non_face_to_face` | critical | Voir [eID](/fr/guides/eid). | |
| `document:*` | warning ou critical | La politique impose des emplacements de documents et l'emplacement est rempli. | |
| `policy:periodic_review`, `policy:periodic_review_unanchored`, `policy:override_refused:*`, `policy:met_in_person_declared` | info / warning / info / info | Voir [politique et options](#politique-et-options). | |
| `partner:*` | tel que vous l'avez envoyé | Vos propres vérifications, voir ci-dessous. | |

## Filtrage

Chaque partie du dossier est filtrée par défaut (`screen: true`).

| Dossier | Parties filtrées |
| - | - |
| Individu | Le titulaire (prénom, deuxième prénom, nom) et chaque nom de `other_names`. |
| Entité | `legal_name`, le dirigeant signataire (`rp_*`), chaque nom de `director_names` et `beneficial_owners`, et `other_names`. Les doublons sont supprimés. |

Une correspondance de sanctions est critique et bloque. Une correspondance PEP est un avertissement. Un résultat propre produit une seule vérification `screening` qui indique contre quoi la partie a été filtrée :

| Vérification `screening` | Sévérité | Signification |
| - | - | - |
| `Sanctions screening — no matches; PEP not list-screened` | info, réussie | Filtré contre le jeu de listes de sanctions (OFAC, liste consolidée de l'ONU et BSIF). Ce jeu n'a pas de liste PEP, donc le statut PEP repose sur la déclaration du client. |
| `Sanctions/PEP screening — no matches` | info, réussie | Filtré contre une source qui inclut des tables PEP (le filtrage canadien). |
| `Sanctions/PEP screening — sample list only` | warning | L'environnement n'a qu'une liste d'exemple de 30 noms. Ce n'est pas un filtrage conforme. Vous ne devriez pas voir ceci en production. |
| `Sanctions/PEP screening — NOT PERFORMED` | critical | Aucune liste n'était chargée. |
| `Sanctions/PEP screening — coverage unknown` | critical | La liste utilisée n'a pas pu être déterminée. Considérez la partie comme non filtrée. |

Avec `canadian_screening` à true (ou si la politique le demande) et un client canadien (`country` vaut `CA`, `CAN` ou `Canada`), les parties sur lesquelles le jeu de listes n'a rien trouvé sont aussi filtrées par les tables canadiennes LBA et PEP du fournisseur eID, quand l'espace de travail a un compte. La vérification `screening:canchek` indique combien de parties ont été filtrées.

## Politique et options

Chaque appel s'exécute sous la politique KYC de votre espace de travail pour le type de client (`kyc` pour une personne, `kyb` pour toute entité) et l'environnement. Le champ `policy` de la réponse indique laquelle.

| `policy.source` | Signification |
| - | - |
| `tenant` | Une politique enregistrée dans la console (Settings, KYC policy), à la `version` indiquée. |
| `preset` | Aucune politique enregistrée. Le préréglage du régime réglementaire de votre espace de travail (FINTRAC pour le Canada, BSA/CIP pour les États-Unis, loi 43-05 pour le Maroc). |
| `legacy` | Aucune politique enregistrée, aucun régime : le défaut léger. Rien n'est verrouillé. |
| `fallback` | Une politique enregistrée qui ne se valide plus. L'appel s'est exécuté sous le préréglage ou le défaut à la place. |

Une option de requête peut ajouter des vérifications ou être plus stricte. Elle ne peut pas désactiver un élément verrouillé par la politique. Une option refusée n'est pas une erreur : l'appel s'exécute avec la règle plus stricte et le refus est consigné.

```json theme={null}
"policy": {
  "source": "preset",
  "regime": "fintrac",
  "purpose": "onboarding",
  "overrides_refused": [
    { "field": "screen", "requested": false, "enforced": true, "locked_item": "sanctions_screening" }
  ]
}
```

(Exemple illustratif : la forme de `overrides_refused` est réelle, les valeurs sont un exemple.) Un refus ajoute aussi une vérification info `policy:override_refused:screen`.

| Option | Respectée quand |
| - | - |
| `require_documents: false` | La politique ne verrouille pas `id_verification`, ou `purpose` vaut `periodic_review`. |
| `screen: false` | La politique ne verrouille pas `sanctions_screening`. |
| `canadian_screening: false` | La politique ne verrouille pas le filtrage canadien. |

Ce qu'une politique peut modifier :

| Paramètre | Défaut | Effet |
| - | - | - |
| `thresholds.document_recency_days` | 90 | La fenêtre du justificatif de domicile (1 à 365). |
| `thresholds.backdate_days` | 14 | Écart entre la date du fichier et la date imprimée qui est signalé. |
| `thresholds.id_expiry_days` | 90 | Fenêtre de `expiry_soon` (0 à 365). |
| `risk_bands.low_max_points`, `medium_max_points` | 1 et 3 | Plus strict seulement. Voir [évaluation du risque](/fr/guides/risk-assessment#risque-de-conformité). |
| `beneficial_ownership_threshold_pct` | 25 | Pourcentage de propriété qui doit être nommé. Jusqu'à 25. |
| `enabled_checks` | toutes les familles | Familles qui apparaissent dans le verdict. Vos `extra_checks` et les résultats eID ne sont jamais filtrés. |
| `document_slot_enforcement` | `off` | `warning` ou `critical` ajoute des vérifications `document:*` pour les emplacements requis. |
| `eid_required_non_face_to_face` | false | Une personne non rencontrée en personne doit avoir une vérification eID réussie. |

Les valeurs de politique se modifient dans la console, pas par l'API.

### Révision périodique

`purpose: "periodic_review"` est destiné à un client déjà intégré. Il ne revérifie pas l'identité (PCMLTFR s.155(1)) : les pièces d'identité, l'exigence eID et les vérifications d'emplacements ne sont pas appliquées. Le filtrage, les déterminations et tous les autres verrous s'exécutent quand même.

* Avec une intégration réussie au dossier chez Sahl pour la même `reference` et le même `environment`, la révision ajoute une vérification info `policy:periodic_review`.
* Sans intégration, ou sans `reference`, la révision est respectée mais ajoute un avertissement `policy:periodic_review_unanchored` : l'identité a été ignorée sur votre seule parole.

## Vos propres vérifications

`extra_checks` vous permet d'intégrer au verdict une vérification que vous avez exécutée vous-même, comme un client en double ou une liste de blocage dans votre base, afin qu'elle puisse le bloquer.

```json theme={null}
"extra_checks": [
  { "id": "internal:duplicate_client", "label": "No duplicate client in our database", "severity": "critical", "passed": false, "detail": "matches client 8812" }
]
```

Chacune exige `id`, `label`, `severity` (`critical`, `warning` ou `info`) et `passed` ; `detail` est facultatif. Un id qui commence par `eid:` ou `policy:` est réservé à Sahl : il revient sous la forme `partner:eid:...` ou `partner:policy:...`, affiché et capable de bloquer, mais il ne satisfait jamais l'exigence eID de la politique.

## Registre Corporations Canada

Pour une `corporation` que le conseiller indique comme constituée au fédéral (LCSA), et quand la politique l'active (activé par défaut), Sahl recherche la société. `registry` contient alors l'enregistrement normalisé, pour que vous puissiez pré-remplir à partir de lui, et les vérifications `registry:` le comparent à vos données. Dans tous les autres cas, `registry` est null.

## Classement

Avec une `reference`, le verdict est classé sur le dossier pour (espace de travail, environnement, référence). Les documents dont le `document_id` vient de `/extract` y sont liés. Un statut défini par une personne (`approved`, `refused`) n'est jamais annulé par un nouveau verdict. Le [webhook](/fr/guides/webhooks) `kyc.case_verified` se déclenche après la validation.

## Exemples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.sahlfinancial.com/api/v1/kyc/verify \
    -H "Authorization: Bearer $SAHL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "reference": "client-0001",
      "environment": "sandbox",
      "subject": "Test Client",
      "kind": "individual",
      "values": {
        "first_name": "Test", "last_name": "Client", "date_of_birth": "1988-04-12",
        "citizenship": "MA", "country": "MA",
        "id_type": "National ID", "id_number": "BK123456", "id_expiry": "2030-05-01"
      },
      "documents": [{
        "filename": "cin-test.jpg", "doc_type": "national_id", "step_hint": "national_id",
        "step_key": null, "mapped": 9, "notes": [],
        "fields": {
          "first_name": "Test", "last_name": "Client", "date_of_birth": "1988-04-12",
          "id_type": "National ID", "id_number": "BK123456", "id_expiry": "2030-05-01",
          "citizenship": "MA", "id_country": "MA", "document_holder_name": "Test Client"
        }
      }]
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://app.sahlfinancial.com/api/v1/kyc/verify", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SAHL_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      reference: "client-0001",
      environment: "sandbox",
      subject: "Test Client",
      kind: "individual",
      values: { first_name: "Test", last_name: "Client", date_of_birth: "1988-04-12" },
      documents: extracted.documents, // from /extract, unchanged
    }),
  });
  const verdict = await res.json();
  if (!verdict.passed) {
    for (const c of verdict.critical_failures) console.log(c.id, c.detail);
  }
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://app.sahlfinancial.com/api/v1/kyc/verify",
      headers={"Authorization": f"Bearer {os.environ['SAHL_API_KEY']}"},
      json={
          "reference": "client-0001",
          "environment": "sandbox",
          "subject": "Test Client",
          "kind": "individual",
          "values": {"first_name": "Test", "last_name": "Client", "date_of_birth": "1988-04-12"},
          "documents": extracted["documents"],  # from /extract, unchanged
      },
      timeout=60,
  )
  res.raise_for_status()
  verdict = res.json()
  for c in verdict["critical_failures"]:
      print(c["id"], c["detail"])
  ```
</CodeGroup>

### Un dossier bloqué

Une carte nationale expirée donne `passed: false` et deux échecs critiques, un du document et un du profil :

```json theme={null}
{
  "passed": false,
  "critical_failures": [
    { "id": "expiry:national_id", "label": "national_id — not expired", "severity": "critical", "passed": false, "detail": "expired 2024-01-01" },
    { "id": "expiry:recorded:id_expiry", "label": "The identity document on file is not expired", "severity": "critical", "passed": false, "detail": "expired 2024-01-01" }
  ]
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.