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

# API de vérification de code SMS : valider un OTP

> Didit : validez un code OTP SMS via POST /v3/phone/check/. Détection de l'opérateur, des numéros virtuels et jetables. Paiement à l'usage.

## Gérer les pannes du fournisseur

Si le fournisseur téléphonique est temporairement indisponible, cet endpoint renvoie `502` avec un code stable lisible par machine :

```json theme={null}
{
  "detail": "The phone verification provider is temporarily unavailable.",
  "code": "phone_provider_unavailable"
}
```

Traitez cette réponse comme pouvant faire l'objet d'une nouvelle tentative. Attendez un court délai avant de réessayer, et affichez à l'utilisateur un message de service temporairement indisponible plutôt que de lui demander de modifier un numéro de téléphone ou un code valide.

## Module complémentaire d'intelligence

Définissez `enable_enrichment` sur `true` pour lancer également une analyse intelligente du numéro de téléphone : un score de risque, le type de ligne, si le numéro a été récemment porté et un indice de confiance.
Le module complémentaire est facturé \$0.05 par requête au tarif public, en plus du prix de la vérification.
La requête renvoie `403` lorsque votre solde ne suffit pas à le couvrir.

Quatre champs déterminent l'effet des signaux.
Chacun prend la valeur `NO_ACTION` (par défaut) ou `DECLINE`, et chacun ne s'applique que lorsque `enable_enrichment` est `true`.

| Champ | Refus lorsque |
| - | - |
| `phone_intelligence_score_action` | Le score de risque est supérieur au seuil. |
| `phone_type_risk_action` | Le numéro correspond à un type de ligne à haut risque. |
| `recent_port_action` | Le numéro a été porté récemment vers un autre opérateur. |
| `low_phone_trust_action` | L'indice de confiance est inférieur ou égal au seuil. |

Avec `NO_ACTION`, le signal est tout de même renvoyé dans `phone.phone_intelligence`, afin que vous puissiez appliquer votre propre règle.


## OpenAPI

