ORI Verify API
Infrastructure de conformité KYC/KYB/AML/TM pour les institutions financières africaines. Intégrez la vérification d'identité, le screening sanctions et la surveillance des transactions en quelques heures.
https://verify.ori-advisory.com/api/v1Démarrage rapide (5 min)
Le modèle d'intégration est identique pour tous les modules : vous appelez notre API depuis votre backend, votre utilisateur complète le parcours sur notre interface hébergée, puis nous vous notifions par webhook. Aucune donnée biométrique ne transite par vos serveurs.
kyc.completedsk_test_ en sandbox.curl -X POST https://verify.ori-advisory.com/api/v1/kyc/create \
-H "Authorization: Bearer sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{ "external_user_id": "user_42" }'{
"id": "kyc_clx1a2b3c4",
"status": "PENDING",
"url": "https://verify.ori-advisory.com/verify/eyJ...",
"expires_at": "2026-06-10T15:00:00Z"
}urlGET /kyc/{id}.POST https://votre-app.com/webhooks/ori-verify
{ "event": "kyc.completed", "session_id": "kyc_clx1a2b3c4", "status": "APPROVED" }sk_test_ ne consomment aucun crédit et n'émettent pas de webhooks facturés. Utilisez-les pour intégrer et tester le parcours de bout en bout avant de passer en sk_live_.Authentification
Toutes les requêtes doivent inclure votre clé API dans le header Authorization. Vos clés sont préfixées sk_live_ (production) ou sk_test_ (sandbox).
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxEnvironnements
| Paramètre | Type | Requis | Description |
|---|---|---|---|
sk_live_... | string | non | Production — transactions réelles, webhooks actifs |
sk_test_... | string | non | Sandbox — aucune donnée réelle, réponses simulées |
Exemple cURL
curl https://verify.ori-advisory.com/api/v1/kyc/create \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"external_user_id": "user_123"}'Erreurs & Codes HTTP
L'API utilise les codes HTTP standard. Les erreurs retournent toujours un objet JSON avec un champ error.
{
"error": "Validation error",
"details": {
"fieldErrors": { "external_user_id": ["Required"] }
}
}| Paramètre | Type | Requis | Description |
|---|---|---|---|
200 | OK | non | Requête traitée avec succès |
201 | Created | non | Ressource créée |
204 | No Content | non | Suppression réussie |
400 | Bad Request | non | Paramètres invalides — voir details |
401 | Unauthorized | non | Clé API manquante ou invalide |
403 | Forbidden | non | Accès refusé à cette ressource |
404 | Not Found | non | Ressource introuvable |
409 | Conflict | non | Ressource déjà existante (external_id dupliqué) |
429 | Rate Limited | non | Trop de requêtes — réessayez dans 60s |
502 | Bad Gateway | non | Erreur ml-service (OCR, liveness) |
503 | Unavailable | non | Service temporairement indisponible |
KYC — Créer une session
Crée une session de vérification KYC et retourne une URL à envoyer à votre utilisateur. Le lien est valide 1 heure.
/api/v1/kyc/createCorps de la requête
| Paramètre | Type | Requis | Description |
|---|---|---|---|
external_user_id | string | oui | Votre identifiant interne pour cet utilisateur |
redirect_url | string | non | URL de retour après completion (optionnel) |
Requête
{
"external_user_id": "user_123",
}Réponse 201
{
"id": "clx1a2b3c4d5e6f7g8h9",
"status": "PENDING",
"token": "eyJhbGciOiJIUzI1NiJ9...",
"url": "https://verify.ori-advisory.com/verify/eyJhbG...",
"expires_at": "2026-06-10T15:00:00.000Z"
}KYC — Consulter une session
/api/v1/kyc/{id}Requête
curl /api/v1/kyc/clx1a2b3c4d5e6f7g8h9 \
-H "Authorization: Bearer sk_live_xxx"Réponse 200
{
"id": "clx1a2b3c4d5e6f7g8h9",
"status": "APPROVED",
"external_user_id": "user_123",
"first_name": "Mamadou",
"last_name": "Keita",
"date_of_birth": "1990-03-15",
"nationality": "MLI",
"document_type": "NATIONAL_ID",
"document_number": "MLI0001234567",
"scores": {
"liveness": 0.82,
"ocr": 0.91,
"face_match": 0.87
},
"aml_status": "CLEAR",
"risk_level": "LOW",
"completed_at": "2026-06-10T14:23:11.000Z",
"created_at": "2026-06-10T14:10:00.000Z"
}Statuts possibles
| Paramètre | Type | Requis | Description |
|---|---|---|---|
PENDING | status | non | Session créée, l'utilisateur n'a pas encore commencé |
PROCESSING | status | non | L'utilisateur a soumis ses données, traitement en cours |
APPROVED | status | non | Vérification réussie — tous les seuils atteints |
REVIEW | status | non | Vérification soumise mais nécessite une revue manuelle |
REJECTED | status | non | Vérification rejetée — fraude suspectée ou seuils non atteints |
KYC — Uploader des documents (API directe)
Alternative au flow end-user : uploadez les documents directement depuis votre backend. Utilisé quand vous avez déjà capturé les documents côté client.
/api/v1/kyc/{id}/documentscurl -X POST /api/v1/kyc/clx1a2b3c4.../documents \
-H "Authorization: Bearer sk_live_xxx" \
-F "file=@id_front.jpg" \
-F "side=front" \
-F "document_type=NATIONAL_ID"| Paramètre | Type | Requis | Description |
|---|---|---|---|
file | file | oui | Image JPEG, PNG, WEBP — max 10 Mo |
side | enum | oui | front | back | selfie | liveness |
document_type | enum | non | NATIONAL_ID | PASSPORT | DRIVERS_LICENSE | RESIDENCE_PERMIT |
KYC — Flow end-user (lien de vérification)
C'est le mode principal : vous branchez ORI Verify dans le parcours d'onboarding de votre application (comme les néobanques avec leur prestataire KYC). Votre backend crée la session, votre app redirige l'utilisateur (WebView mobile, redirect web) vers l'URL retournée — capture caméra en direct, cadrage guidé, contrôle de présence — puis vous recevez le résultat par webhook. Pour les clients non digitaux, vos agents disposent du mode guichet dans la console (Dashboard → KYC → « Vérification au guichet ») : documents seuls, contrôle visuel par l'agent.
urlkyc.completedStatut APPROVED ou REVIEW selon les scoresSeuils de décision automatique
| Paramètre | Type | Requis | Description |
|---|---|---|---|
liveness_score | float | non | ≥ 0.55 requis pour auto-approve (MediaPipe 3D, anti-spoofing) |
ocr_score | float | non | ≥ 0.40 requis — confiance de lecture du document |
face_match | float | non | ≥ 0.50 requis — correspondance selfie ↔ document |
KYB — Créer un dossier
Ouvre un dossier de vérification pour une personne morale (entreprise, ONG, etc.).
/api/v1/kyb/createRequête
{
"company_name": "Société Générale CI",
"registration_no": "CI-ABJ-2018-B-00123",
"legal_form": "SA",
"country": "CI",
"industry": "banking",
"website": "https://societegenerale.ci",
"ubos": [
{
"first_name": "Kofi",
"last_name": "Asante",
"date_of_birth": "1975-04-22",
"nationality": "GHA",
"ownership": 35.0,
"role": "CEO"
}
]
}Réponse 201
{
"id": "kyb_clx9z8y7x6w5v4u3t",
"status": "PENDING",
"company_name": "Société Générale CI",
"country": "CI",
"ubos": [
{
"id": "ubo_clx...",
"first_name": "Kofi",
"last_name": "Asante",
"ownership": 35.0
}
],
"created_at": "2026-06-10T14:00:00.000Z"
}KYB — Consulter un dossier
/api/v1/kyb/{id}{
"id": "kyb_clx9z8y7x6w5v4u3t",
"status": "APPROVED",
"company_name": "Société Générale CI",
"registration_no": "CI-ABJ-2018-B-00123",
"country": "CI",
"aml_status": "CLEAR",
"risk_score": 38,
"risk_level": "MEDIUM",
"ubos": [ ... ],
"documents": [
{ "type": "KBIS", "file_name": "kbis_2026.pdf" },
{ "type": "STATUTS", "file_name": "statuts.pdf" }
],
"completed_at": "2026-06-10T16:00:00.000Z"
}KYB — Mettre à jour un dossier
/api/v1/kyb/{id}| Paramètre | Type | Requis | Description |
|---|---|---|---|
status | enum | non | APPROVED | REJECTED | REVIEW |
review_notes | string | non | Notes de revue manuelle |
risk_score | int | non | Score de risque manuel (0–100) |
KYB — Flow end-user entreprise (lien de vérification)
Comme pour le KYC, vous pouvez déléguer la constitution du dossier à l'entreprise elle-même : créez le dossier avec flow: "hosted" et transmettez l'URL retournée. L'entreprise renseigne ses informations (formes juridiques OHADA et common law), dépose ses pièces et déclare ses bénéficiaires effectifs.
Requête
curl -X POST .../api/v1/kyb/create \
-H "Authorization: Bearer sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"company_name": "Sahel Distribution SARL",
"country": "CI",
"flow": "hosted"
}'Réponse 201
{
"id": "kyb_clx...",
"status": "PENDING",
"url": "https://verify.ori-advisory.com/verify-kyb/eyJ...",
"ubos": []
}Pièces demandées (adaptées OHADA / Afrique)
| Paramètre | Type | Requis | Description |
|---|---|---|---|
STATUTS | requis | non | Statuts signés et enregistrés |
RCCM | requis | non | Extrait RCCM < 3 mois (ou équivalent : CAC Nigeria, Registrar Ghana/Kenya…) |
DFE | facultatif | non | Déclaration fiscale d'existence / NIF |
PROOF_ADDRESS | facultatif | non | Justificatif d’adresse du siège < 3 mois |
FINANCIALS | facultatif | non | Derniers états financiers approuvés |
KYC automatique des bénéficiaires effectifs
À la soumission du dossier, une session KYC est créée pour chaque UBO détenant ≥ 25 % (seuil FATF/BCEAO). La réponse de finalisation — et le webhook kyb.completed — contiennent les liens de vérification à transmettre à chaque bénéficiaire :
{
"id": "kyb_clx...",
"status": "REVIEW",
"ubo_kyc_links": [
{
"ubo_id": "ubo_clx...",
"name": "Awa Diallo",
"ownership": 60,
"kyc_url": "https://verify.ori-advisory.com/verify/eyJ..."
}
]
}/dashboard/kyb) et via GET /kyb/{id}.AML — Screening d'une entité
Criblage d'une personne physique ou morale contre les listes de sanctions internationales (ONU, UE, OFAC…). Résultat disponible en moins de 2 secondes.
/api/v1/aml/screenRequête
{
"name": "Amadou Traoré",
"dob": "1968-11-15",
"nationality": "MLI",
"entity_type": "PERSON",
"ref_id": "kyc_session_id_ici",
"ref_type": "kyc_session"
}Réponse 201
{
"id": "aml_clx...",
"status": "CLEAR",
"match_type": "CLEAR",
"match_score": 0,
"top_match": null
}En cas de match
{
"status": "POTENTIAL_MATCH",
"match_type": "POTENTIAL",
"match_score": 0.88,
"top_match": {
"id": "NK-12345",
"caption": "Amadou Traoré (né 1968)",
"score": 0.88,
"datasets": ["un_sc_sanctions", "eu_fsf"]
}
}| Paramètre | Type | Requis | Description |
|---|---|---|---|
CLEAR | status | non | Aucun match au-dessus du seuil (0.85) — entité non listée |
POTENTIAL_MATCH | status | non | Score 0.85–0.94 — révision manuelle recommandée |
CONFIRMED_MATCH | status | non | Score ≥ 0.95 — forte correspondance, bloquez l'opération |
PENDING | status | non | Service yente indisponible — relancez dans 30s |
AML — Lister les screenings
/api/v1/aml/screenGET /api/v1/aml/screen?status=POTENTIAL_MATCH&page=1&limit=50{
"screenings": [
{
"id": "aml_clx...",
"entity_name": "Amadou Traoré",
"entity_type": "PERSON",
"status": "POTENTIAL_MATCH",
"match_score": 0.88,
"ref_id": "kyc_clx...",
"ref_type": "kyc_session",
"created_at": "2026-06-10T12:00:00.000Z"
}
],
"total": 1,
"page": 1,
"limit": 50
}Décisions — Monitoring pré-transaction (temps réel)
Appelez ce endpoint avant d'exécuter la transaction chez votre PSP : la réponse synchrone contient l'outcome à appliquer. Chaque scénario déclenché ajoute son score_modifier ; l'outcome découle de vos seuils (par défaut : REVIEW ≥ 30, BLOCK ≥ 60, DECLINE ≥ 90 ; un scénario bloquant force au minimum BLOCK).
/api/v1/decisionsRequête (data model canonique)
{
"external_id": "tx_20260704_001",
"amount": 75000000,
"currency": "XOF",
"type": "wire_transfer_out",
"direction": "OUTBOUND",
"payment_provider": "BANK",
"payment_method": "wire",
"sender_name": "Sahel Trading SARL",
"sender_account": "CI93CI042...",
"sender_country": "CI",
"receiver_country": "IR",
"country_dest": "IR",
"channel": "web",
"ip_address": "196.201.64.12",
"device_id": "dev_9f2a"
}Réponse 201
{
"id": "dec_clx...",
"transaction_id": "tx_clx...",
"phase": "PRE_AUTH",
"outcome": "DECLINE",
"score": 95,
"rules": [
{ "name": "Pays à haut risque",
"severity": "CRITICAL",
"score_modifier": 70,
"blocking": true },
{ "name": "Montant élevé",
"severity": "MEDIUM",
"score_modifier": 25,
"blocking": false }
],
"alert_ids": ["alr_..."]
}Outcomes
| Paramètre | Type | Requis | Description |
|---|---|---|---|
APPROVE | outcome | non | Exécutez la transaction |
REVIEW | outcome | non | Exécutez, une alerte est ouverte pour investigation |
BLOCK | outcome | non | Suspendez la transaction en attendant la revue |
DECLINE | outcome | non | Refusez définitivement |
Historique : GET /api/v1/decisions?outcome=BLOCK&phase=PRE_AUTH.
Transactions — Soumettre
Soumet une transaction au moteur de surveillance. Le moteur évalue instantanément tous les scénarios TM actifs et retourne le résultat (APPROVED / REVIEW / BLOCKED).
/api/v1/transactionsRequête
{
"external_id": "tx_bank_9876543",
"amount": 15000000,
"currency": "XOF",
"type": "wire_transfer_out",
"country_origin": "CI",
"country_dest": "NG",
"account_id": "acc_001",
"account_age_days": 12,
"metadata": {
"channel": "mobile_app",
"ip": "41.203.x.x"
}
}Réponse 201
{
"id": "tx_clx...",
"external_id": "tx_bank_9876543",
"status": "BLOCKED",
"blocked": true,
"alert_ids": ["alert_clx_aaa", "alert_clx_bbb"],
"created_at": "2026-06-10T14:30:00.000Z"
}Types de transaction supportés
cash_deposit | cash_withdrawal | wire_transfer_in | wire_transfer_out
mobile_money_in | mobile_money_out | card_payment | otherTransactions — Lister
/api/v1/transactionsGET /api/v1/transactions?status=BLOCKED&page=1&limit=50Connecteurs PSP — Stripe, Orange Money, Wave
Branchez directement les webhooks de vos prestataires de paiement : ORI Verify normalise leurs événements vers le data model canonique puis exécute le monitoring. Avec phase=pre, la réponse synchrone contient l'outcome — utilisez-la pour bloquer la transaction chez le PSP avant exécution.
POST /api/webhooks/psp/stripe?client_key=sk_live_...&phase=post
POST /api/webhooks/psp/orange-money?client_key=sk_live_...&phase=pre
POST /api/webhooks/psp/wave?client_key=sk_live_...| Paramètre | Type | Requis | Description |
|---|---|---|---|
client_key | query | oui | Votre clé API ORI Verify (identifie votre compte) |
phase | query | non | pre (décision synchrone avant exécution) | post (défaut, ingestion après coup) |
Mapping automatique
| Paramètre | Type | Requis | Description |
|---|---|---|---|
stripe | PSP | non | payment_intent.* / charge.* — montants en centimes convertis, devises zéro-décimale (XOF…) gérées. Signature Stripe-Signature vérifiée si STRIPE_WEBHOOK_SECRET configuré. |
orange-money | PSP | non | Callbacks Web Payment / MoMo API — txnid, subscriberMsisdn → sender_account |
wave | PSP | non | Checkout sessions / merchant payments — id, sender_mobile, client_reference |
duplicate: true) sans recréer de transaction.Scénarios TM — Créer
Les scénarios sont des règles métier qui déclenchent des alertes. Chaque scénario contient une ou plusieurs règles (logique AND). Exemple : montant élevé ET pays à risque.
/api/v1/scenariosRequête — Exemple 1 : gros virement
{
"name": "Virement > 10M XOF",
"description": "Alerte sur tout virement sortant > 10M XOF",
"is_active": true,
"blocking": false,
"severity": "HIGH",
"lookback_window": "24h",
"rules": [
{
"field": "amount",
"operator": "gte",
"value": 10000000
},
{
"field": "type",
"operator": "in",
"value": ["wire_transfer_out", "cash_withdrawal"]
}
]
}Requête — Exemple 2 : agrégat
{
"name": "Structuring > 5M / 24h",
"severity": "CRITICAL",
"blocking": true,
"rules": [
{
"field": "amount",
"operator": "gt",
"value": 0,
"aggregate": "sum",
"window": "24h"
},
{
"field": "amount",
"operator": "gte",
"value": 5000000,
"aggregate": "sum",
"window": "24h"
}
]
}Opérateurs disponibles
| Paramètre | Type | Requis | Description |
|---|---|---|---|
gt / gte / lt / lte | comparaison | non | Supérieur / inférieur à (strict ou non) — pour les nombres |
eq / neq | égalité | non | Égal / différent — fonctionne sur string et nombre |
in / not_in | liste | non | Valeur dans / hors d'une liste — ex: ["CI","NG","SN"] |
contains | string | non | La valeur du champ contient la chaîne |
Champs disponibles pour les règles
| Paramètre | Type | Requis | Description |
|---|---|---|---|
amount | number | non | Montant de la transaction (en devise brute) |
currency | string | non | Code ISO 4217 (XOF, EUR, USD…) |
type | string | non | Type de transaction (voir liste ci-dessus) |
country_origin | string | non | Code ISO 3166-1 alpha-2 du pays d'origine |
country_dest | string | non | Code ISO 3166-1 alpha-2 du pays de destination |
account_age_days | number | non | Ancienneté du compte en jours |
Agrégats (fenêtres temporelles)
| Paramètre | Type | Requis | Description |
|---|---|---|---|
aggregate: "count" | aggregate | non | Nombre de transactions du client sur la fenêtre |
aggregate: "sum" | aggregate | non | Somme des montants du client sur la fenêtre |
window: "30m" | durée | non | Fenêtre de 30 minutes (suffixes : m, h, d) |
Scénarios TM — Lister
/api/v1/scenariosGET /api/v1/scenarios?active=true&page=1&limit=50{
"scenarios": [
{
"id": "scen_clx...",
"name": "Virement > 10M XOF",
"is_active": true,
"blocking": false,
"severity": "HIGH",
"rules": [ { "field": "amount", "operator": "gte", "value": 10000000 } ],
"created_at": "2026-06-10T12:00:00.000Z"
}
],
"total": 1,
"page": 1,
"limit": 50
}Scénarios TM — Modifier / Supprimer
/api/v1/scenarios/{id}{
"is_active": false,
"blocking": true,
"severity": "CRITICAL"
}/api/v1/scenarios/{id}Risk Scoring — Configuration
Configure les poids et les tables de référence du scoring de risque client. Chaque axe est noté de 0 à 100 et les poids doivent totaliser 100.
/api/v1/risk/config{
"geography_weight": 25,
"customer_weight": 30,
"product_weight": 15,
"channel_weight": 15,
"transaction_weight": 15,
"country_scores": {
"CI": 40, "NG": 55, "ML": 50,
"__default": 40
},
"customer_scores": {
"individual": 20, "pep": 80,
"__default": 25
},
"risk_levels": [
{ "max": 30, "level": "LOW" },
{ "max": 55, "level": "MEDIUM" },
{ "max": 75, "level": "HIGH" },
{ "max": 100, "level": "VERY_HIGH" }
]
}/api/v1/risk/configAxes de risque
| Paramètre | Type | Requis | Description |
|---|---|---|---|
geography | axe | non | Pays de résidence ou de transaction (listes FATF incluses) |
customer | axe | non | Type de client : individual, pep, sme, ngo… |
product | axe | non | Produit utilisé : cash, virement, mobile money… |
channel | axe | non | Canal : agence, ATM, online, agent tiers |
transaction | axe | non | Comportement transactionnel : montant, fréquence, cash |
Risk Scoring — Calculer un score
Calcule instantanément un score de risque pour un client ou une opération, sans créer de session KYC.
/api/v1/risk/scoreRequête
{
"country_code": "NG",
"customer_type": "pep",
"product_type": "cash_withdrawal",
"channel": "third_party_agent",
"amount_usd": 25000,
"monthly_tx_count": 45,
"has_cash_intensive": true,
"has_high_risk_counterparty": false
}Réponse 200
{
"score": 87,
"level": "VERY_HIGH",
"axes": {
"geography": 55,
"customer": 80,
"product": 60,
"channel": 65,
"transaction": 95
}
}Webhooks
ORI Verify envoie des événements HTTP POST à vos endpoints lors des changements d'état. Configurez vos endpoints depuis le dashboard.
Événements disponibles
| Paramètre | Type | Requis | Description |
|---|---|---|---|
kyc.completed | event | non | Session KYC finalisée (APPROVED, REVIEW ou REJECTED) |
kyb.completed | event | non | Dossier KYB finalisé |
aml.match_found | event | non | Screening AML avec POTENTIAL_MATCH ou CONFIRMED_MATCH |
transaction.blocked | event | non | Transaction bloquée par un scénario TM |
transaction.flagged | event | non | Transaction en REVIEW suite à une alerte TM |
Format du payload
POST https://your-app.com/webhooks/ori-verify
Content-Type: application/json
X-ORI-Signature: sha256=<HMAC-SHA256 de la payload avec votre secret>
{
"event": "kyc.completed",
"session_id": "clx1a2b3c4d5e6f7g8h9",
"status": "APPROVED",
"timestamp": "2026-06-10T14:23:11.000Z"
}Vérification de signature
const crypto = require('crypto')
function verifyOriSignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
// Dans votre route Express :
app.post('/webhooks/ori', (req, res) => {
const sig = req.headers['x-ori-signature']
const body = req.rawBody // string
if (!verifyOriSignature(body, sig, process.env.ORI_WEBHOOK_SECRET)) {
return res.status(401).end()
}
const event = req.body
if (event.event === 'kyc.completed') {
// Mettez à jour votre base de données
await db.users.update({ where: { oriSessionId: event.session_id }, ... })
}
res.status(200).end()
})Livraison & re-tentatives
Risk Scoring — Règles custom & prestataires externes
Depuis Dashboard → Risk Scoring → Règles & prestataires, vos équipes conformité créent sans coder des règles qui ajustent le score interne (± points), et branchent des prestataires de scoring externes dont le score est pondéré dans le résultat final.
Règles custom
SI <champ> <opérateur> <valeur> ALORS score += <impact>
Champs : country_code · customer_type · product_type · channel ·
amount_usd · monthly_tx_count · has_cash_intensive
Opérateurs : eq · neq · in · not_in · gt · gte · lt · lte · contains
Impact : -100 à +100 points (négatif = réduit le risque)Prestataires externes (iDenfy, bureaux de crédit…)
Chaque prestataire actif reçoit l'input de scoring en POST JSON sur son endpoint HTTPS ; son score (0–100, lu au chemin configuré ex. data.risk.score) est combiné au score interne selon son poids. Un prestataire injoignable est ignoré — le scoring n'échoue jamais.
Réponse enrichie de POST /risk/score
{
"score": 84,
"level": "VERY_HIGH",
"axes": { "geography": 65, "customer": 85, "product": 75, "channel": 35, "transaction": 60 },
"rules_applied": [
{ "name": "Pays sous surveillance", "score_impact": 30 }
],
"providers": [
{ "name": "iDenfy Risk", "score": 72, "weight": 30 }
]
}SDK JavaScript / TypeScript
Le SDK officiel @ori-verify/sdk encapsule l'authentification et tous les modules. Typé de bout en bout, il fonctionne côté serveur (Node) — ne l'exposez jamais dans un bundle navigateur avec une clé sk_live_.
Installation
npm install @ori-verify/sdkCréer une session KYC
import { OriVerify } from '@ori-verify/sdk'
const ori = new OriVerify({
apiKey: process.env.ORI_API_KEY!, // sk_live_... ou sk_test_...
baseUrl: 'https://verify.ori-advisory.com/api/v1',
})
const session = await ori.kyc.create({
externalUserId: 'user_42',
redirectUrl: 'https://votre-app.com/kyc/done',
})
// Envoyez session.url à l'utilisateur (email, SMS, in-app)
console.log(session.url)Autres modules
await ori.kyb.create({ companyName: 'Demo SARL', registrationNo: 'CI-ABJ-...', country: 'CI' })
await ori.aml.screen({ name: 'Awa Diallo', nationality: 'SN', entityType: 'person' })
await ori.transactions.submit({ externalId: 'tx_1', amount: 75_000_000, type: 'wire_transfer_out' })
await ori.risk.score({ countryCode: 'ML', customerType: 'pep', productType: 'crypto' })OriVerifyError typée (avec status et body) sur toute réponse non-2xx — enveloppez vos appels dans un try / catch.API Keys — Administration
/api/v1/apikeys{
"keys": [
{
"id": "key_clx...",
"name": "Production",
"prefix": "sk_live_xxxx",
"environment": "LIVE",
"last_used_at": "2026-06-10T12:00:00Z",
"created_at": "2026-06-01T00:00:00Z"
}
]
}/api/v1/apikeys// Requête
{ "name": "Mobile App", "environment": "LIVE" }
// Réponse 201 — la clé complète n'est visible qu'une seule fois
{
"id": "key_clx...",
"key": "sk_live_AbCdEfGhIjKl...",
"name": "Mobile App",
"environment": "LIVE"
}/api/v1/apikeys/{id}/revoke401.