````yaml fr/openapi-25.json POST /v3/phone/check/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de vérification d'identité. Authentifiez-vous avec l'en-tête x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/phone/check/:
    post:
      tags:
        - Standalone APIs
      summary: Vérifier le code de téléphone
      description: >-
        Vérifiez l'OTP délivré par [`POST
        /v3/phone/send/`](/fr/standalone-apis/phone-send) et obtenez le résultat
        final de la vérification ainsi que les renseignements sur le téléphone :
        nom de l'opérateur et type de ligne, indicateurs de numéro virtuel
        (VoIP) et jetable, et utilisation en double du numéro parmi vos
        sessions.


        **Comment la vérification retrouve l'enregistrement.** La correspondance
        s'effectue via votre application et le `phone_number` au format E.164
        (`request_id` n'est pas un paramètre d'entrée). La vérification en
        attente la plus récente créée au cours des **5 dernières minutes** est
        contrôlée. S'il n'en existe aucune (jamais envoyée, déjà finalisée ou
        datant de plus de 5 minutes), l'endpoint renvoie `200` avec `status:
        "Expired or Not Found"`.


        **Quota de tentatives.** Chaque vérification autorise **3 tentatives de
        code**. Les deux premiers codes incorrects renvoient `status: "Failed"`
        avec le nombre de tentatives restantes et `phone: null` ; le troisième
        code incorrect finalise la vérification avec le statut `Declined`,
        assorti d'un avertissement `VERIFICATION_CODE_ATTEMPTS_EXCEEDED`, et
        renvoie le rapport téléphonique complet.


        **Résultats.** `Approved` : code correct et aucun risque entraînant un
        refus. `Declined` : définitif, le code était correct mais un risque
        entraînant un refus a été détecté (une action `DECLINE` ci-dessous, un
        numéro sur liste de blocage ou à haut risque), ou le quota de tentatives
        a été épuisé. `Failed` : mauvais code, tentatives restantes. `Expired or
        Not Found` : rien à vérifier. Pour `Approved`/`Declined`, `request_id`
        est égal au `request_id` de l'envoi (l'identifiant de session) et
        `phone` contient le rapport complet (`carrier`, `is_virtual`,
        `is_disposable`, `warnings`, `lifecycle`, `matches`) ; pour `Failed` et
        `Expired or Not Found`, `request_id` est un UUID aléatoire unique.


        **Actions en cas de risque.** `duplicated_phone_number_action`,
        `disposable_number_action` et `voip_number_action` déterminent ce qui se
        passe lorsque le risque correspondant est détecté sur un code correct :
        `DECLINE` bascule le statut final à `Declined` ; `NO_ACTION` (valeur par
        défaut) enregistre le risque dans `phone.warnings` sans affecter le
        statut.


        **Facturation.** Les contrôles sont gratuits, la livraison est facturée
        du côté de l'envoi (voir [Tarifs de la vérification du
        téléphone](/fr/getting-started/phone-verification-pricing)).


        **Persistance de la session.** Un contrôle finalisé met à jour la
        session créée par l'envoi (visible dans la Business Console, consultable
        via `GET /v3/session/{sessionId}/decision/`) et déclenche un webhook
        `status.updated`.


        **Sandbox.** Les clés API de sandbox ignorent tout traitement : tout
        code bien formé (de 4 à 8 chiffres, `123456` inclus) renvoie un payload
        statique `Approved` avec un objet `phone` simplifié et plat (`status`,
        `phone_number`, `country_code`, `carrier_name`, `line_type`, `flags`) ;
        une entrée mal formée renvoie toujours `400`. Rien n'est conservé.


        **Authentification.** Envoyez la clé API de votre application dans
        l'en-tête `x-api-key`. Des identifiants manquants ou non valides
        renvoient `403` (`{"detail": "You do not have permission to perform this
        action."}`) ; cette API ne renvoie jamais `401`.


        **Limites de débit.** Quota partagé d'écriture de 300 requêtes/min par
        clé API, en plus de la limite anti-abus en amont de 4 tentatives par
        numéro et par heure ; dépasser l'une ou l'autre renvoie `429`.


        **Empreinte sociale.** Définissez `enable_social` sur `true` pour
        ajouter un bloc `phone_social` : les plateformes en ligne sur lesquelles
        ce numéro est enregistré, avec le nombre par catégorie et les détails de
        profil disponibles. `profiles_registered: 0` signifie que les
        plateformes ont été vérifiées et que le numéro n'a été trouvé sur aucune
        d'entre elles - une réponse valide et facturable. Le bloc est absent
        lorsque le module complémentaire n'a pas été demandé ou que le contrôle
        n'a pas pu aboutir, et il n'est pas facturé dans ce cas. La facturation
        ajoute une unité `phone_social` par requête au prix propre de cet
        endpoint.
      operationId: post_v3phone_check
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  type: string
                  maxLength: 20
                  description: >-
                    Le même numéro de téléphone que celui utilisé dans l'appel
                    [`POST /v3/phone/send/`](/fr/standalone-apis/phone-send)
                    correspondant, au format E.164. C'est ce qui associe la
                    vérification à l'envoi.
                  example: '+14155552671'
                code:
                  type: string
                  minLength: 4
                  maxLength: 8
                  pattern: ^[0-9]{4,8}$
                  description: >-
                    L'OTP reçu par l'utilisateur final. Doit comporter entre 4
                    et 8 chiffres numériques — toute autre valeur renvoie `400`
                    sans décompter de tentative. Un code bien formé mais
                    incorrect renvoie `200` avec `status: "Failed"` et décompte
                    l'une des 3 tentatives.
                  example: '123456'
                duplicated_phone_number_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: >-
                    Que faire lorsque le même numéro a déjà été utilisé par un
                    autre utilisateur (`vendor_data` différent) de votre
                    application. `DECLINE` fait passer le `status` final à
                    `Declined` ; `NO_ACTION` enregistre le risque dans
                    `phone.warnings` et renseigne `phone.matches`.
                disposable_number_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: >-
                    Ce qu'il faut faire lorsque la recherche d'opérateur signale
                    le numéro comme une ligne temporaire ou jetable
                    (`phone.is_disposable`). `DECLINE` fait passer le `status`
                    final à `Declined` ; `NO_ACTION` enregistre le risque dans
                    `phone.warnings`.
                voip_number_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: >-
                    Ce qu'il faut faire lorsque la recherche d'opérateur indique
                    un type de ligne virtuelle — `voip`, `isp` ou `vpn`
                    (`phone.is_virtual`). `DECLINE` fait passer le `status`
                    final à `Declined` ; `NO_ACTION` enregistre le risque dans
                    `phone.warnings`.
                enable_enrichment:
                  type: boolean
                  default: false
                  description: >-
                    Lorsque la valeur est `true`, exécute également une analyse
                    de renseignements téléphoniques sur le numéro : un score de
                    risque, le type de ligne, un éventuel portage récent et un
                    indice de confiance. Facturé comme une unité
                    `phone_intelligence_api` par requête ($0.05 au prix
                    catalogue) en plus du prix propre à cet endpoint. La requête
                    renvoie `403` lorsque votre solde ne permet pas de la
                    couvrir.
                  example: false
                phone_intelligence_score_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: "Action lorsque le score de risque de l'intelligence téléphonique est supérieur au seuil. `DECLINE` fait passer le `status` final à `Declined`\_; `NO_ACTION` enregistre le signal sans refuser. Ne prend effet que lorsque `enable_enrichment` est `true`."
                phone_type_risk_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: "Action lorsque le numéro correspond à un type de ligne à haut risque. `DECLINE` fait passer le `status` final à `Declined`\_; `NO_ACTION` enregistre le signal sans refuser. Ne prend effet que lorsque `enable_enrichment` est `true`."
                recent_port_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: "Action lorsque le numéro a été récemment porté vers un autre opérateur. `DECLINE` fait passer le `status` final à `Declined`\_; `NO_ACTION` enregistre le signal sans refuser. Ne prend effet que lorsque `enable_enrichment` est `true`."
                low_phone_trust_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: "Action lorsque l'indice de confiance de l'intelligence téléphonique est inférieur ou égal au seuil. `DECLINE` fait passer le `status` final à `Declined`\_; `NO_ACTION` enregistre le signal sans refuser. Ne prend effet que lorsque `enable_enrichment` est `true`."
                enable_social:
                  type: boolean
                  default: false
                  description: >-
                    Si true, recherche également l'empreinte sociale du numéro :
                    les plateformes de messagerie, sociales, d'e-commerce et
                    professionnelles sur lesquelles il est enregistré. Facturé
                    comme une unité `phone_social` par requête en plus du prix
                    propre de cet endpoint.
                  example: true
                phone_no_social_presence_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: "Action lorsque la vérification de l'empreinte sociale ne trouve le numéro enregistré sur aucune des plateformes couvertes. Seuls NO_ACTION et DECLINE sont acceptés sur cet endpoint\_; REVIEW est disponible sur la clé de configuration du workflow du même nom."
              required:
                - phone_number
                - code
            examples:
              Default:
                summary: >-
                  Enregistrer tous les risques sans jamais refuser
                  automatiquement
                value:
                  phone_number: '+14155552671'
                  code: '123456'
              Strict risk policy:
                summary: Refuser automatiquement les lignes VoIP et jetables
                value:
                  phone_number: '+14155552671'
                  code: '123456'
                  voip_number_action: DECLINE
                  disposable_number_action: DECLINE
      responses:
        '200':
          description: >-
            Vérification terminée — les codes erronés et les vérifications
            manquantes renvoient également `200` ; inspectez `status`, et non le
            code HTTP. `phone` n'est renseigné que pour les résultats finalisés
            (`Approved`/`Declined`), vaut `null` pour `Failed`, et est absent
            pour `Expired or Not Found`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhoneVerificationCheckResponse'
              examples:
                Approved:
                  summary: >-
                    Code correct — rapport téléphonique complet avec opérateur,
                    cycle de vie et correspondances
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Approved
                    message: The verification code is correct.
                    phone:
                      status: Approved
                      phone_number_prefix: '+1'
                      phone_number: '4155552671'
                      full_number: '+14155552671'
                      country_code: US
                      country_name: United States
                      carrier:
                        name: AT&T
                        type: mobile
                      is_disposable: false
                      is_virtual: false
                      verification_method: whatsapp
                      verification_attempts: 1
                      verified_at: '2026-06-12T01:24:47.311323Z'
                      warnings: []
                      lifecycle:
                        - type: PHONE_VERIFICATION_MESSAGE_SENT
                          timestamp: '2026-06-12T01:23:39.580554+00:00'
                          details:
                            status: Success
                            reason: null
                            channel: whatsapp
                            actual_channel: whatsapp
                          fee: 0.0509
                        - type: PHONE_DELIVERY_DELIVERED
                          timestamp: '2026-06-12T01:23:43.118220+00:00'
                          details:
                            channel: whatsapp
                            status: delivered
                          fee: 0
                        - type: VALID_CODE_ENTERED
                          timestamp: '2026-06-12T01:24:47.311201+00:00'
                          details:
                            code_tried: '123456'
                            status: Approved
                          fee: 0
                        - type: PHONE_VERIFICATION_APPROVED
                          timestamp: '2026-06-12T01:24:47.384292+00:00'
                          details: null
                          fee: 0
                      matches: []
                    vendor_data: user-1234
                    metadata: null
                    created_at: '2026-06-12T01:24:47.401719+00:00'
                Failed (attempts remaining):
                  summary: >-
                    Code erroné — l'utilisateur peut réessayer ; request_id est
                    ici un UUID à usage unique
                  value:
                    request_id: 11111111-2222-3333-4444-555555555555
                    status: Failed
                    message: 'The verification code is incorrect. Attempts remaining: 2'
                    phone: null
                    vendor_data: user-1234
                    metadata: null
                    created_at: '2026-06-12T01:24:21.512340+00:00'
                Declined (max attempts):
                  summary: >-
                    Troisième code erroné — vérification finalisée avec le
                    statut Refusé
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Declined
                    message: >-
                      The verification code is incorrect. Maximum attempts
                      reached.
                    phone:
                      status: Declined
                      phone_number_prefix: '+1'
                      phone_number: '4155552671'
                      full_number: '+14155552671'
                      country_code: US
                      country_name: United States
                      carrier:
                        name: AT&T
                        type: mobile
                      is_disposable: false
                      is_virtual: false
                      verification_method: whatsapp
                      verification_attempts: 1
                      verified_at: null
                      warnings:
                        - feature: PHONE
                          risk: VERIFICATION_CODE_ATTEMPTS_EXCEEDED
                          additional_data: null
                          log_type: error
                          short_description: Verification code attempts exceeded
                          long_description: >-
                            The system detected that the phone number has
                            exceeded the maximum number of verification code
                            attempts.
                      lifecycle:
                        - type: PHONE_VERIFICATION_MESSAGE_SENT
                          timestamp: '2026-06-12T01:23:39.580554+00:00'
                          details:
                            status: Success
                            reason: null
                            channel: whatsapp
                            actual_channel: whatsapp
                          fee: 0.0509
                        - type: INVALID_CODE_ENTERED
                          timestamp: '2026-06-12T01:24:01.118220+00:00'
                          details:
                            code_tried: '111111'
                            status: Failed
                          fee: 0
                        - type: INVALID_CODE_ENTERED
                          timestamp: '2026-06-12T01:24:21.512340+00:00'
                          details:
                            code_tried: '222222'
                            status: Failed
                          fee: 0
                        - type: INVALID_CODE_ENTERED
                          timestamp: '2026-06-12T01:24:47.311201+00:00'
                          details:
                            code_tried: '333333'
                            status: Failed
                          fee: 0
                        - type: PHONE_VERIFICATION_DECLINED
                          timestamp: '2026-06-12T01:24:47.384292+00:00'
                          details:
                            reason: VERIFICATION_CODE_ATTEMPTS_EXCEEDED
                          fee: 0
                      matches: []
                    vendor_data: user-1234
                    metadata: null
                    created_at: '2026-06-12T01:24:47.401719+00:00'
                Declined (risk policy):
                  summary: >-
                    Code correct, mais la ligne est VoIP et
                    voip_number_action=DECLINE
                  value:
                    request_id: 7f1c9d2e-44a1-4b6e-9a3e-5b8e6f1c2d3a
                    status: Declined
                    message: The verification code is correct.
                    phone:
                      status: Declined
                      phone_number_prefix: '+1'
                      phone_number: '5005550006'
                      full_number: '+15005550006'
                      country_code: US
                      country_name: United States
                      carrier:
                        name: CLEC LLC
                        type: voip
                      is_disposable: false
                      is_virtual: true
                      verification_method: sms
                      verification_attempts: 1
                      verified_at: '2026-06-12T01:24:47.311323Z'
                      warnings:
                        - feature: PHONE
                          risk: VOIP_NUMBER_DETECTED
                          additional_data: null
                          log_type: error
                          short_description: VoIP number detected
                          long_description: >-
                            The system detected that the phone number is a VoIP
                            number, which is not allowed.
                      lifecycle:
                        - type: PHONE_VERIFICATION_MESSAGE_SENT
                          timestamp: '2026-06-12T01:23:39.580554+00:00'
                          details:
                            status: Success
                            reason: null
                            channel: whatsapp
                            actual_channel: sms
                          fee: 0.0509
                        - type: VALID_CODE_ENTERED
                          timestamp: '2026-06-12T01:24:47.311201+00:00'
                          details:
                            code_tried: '123456'
                            status: Approved
                          fee: 0
                        - type: PHONE_VERIFICATION_DECLINED
                          timestamp: '2026-06-12T01:24:47.384292+00:00'
                          details:
                            reason: VOIP_NUMBER_DETECTED
                          fee: 0
                      matches: []
                    vendor_data: user-1234
                    metadata: null
                    created_at: '2026-06-12T01:24:47.401719+00:00'
                Expired or Not Found:
                  summary: >-
                    Aucune vérification en attente pour ce numéro au cours des 5
                    dernières minutes
                  value:
                    request_id: 69cc35c6-280a-47a6-ab8c-4f32abc02ed0
                    status: Expired or Not Found
                    message: No pending phone verification found in the last 5 minutes.
                    vendor_data: null
                    metadata: null
                    created_at: '2026-06-12T01:24:47.311323+00:00'
        '400':
          description: >-
            Erreur de validation — enveloppe d'erreur de champ de DRF : un
            tableau de messages par champ concerné.
          content:
            application/json:
              examples:
                Invalid code format:
                  summary: '`code` n''est pas composé de 4 à 8 chiffres'
                  value:
                    code:
                      - Invalid code format. Enter 4 to 8 numeric digits.
                Invalid phone number:
                  summary: '`phone_number` n''est pas au format E.164 valide'
                  value:
                    phone_number:
                      - Invalid phone number provided.
                Invalid action:
                  summary: >-
                    Les actions de risque acceptent uniquement NO_ACTION ou
                    DECLINE
                  value:
                    voip_number_action:
                      - '"REVIEW" is not a valid choice.'
        '403':
          description: "Permission refusée. Renvoyé lorsque l'en-tête `x-api-key` est manquant\_; une clé incorrecte, révoquée ou expirée renvoie `401`. Les vérifications sont gratuites, aucun contrôle de crédit n'est donc effectué ici."
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: Aucun en-tête `x-api-key`, ou la clé est non valide/révoquée
                  value:
                    detail: You do not have permission to perform this action.
        '429':
          description: >-
            Limite de débit dépassée. Les endpoints POST/PATCH/DELETE partagent
            un budget de 300 requêtes d'écriture par minute par clé API (la
            création de transactions et l'ingestion d'événements disposent d'un
            budget distinct de 600). De plus, un plafond anti-abus de 4
            tentatives de vérification par numéro de téléphone par heure
            s'applique en amont. La réponse contient les en-têtes
            `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` et
            `Retry-After`. Remarque : les en-têtes `X-RateLimit-*`/`Retry-After`
            accompagnent uniquement l'erreur 429 de la limite d'écriture de
            300/min ; l'erreur 429 du plafond par numéro ne comporte aucun
            en-tête de limitation de débit.
          content:
            application/json:
              examples:
                Per-number cap:
                  summary: >-
                    Plus de 4 tentatives de vérification pour le même numéro au
                    cours de la dernière heure
                  value:
                    detail: >-
                      Maximum verification attempts reached for this phone
                      number. Only 4 authentication attempts are allowed per
                      hour. Try again later or use a different number.
                Write rate limit exceeded:
                  summary: >-
                    Plus de 300 requêtes d'écriture au cours de la minute
                    actuelle
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '500':
          description: >-
            Échec inattendu lors de la vérification du code en amont ne
            correspondant pas à une panne connue du fournisseur. Peut être
            réessayé en toute sécurité ; le quota de tentatives n'est consommé
            que par les vérifications terminées.
          content:
            application/json:
              examples:
                Provider error:
                  summary: La vérification du code n'a pas pu être effectuée
                  value:
                    detail: Error checking phone verification
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '502':
          description: >-
            Le fournisseur de vérification du téléphone est temporairement
            indisponible - une réponse 5xx, un délai d'attente dépassé ou une
            erreur de connexion persistante après les tentatives automatiques
            intégrées. Vous pouvez réessayer en toute sécurité ; le quota de
            tentatives n'est pas consommé.
          content:
            application/json:
              examples:
                Provider outage:
                  summary: Le fournisseur n'a pas répondu à la requête de vérification
                  value:
                    detail: >-
                      Phone verification is temporarily unavailable. Please try
                      again shortly.
                    code: phone_provider_unavailable
              schema:
                type: object
                properties:
                  detail:
                    type: string
                  code:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/phone/check/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "phone_number": "+14155552671",
                "code": "123456",
                "voip_number_action": "DECLINE"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.phone.check_code(
                phone_number="+14155552671",
                code="123456",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.phone.checkCode({
              phone_number: "+14155552671",
              code: "123456",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tCode:        \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.PhoneCheckCodeParams;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            var result = client.phone().checkCode(PhoneCheckCodeParams.builder()
                    .phoneNumber("+14155552671")
                    .code("123456")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->phone->checkCode([
                'phone_number' => '+14155552671',
                'code' => '123456',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.phone.check_code(
              phone_number: "+14155552671",
              code: "123456"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.Phone.CheckCodeAsync(new
            PhoneCheckCodeParams

            {
                PhoneNumber = "+14155552671",
                Code = "123456",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    PhoneVerificationCheckResponse:
      type: object
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            Pour `Approved`/`Declined` : l'identifiant de session de la
            vérification correspondante — identique au `request_id` renvoyé par
            `POST /v3/phone/send/`. Pour `Failed` et `Expired or Not Found` : un
            UUID aléatoire à usage unique qui ne pourra pas être consulté
            ultérieurement.
        status:
          type: string
          enum:
            - Approved
            - Declined
            - Failed
            - Expired or Not Found
          description: >-
            `Approved` — code correct, aucun risque de refus. `Declined` —
            définitif : un risque entraînant un refus a correspondu ou le nombre
            maximal de tentatives (3) a été épuisé. `Failed` — code erroné,
            tentatives restantes. `Expired or Not Found` — aucune vérification
            en attente pour ce numéro au cours des 5 dernières minutes.
        message:
          type: string
          description: >-
            Explication lisible par l'humain du résultat, incluant le nombre de
            tentatives restantes après un code erroné.
        phone:
          type: object
          nullable: true
          description: >-
            Rapport téléphonique complet. Présent (non nul) uniquement pour les
            résultats finalisés (`Approved`/`Declined`) ; `null` en cas de
            `Failed` et absent en cas de `Expired or Not Found`.
          properties:
            status:
              type: string
              enum:
                - Approved
                - Declined
                - In Review
                - Not Finished
                - Expired
              description: >-
                Statut final de la vérification du téléphone. Correspond au
                `status` de premier niveau pour les vérifications finalisées.
            phone_number_prefix:
              type: string
              description: >-
                Indicatif téléphonique du pays avec un `+` au début (par ex.,
                `+1`).
              example: '+1'
            phone_number:
              type: string
              description: Numéro national sans l'indicatif téléphonique du pays.
              example: '4155552671'
            full_number:
              type: string
              description: Numéro complet au format E.164.
              example: '+14155552671'
            country_code:
              type: string
              nullable: true
              description: Pays ISO 3166-1 alpha-2 du numéro.
              example: US
            country_name:
              type: string
              description: Nom complet du pays dérivé de `country_code`.
              example: United States
            carrier:
              type: object
              description: >-
                Réseau actuel desservant le numéro, issu de la recherche
                d'opérateur effectuée lors de la finalisation.
              properties:
                name:
                  type: string
                  description: >-
                    Nom de l'opérateur. Chaîne vide lorsque la recherche n'a pas
                    pu l'identifier.
                type:
                  type: string
                  description: >-
                    Type de ligne signalé par la recherche : `mobile`,
                    `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`,
                    `premium_rate`, `pager`, `payphone`, `satellite`, `service`,
                    `shared_cost`, `short_codes_commercial`, `calling_cards`,
                    `local_rate`, `universal_access`, `voice_mail`, `other` ou
                    `unknown`.
            is_disposable:
              type: boolean
              description: >-
                `true` lorsque le numéro appartient à un service de numéros
                temporaires/jetables.
            is_virtual:
              type: boolean
              description: >-
                `true` lorsque le type de ligne est virtuel (`voip`, `isp` ou
                `vpn`).
            verification_method:
              type: string
              description: >-
                Canal ayant réellement délivré l'OTP une fois la livraison
                confirmée (par ex. `whatsapp`, `sms`) ; jusqu'à cette
                confirmation, il s'agit du canal demandé.
            verification_attempts:
              type: integer
              description: >-
                Nombre d'envois d'OTP pour cette vérification (1, ou 2 après une
                nouvelle tentative).
            verified_at:
              type: string
              format: date-time
              nullable: true
              description: >-
                Date et heure de saisie du code correct. `null` si la
                vérification n'a jamais été approuvée.
            warnings:
              type: array
              description: >-
                Avertissements de risque enregistrés pendant la vérification
                (doublon, jetable, VoIP, nombre maximal de tentatives dépassé,
                liste de blocage, etc.). Tableau vide lorsqu'il n'y en a aucun.
              items:
                type: object
                properties:
                  feature:
                    type: string
                    description: >-
                      Fonctionnalité ayant généré l'avertissement. Toujours
                      `PHONE` ici.
                  risk:
                    type: string
                    description: Code de risque lisible par machine.
                  additional_data:
                    type: object
                    nullable: true
                    description: >-
                      Contexte spécifique au risque (par ex., l'identifiant de
                      la session dupliquée pour les risques de doublon). `null`
                      lorsque le risque ne comporte aucune donnée
                      supplémentaire.
                  log_type:
                    type: string
                    enum:
                      - error
                      - warning
                      - information
                    description: >-
                      Gravité. Les risques `error` entraînent le refus de la
                      vérification, `warning` la signale pour examen, et
                      `information` est enregistrée sans affecter le statut.
                  short_description:
                    type: string
                    description: Résumé du risque en une ligne, lisible par l'utilisateur.
                  long_description:
                    type: string
                    description: Explication lisible par l'humain du risque.
            lifecycle:
              type: array
              description: >-
                Piste d'audit chronologique de la vérification. L'événement
                `type` est l'un des suivants :
                `PHONE_VERIFICATION_MESSAGE_SENT`,
                `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`,
                `PHONE_VERIFICATION_BLOCKED`, `PHONE_DELIVERY_DELIVERED`,
                `PHONE_DELIVERY_UNDELIVERABLE`, `VALID_CODE_ENTERED`,
                `INVALID_CODE_ENTERED`, `PHONE_VERIFICATION_APPROVED`,
                `PHONE_VERIFICATION_DECLINED`, `PHONE_VERIFICATION_IN_REVIEW`,
                `PHONE_VERIFICATION_EXPIRED`.
              items:
                type: object
                properties:
                  type:
                    type: string
                    description: Type d'événement.
                  timestamp:
                    type: string
                    format: date-time
                    description: Date et heure de l'événement.
                  details:
                    type: object
                    nullable: true
                    description: >-
                      Payload spécifique à l'événement. Événements d'envoi :
                      `{status, reason, channel, actual_channel}`
                      (`actual_channel` est renseigné une fois la livraison
                      confirmée). Événements de livraison : `{channel, status}`.
                      Événements de saisie de code : `{code_tried, status}`.
                      Événements de statut final : `null`, ou `{reason}` en cas
                      de refus ou d'examen en cours.
                  fee:
                    type: number
                    description: "Montant en USD facturé pour cet événement. Non nul uniquement sur les événements d'envoi (le prix de la livraison)\_; 0 pour les saisies de code, les confirmations de livraison et les événements de statut."
            matches:
              type: array
              description: >-
                Autres sessions de votre application (KYC, KYB ou API) où le
                même numéro de téléphone a été utilisé par un utilisateur
                différent (`vendor_data` différent). Jusqu'à 5 entrées, avec en
                premier une correspondance synthétique issue d'une liste de
                blocage lorsqu'elle est présente (les correspondances dérivées
                de sessions conservent l'ordre de la requête). Tableau vide
                lorsqu'il n'y a aucune correspondance.
              items:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                    description: >-
                      ID de session de l'autre vérification ayant utilisé ce
                      numéro de téléphone.
                  session_number:
                    type: integer
                    description: Numéro séquentiel lisible par l'humain de cette session.
                  vendor_data:
                    type: string
                    nullable: true
                    description: '`vendor_data` de cette session.'
                  verification_date:
                    type: string
                    description: >-
                      Date et heure de création de cette session
                      (`YYYY-MM-DDTHH:MM:SSZ`).
                  phone_number:
                    type: string
                    description: Le numéro de téléphone correspondant.
                  status:
                    type: string
                    description: >-
                      Statut de cette session (par exemple, `Approved`,
                      `Declined`, `In Progress`).
                  is_blocklisted:
                    type: boolean
                    description: >-
                      Indique si le numéro de téléphone figure sur la liste de
                      blocage de votre application.
                  api_service:
                    type: string
                    nullable: true
                    description: >-
                      Pour les sessions de type API, l'API autonome qui l'a
                      créée (par ex., `PHONE_VERIFICATION`) ; `null` pour les
                      sessions de vérification régulières.
                  source:
                    type: string
                    description: >-
                      Emplacement où la correspondance a été trouvée.
                      Généralement `session` ; une correspondance avec une liste
                      de blocage via une entrée de liste d'organisation insère
                      une correspondance synthétique avec `source: "list_entry"`
                      et `session_id`/`session_number` à null.
            phone_social:
              $ref: '#/components/schemas/PhoneSocialFootprint'
            phone_intelligence:
              allOf:
                - $ref: '#/components/schemas/PhoneIntelligence'
              description: >-
                Signaux d'intelligence téléphonique. Présent uniquement lorsque
                `enable_enrichment` valait `true` lors de la vérification.
        vendor_data:
          type: string
          nullable: true
          description: >-
            `vendor_data` de la session de la vérification correspondante.
            `null` pour `Expired or Not Found`.
        metadata:
          type: object
          nullable: true
          description: >-
            `metadata` de la session de la vérification correspondante. `null`
            pour `Expired or Not Found`.
        created_at:
          type: string
          format: date-time
          description: Horodatage de cette réponse de vérification.
    PhoneSocialFootprint:
      type: object
      nullable: true
      description: >-
        Empreinte sociale du numéro de téléphone : les plateformes en ligne sur
        lesquelles il est enregistré. Présent uniquement lorsque `enable_social`
        a été défini et que la vérification s'est terminée. Chaque décompte peut
        être nul lorsqu'aucune donnée n'a été renvoyée pour celui-ci.
        `profiles_registered: 0` signifie que les plateformes ont été vérifiées
        et que le numéro de téléphone n'a été trouvé sur aucune d'entre elles,
        une réponse valide et facturable, ainsi qu'un signal fréquent d'identité
        synthétique.
      properties:
        profiles_registered:
          type: integer
          nullable: true
          description: >-
            Plateformes pour lesquelles l'inscription du numéro de téléphone est
            confirmée.
          example: 5
        profiles_checked:
          type: integer
          nullable: true
          description: Plateformes évaluées pour l'inscription.
          example: 14
        names_found:
          type: integer
          nullable: true
          description: Plateformes ayant renvoyé un nom associé.
          example: 0
        photos_found:
          type: integer
          nullable: true
          description: Plateformes ayant renvoyé une photo de profil.
          example: 0
        communication_breadth:
          type: integer
          nullable: true
          description: >-
            Plateformes de communication sur lesquelles une présence a été
            détectée.
          example: 2
        digital_footprint_diversity:
          type: integer
          nullable: true
          description: Catégories de plateformes distinctes avec une présence détectée.
          example: 5
        digital_sophistication_index:
          type: integer
          nullable: true
          description: Indicateur composite de maturité numérique, de 0 à 10.
          example: 5
        engagement_depth_index:
          type: integer
          nullable: true
          description: Indicateur de richesse du profil, de 0 à 10.
          example: 3
        subscription_affordability_index:
          type: integer
          nullable: true
          description: Mix de plateformes gratuites vs payantes, 0-10.
          example: 2
        free_platforms:
          type: integer
          nullable: true
          description: Inscriptions sur des plateformes gratuites.
          example: 4
        full_paid_platforms:
          type: integer
          nullable: true
          description: Inscriptions sur des plateformes payantes.
          example: 0
        partial_paid_platforms:
          type: integer
          nullable: true
          description: Inscriptions sur des plateformes freemium.
          example: 1
        whatsapp_profile_completeness:
          type: string
          nullable: true
          enum:
            - Basic
            - Partial
            - Complete
            - Not Present
            - null
          description: "Niveau de complétion du profil WhatsApp. Téléphone uniquement\_; null pour l'e-mail."
          example: Partial
        registered_platforms:
          type: array
          description: Plateformes pour lesquelles l'inscription est confirmée.
          items:
            $ref: '#/components/schemas/SocialFootprintPlatform'
        not_registered_platforms:
          type: array
          description: Plateformes vérifiées avec un résultat négatif.
          items:
            $ref: '#/components/schemas/SocialFootprintPlatform'
        categories:
          type: object
          description: Nombre d'inscrits et ratio par catégorie de plateforme.
          additionalProperties:
            $ref: '#/components/schemas/SocialFootprintCategorySummary'
        profiles:
          type: object
          description: >-
            Détails du profil par plateforme, indexés par plateforme, lorsque
            celle-ci les expose.
          additionalProperties:
            $ref: '#/components/schemas/SocialFootprintProfile'
    PhoneIntelligence:
      type: object
      description: >-
        Bloc de renseignements téléphoniques normalisé. Présent uniquement
        lorsque le module complémentaire d'intelligence a été exécuté pour cette
        recherche ; lorsqu'il est présent, il est également exposé sous l'alias
        `enrichment` avec des valeurs identiques.
      properties:
        score:
          type: number
          nullable: true
          description: >-
            Score de risque normalisé de 0 à 100. Plus la valeur est élevée,
            plus le risque est grand.
        phone_type_risk:
          type: string
          nullable: true
          description: '`Low`, `Medium` ou `High`, dérivé du score.'
        phone_trust_index:
          type: number
          nullable: true
          description: >-
            Inverse du score, pour les tableaux de bord qui préfèrent qu'une
            valeur plus élevée soit meilleure.
        network_stability_index:
          type: number
          nullable: true
          description: Stabilité du réseau de la ligne.
        is_disposable:
          type: boolean
          nullable: true
          description: '`true` lorsque le numéro semble jetable ou virtuel.'
        is_ported:
          type: boolean
          nullable: true
          description: '`true` lorsque le numéro a changé d''opérateur.'
        is_recently_ported:
          type: boolean
          nullable: true
          description: '`true` lorsque la portabilité a eu lieu récemment.'
        carrier_type:
          type: string
          nullable: true
          description: >-
            Classification de la ligne signalée par la recherche (par exemple,
            `mobile`).
        reason_codes:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
                description: "Identifiant Didit stable du signal, par exemple `IR-5AC67A32`. Opaque\_: utilisez-le pour regrouper et filtrer, ne l'interprétez pas."
              value:
                nullable: true
                description: >-
                  Pour un indicateur de risque (par exemple `voip`, `leaked`,
                  `disposable`, `spam_trap`), sa valeur : un booléen, un niveau
                  ou une date. Null pour un code de motif noté.
              direction:
                type: string
                enum:
                  - risk
                  - trust
                description: >-
                  Indique si le signal a augmenté le risque ou renforcé la
                  confiance.
              message:
                type: string
                description: Explication lisible par l'humain du signal, en anglais.
              impact_level:
                type: string
                nullable: true
                description: >-
                  Mesure dans laquelle le signal a influencé le score, par
                  exemple `low`, `medium` ou `high`.
          description: >-
            Signaux expliquant le score, chacun accompagné d'un code Didit
            stable, d'un sens, d'un message et d'un niveau d'impact. De nouveaux
            codes pouvant apparaître au fil du temps, ne rejetez pas les codes
            inconnus.
    SocialFootprintPlatform:
      type: object
      properties:
        platform:
          type: string
          description: Identifiant de plateforme.
          example: whatsapp
        category:
          type: string
          description: >-
            Catégorie de plateforme, par ex. MESSAGING, SOCIAL_MEDIA, ECOMMERCE,
            PROFESSIONAL, EMAIL_PROVIDER.
          example: MESSAGING
        scope:
          type: string
          enum:
            - global
            - local
          description: >-
            `global` pour les plateformes mondiales, `local` pour celles
            spécifiques à une région.
          example: global
    SocialFootprintCategorySummary:
      type: object
      properties:
        registered:
          type: integer
          nullable: true
          description: >-
            Plateformes de cette catégorie pour lesquelles l'inscription est
            confirmée.
          example: 2
        ratio:
          type: number
          format: float
          nullable: true
          description: >-
            Part des plateformes vérifiées de la catégorie comportant une
            inscription, de 0.0 à 1.0.
          example: 0.6667
    SocialFootprintProfile:
      type: object
      properties:
        name:
          type: string
          nullable: true
          description: Nom du profil, lorsque la plateforme en fournit un.
        photo:
          type: string
          nullable: true
          description: URL de la photo de profil, lorsque la plateforme en fournit une.
        about:
          type: string
          nullable: true
          description: >-
            Texte de présentation/biographie du profil, lorsque la plateforme en
            fournit un.
        privacy_status:
          type: string
          nullable: true
          enum:
            - PUBLIC
            - PRIVATE
            - null
          description: Visibilité du profil, lorsque la plateforme la fournit.
        business_account:
          type: boolean
          nullable: true
          description: >-
            Indique si le profil est un compte professionnel, lorsque la
            plateforme l'expose.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clé API de votre application, issue de Développeurs -> Clés API dans
        la Business Console. La clé principale dispose d'un accès complet. Une
        clé nommée peut être restreinte : aucun, lecture ou écriture par
        ressource, limitée à certains workflows ou aux sessions approuvées, à
        une liste d'adresses IP et à une date d'expiration. 401 signifie que la
        clé est incorrecte, révoquée ou expirée ; 403 signifie qu'aucune clé n'a
        été envoyée, que la clé n'a pas accès à cette ressource ou action, ou
        que la requête provient d'une adresse hors de sa liste d'IP ; 404 sur
        une route de session signifie que la session est hors des workflows ou
        des statuts de la clé. Une clé sans accès aux médias reçoit les URL
        d'images, de vidéos et de PDF à null, et une clé sans accès en écriture
        aux sessions reçoit les liens et tokens de session à null. Voir
        https://docs.didit.me/console/api-keys.

````

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