> ## 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 d'estimation de l'âge par selfie pour développeurs

> API Didit d'estimation de l'âge par IA : détection du vivant passive, sans pièce d'identité, inférence sous 2s, tarification à l'usage.



## OpenAPI

````yaml fr/openapi-25.json POST /v3/age-estimation/
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/age-estimation/:
    post:
      tags:
        - Standalone APIs
      summary: Estimation de l'âge (âge du visage + détection passive du vivant)
      description: >-
        Estimez l'âge d'une personne à partir d'une seule photo de visage et
        effectuez une vérification passive du vivant dans le même appel —
        renvoie l'`age_estimation` prédit par le modèle (en années), un `score`
        de vivacité (0–100) et un `status` `Approved`/`Declined`. L'âge est
        **prédit par le modèle à partir du visage, non vérifié par rapport à un
        document** — utilisez-le pour les contrôles d'accès par âge et les
        vérifications à faible friction, et non comme preuve légale de l'âge.


        **Fonctionnement.** L'image est analysée pour détecter les visages
        (définissez `rotate_image=true` si les captures peuvent être inclinées
        ou inversées) ; chaque visage détecté reçoit un âge estimé, et le plus
        grand visage dans le cadre détermine `age_estimation`. En parallèle, un
        modèle passif de détection du vivant évalue si la photo montre une
        personne vivante (aucun défi utilisateur requis) et détecte les attaques
        par présentation (photos de photos, écrans, masques). Pour obtenir les
        meilleurs résultats, soumettez un seul visage net, de face et bien
        éclairé par image.


        **Logique de décision.** Tout avertissement entraîne un refus : `status`
        est `Approved` uniquement lorsque le tableau `warnings` est vide. Un
        `score` de vivacité inférieur ou égal à
        `face_liveness_score_decline_threshold` (par défaut `30`) ajoute
        `LOW_LIVENESS_SCORE` ; une attaque détectée ajoute
        `LIVENESS_FACE_ATTACK` ; aucun visage trouvé par le modèle de détection
        du vivant ajoute `NO_FACE_DETECTED` ; aucun âge de visage estimable
        ajoute `AGE_NOT_DETECTED` (`age_estimation` est `null`) ; un âge estimé
        inférieur à `age_estimation_decline_threshold` (par défaut `18`) ajoute
        `AGE_BELOW_MINIMUM`. Pour les âges limites proches de votre seuil, il
        est recommandé de basculer vers une vérification basée sur un document —
        l'erreur du modèle augmente pour les visages proches de la limite.


        **Facturation.** Chaque réponse `200` consomme un crédit API Estimation
        de l'âge (déduit du crédit de votre forfait ou du solde de recharge).
        Lorsque le solde de l'organisation ne peut pas couvrir l'appel,
        l'endpoint renvoie une erreur `403` pour crédits insuffisants avant tout
        traitement d'image.


        **Persistance de la session (`save_api_request`, par défaut `true`).**
        Lorsque la valeur est `true`, l'appel est conservé sous forme de session
        de type API : il apparaît dans la Business Console, le `request_id`
        renvoyé est un identifiant de session réel que vous pouvez transmettre à
        `GET /v3/session/{sessionId}/decision/` (le résultat y est exposé dans
        `liveness_checks[]`, avec `features: ["AGE_ESTIMATION"]`), le recadrage
        du visage et l'image de référence sont stockés, l'embedding facial est
        ajouté à l'index de visages de votre application (utilisé par la
        recherche faciale et la détection de doublons), et un webhook
        `status.updated` est émis. Lorsque la valeur est `false`, rien n'est
        stocké et `request_id` est un UUID de corrélation unique qui ne peut pas
        être consulté ultérieurement.


        **Sandbox.** Les clés API de sandbox ignorent tout traitement et
        facturation : après validation de la requête (une entrée malformée
        renvoie toujours `400`), l'endpoint renvoie un payload fictif statique
        `Approved` (`age_estimation: 30`, sans avertissements), aucune session
        n'est conservée et aucun crédit n'est consommé.


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


        **Limite de débit.** Budget d'écriture partagé de 300 requêtes/min par
        clé API sur tous les endpoints POST/PATCH/DELETE ; tout dépassement
        renvoie `429`.
      operationId: post_v3age-estimation
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - user_image
              properties:
                user_image:
                  type: string
                  format: binary
                  description: >-
                    Photo de visage à analyser (par ex. un selfie). Soumettez
                    une seule photo de face avec le visage du sujet clairement
                    visible et bien éclairé. Extensions autorisées : `tiff`,
                    `jpg`, `jpeg`, `png`, `webp` (pas de PDF). Taille maximale
                    de téléversement : **5 MB** (les fichiers plus volumineux
                    sont rejetés avec une erreur `400`). Les images sont
                    automatiquement compressées à ~0,3 MB avant le traitement,
                    de sorte que de très hautes résolutions n'améliorent pas la
                    précision.
                face_liveness_score_decline_threshold:
                  type: number
                  format: float
                  default: 30
                  minimum: 0
                  maximum: 100
                  description: >-
                    Seuil de détection du vivant (0–100). Un `score` de
                    détection du vivant **inférieur ou égal** à cette valeur
                    ajoute un avertissement `LOW_LIVENESS_SCORE` et refuse la
                    vérification. Augmentez-le pour un anti-usurpation plus
                    strict ; les valeurs en dehors de 0–100 renvoient `400`.
                  example: 30
                age_estimation_decline_threshold:
                  type: integer
                  default: 18
                  minimum: 0
                  maximum: 100
                  description: >-
                    Âge estimé minimum acceptable en années. Un âge estimé
                    **inférieur** à cette valeur ajoute un avertissement
                    `AGE_BELOW_MINIMUM` et refuse la vérification. Définissez
                    `0` pour désactiver la vérification de l'âge (l'appel
                    exécute alors uniquement la détection du vivant +
                    l'estimation de l'âge sans décision basée sur l'âge).
                  example: 18
                rotate_image:
                  type: boolean
                  default: false
                  description: >-
                    Lorsque la valeur est `true`, le service teste l'image
                    fournie par incréments de 90 degrés (0, 90, 180, 270) et
                    utilise l'orientation qui produit la meilleure détection
                    faciale — utile pour les captures mobiles sans orientation
                    EXIF. Ajoute de la latence, ne l'activez donc que si vous ne
                    pouvez pas garantir des images dans le bon sens.
                  example: false
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    Lorsque la valeur est `true` (par défaut), conserve l'appel
                    sous la forme d'une session de type API — visible dans la
                    Business Console, récupérable via `GET
                    /v3/session/{sessionId}/decision/` à l'aide du `request_id`
                    renvoyé, notifiée via un webhook `status.updated`, et avec
                    le visage détecté ajouté à l'index facial de votre
                    application. Lorsque la valeur est `false`, rien n'est
                    stocké et `request_id` est un UUID éphémère servant
                    uniquement à la corrélation des réponses.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    Chaîne opaque optionnelle (votre identifiant d'utilisateur
                    interne, e-mail, UUID…) stockée sur la session persistée et
                    renvoyée dans la réponse. Utilisez-la pour corréler les
                    appels d'API avec vos propres enregistrements et pour
                    filtrer les sessions ultérieurement.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Objet JSON optionnel stocké avec la session (lorsque
                    `save_api_request=true`) et renvoyé dans la réponse. Dans
                    les requêtes multipart, envoyez-le sous forme de champ
                    textuel encodé en JSON (par ex.
                    `metadata={"flow":"age-gate"}`) — il est analysé sous forme
                    d'objet.
                  example:
                    flow: age-gate
            example:
              user_image: (binary JPEG/PNG of the selfie)
              face_liveness_score_decline_threshold: 30
              age_estimation_decline_threshold: 18
              rotate_image: false
              save_api_request: true
              vendor_data: user-123
              metadata:
                flow: age-gate
      responses:
        '200':
          description: "Estimation de l'âge et détection passive du vivant terminées. `age_estimation.age_estimation` est l'âge en années prédit par le modèle pour le plus grand visage détecté (`null` si aucun)\_; `age_estimation.score` est le score de détection passive du vivant (0–100)\_; `status` est `Approved` uniquement lorsque `warnings` est vide. Une capture de personne mineure ou usurpée renvoie tout de même `200` avec `status: \"Declined\"`\_: inspectez le corps, pas seulement le code HTTP. Lorsque `save_api_request=true`, `request_id` est l'identifiant de session enregistré."
          content:
            application/json:
              examples:
                Approved:
                  summary: Visage adulte vivant — les deux vérifications ont réussi
                  value:
                    request_id: 0c40ba43-64ab-4e2e-b4b8-7d1f12f81bc1
                    age_estimation:
                      status: Approved
                      method: PASSIVE
                      score: 97.5
                      user_image:
                        entities:
                          - age: 27.33
                            bbox:
                              - 40
                              - 40
                              - 100
                              - 100
                            confidence: 0.7177750468254089
                            gender: male
                        best_angle: 0
                      age_estimation: 27.33
                      warnings: []
                    vendor_data: user-123
                    metadata:
                      flow: age-gate
                    created_at: '2026-06-12T02:24:11.512941+00:00'
                Declined - age below threshold:
                  summary: Âge estimé inférieur à `age_estimation_decline_threshold`
                  value:
                    request_id: 9be41a6f-2f4e-4f57-92f4-b3a4f6f0a1c2
                    age_estimation:
                      status: Declined
                      method: PASSIVE
                      score: 95
                      user_image:
                        entities:
                          - age: 16.5
                            bbox:
                              - 40
                              - 40
                              - 100
                              - 100
                            confidence: 0.7177750468254089
                            gender: female
                        best_angle: 0
                      age_estimation: 16.5
                      warnings:
                        - risk: AGE_BELOW_MINIMUM
                          feature: LIVENESS
                          additional_data: null
                          log_type: error
                          short_description: Age below minimum
                          long_description: >-
                            The age of the face is below the minimum age
                            threshold for the application.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:26:40.118332+00:00'
                Declined - liveness too low:
                  summary: >-
                    Score de détection du vivant inférieur ou égal au seuil de
                    refus (usurpation possible)
                  value:
                    request_id: 5f6f2f1f-7c4f-43b9-8d62-0a8f4c2d9e77
                    age_estimation:
                      status: Declined
                      method: PASSIVE
                      score: 5
                      user_image:
                        entities:
                          - age: 25
                            bbox:
                              - 40
                              - 40
                              - 100
                              - 100
                            confidence: 0.7177750468254089
                            gender: male
                        best_angle: 0
                      age_estimation: 25
                      warnings:
                        - risk: LOW_LIVENESS_SCORE
                          feature: LIVENESS
                          additional_data: null
                          log_type: error
                          short_description: Low liveness score
                          long_description: >-
                            The liveness check resulted in a low score,
                            indicating potential use of non-live facial
                            representations or poor-quality biometric data.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:27:02.901547+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: "Identifiant de session persistante lorsque `save_api_request=true` (utilisable avec `GET /v3/session/{sessionId}/decision/`)\_; sinon un UUID de corrélation temporaire."
                  age_estimation:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          `Approved` lorsqu'aucun avertissement n'a été émis ;
                          `Declined` dans le cas contraire (chaque avertissement
                          généré par cet endpoint entraîne un refus).
                      method:
                        type: string
                        enum:
                          - PASSIVE
                        description: >-
                          Méthode de détection du vivant. Toujours `PASSIVE` sur
                          cet endpoint (image unique, aucun défi utilisateur).
                      score:
                        type: number
                        format: float
                        nullable: true
                        minimum: 0
                        maximum: 100
                        description: "Score de détection passive du vivant de 0 à 100\_— la confiance du modèle dans le fait que la photo montre une personne vivante. Comparé à `face_liveness_score_decline_threshold`\_; à ce niveau ou en dessous, l'appel est refusé avec `LOW_LIVENESS_SCORE`. `null` lorsque le modèle de détection du vivant ne renvoie aucune confiance\_— l'appel est tout de même refusé avec `LOW_LIVENESS_SCORE` car null est traité comme 0 pour la comparaison avec le seuil."
                        example: 97.5
                      user_image:
                        type: object
                        description: >-
                          Résultats de la détection faciale pour l'image
                          analysée.
                        properties:
                          entities:
                            type: array
                            description: >-
                              Une entrée par visage détecté. Vide si aucun
                              visage n'a été trouvé (dans ce cas,
                              `age_estimation` est `null` et un avertissement
                              `AGE_NOT_DETECTED` est ajouté).
                            items:
                              type: object
                              properties:
                                age:
                                  type: number
                                  format: float
                                  description: >-
                                    Âge estimé par le modèle pour ce visage, en
                                    années.
                                  example: 27.33
                                bbox:
                                  type: array
                                  items:
                                    type: integer
                                  minItems: 4
                                  maxItems: 4
                                  description: >-
                                    Boîte englobante du visage détecté sous
                                    forme de coordonnées en pixels `[x_min,
                                    y_min, x_max, y_max]` dans l'image traitée.
                                  example:
                                    - 40
                                    - 40
                                    - 100
                                    - 100
                                confidence:
                                  type: number
                                  format: float
                                  minimum: 0
                                  maximum: 1
                                  description: >-
                                    Indice de confiance de la détection faciale
                                    (0–1).
                                  example: 0.7177750468254089
                                gender:
                                  type: string
                                  description: >-
                                    Genre prédit par le modèle pour le visage
                                    détecté (`male` ou `female`). À titre
                                    informatif uniquement.
                                  example: male
                          best_angle:
                            type: integer
                            nullable: true
                            description: >-
                              Rotation (en degrés : 0, 90, 180 ou 270) ayant
                              produit la meilleure détection de visage. Non
                              nulle uniquement lorsque `rotate_image=true` a
                              corrigé l'orientation.
                            example: 0
                      age_estimation:
                        type: number
                        format: float
                        nullable: true
                        description: >-
                          Âge prédit par le modèle en années pour le **plus
                          grand** visage détecté. `null` lorsqu'aucun âge du
                          visage n'a pu être estimé (un avertissement
                          `AGE_NOT_DETECTED` est ajouté et l'appel est refusé).
                        example: 27.33
                      warnings:
                        type: array
                        description: >-
                          Vide en cas d'approbation sans réserve. Toute entrée
                          définit `status` sur `Declined`.
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              enum:
                                - NO_FACE_DETECTED
                                - LOW_LIVENESS_SCORE
                                - LIVENESS_FACE_ATTACK
                                - AGE_NOT_DETECTED
                                - AGE_BELOW_MINIMUM
                              description: >-
                                Code de risque lisible par machine.
                                `NO_FACE_DETECTED` — le modèle de détection du
                                vivant n'a trouvé aucun visage ;
                                `LOW_LIVENESS_SCORE` — `score` de détection du
                                vivant inférieur ou égal à
                                `face_liveness_score_decline_threshold` ;
                                `LIVENESS_FACE_ATTACK` — une attaque par
                                présentation (photo/écran/masque) a été détectée
                                ; `AGE_NOT_DETECTED` — aucun âge n'a pu être
                                estimé à partir du visage ; `AGE_BELOW_MINIMUM`
                                — âge estimé inférieur à
                                `age_estimation_decline_threshold`.
                                `NO_FACE_DETECTED` et `LOW_LIVENESS_SCORE` sont
                                mutuellement exclusifs — lorsqu'aucun visage
                                n'est trouvé, seul `NO_FACE_DETECTED` est émis.
                            feature:
                              type: string
                              enum:
                                - LIVENESS
                              description: >-
                                Fonctionnalité ayant émis l'avertissement.
                                Toujours `LIVENESS` sur cet endpoint.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Toujours `null` pour les avertissements
                                d'estimation de l'âge.
                            log_type:
                              type: string
                              enum:
                                - error
                              description: >-
                                Gravité. Chaque avertissement produit par cet
                                endpoint est une `error` et définit `status` sur
                                `Declined`.
                            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.
                  vendor_data:
                    type: string
                    nullable: true
                    description: Écho des `vendor_data` que vous avez envoyées, ou `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: >-
                      Écho de l'objet `metadata` que vous avez envoyé, ou
                      `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: >-
                      Horodatage ISO 8601 (UTC) du moment où la réponse a été
                      générée.
        '400':
          description: >-
            Erreur de validation. Renvoyée lorsque `user_image` est manquant,
            dépasse 5 Mo, possède une extension non prise en charge, ou
            lorsqu'un seuil est hors limites. Le corps est l'enveloppe standard
            d'erreur de champ de DRF : un tableau de messages par champ en
            cause.
          content:
            application/json:
              examples:
                Missing user image:
                  summary: '`user_image` non inclus dans les données de formulaire'
                  value:
                    user_image:
                      - No file was submitted.
                Unsupported file extension:
                  summary: Extension de fichier autre que tiff/jpg/jpeg/png/webp
                  value:
                    user_image:
                      - >-
                        File extension “txt” is not allowed. Allowed extensions
                        are: tiff, jpg, jpeg, png, webp.
                File too large:
                  summary: Le téléversement dépasse la limite de 5 MB
                  value:
                    user_image:
                      - File size should not exceed 5 MB
                Threshold out of range:
                  summary: '`face_liveness_score_decline_threshold` hors de 0–100'
                  value:
                    face_liveness_score_decline_threshold:
                      - Ensure this value is less than or equal to 100.
        '403':
          description: "Permission refusée. Renvoyé lorsque l'en-tête `x-api-key` est manquant, ainsi que lorsque le solde de l'organisation appelante ne permet pas de couvrir l'appel\_; une clé incorrecte, révoquée ou expirée renvoie `401`. Une clé manquante renvoie `403` avec `{\"detail\": ...}`\_; une clé incorrecte, révoquée ou expirée renvoie `401`. Les crédits insuffisants renvoient `403` avec `{\"error\": ...}` avant tout traitement d'image."
          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.
                Not enough credits:
                  summary: Le solde de l'organisation ne peut pas couvrir l'appel
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '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 ont un budget
            distinct de 600). La réponse comporte les en-têtes
            `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` et
            `Retry-After`.
          content:
            application/json:
              examples:
                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
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST 'https://verification.didit.me/v3/age-estimation/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -F 'user_image=@./selfie.jpg' \
              -F 'age_estimation_decline_threshold=18' \
              -F 'face_liveness_score_decline_threshold=30' \
              -F 'save_api_request=true' \
              -F 'vendor_data=user-123'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.age_estimation.estimate(
                user_image=open("user_image.jpg", "rb"),
                face_liveness_score_decline_threshold=30.0,
                age_estimation_decline_threshold=18,
                rotate_image=False,
                save_api_request=True,
                vendor_data="user-123",
                metadata={"flow": "age-gate"},
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit, { fileFromPath } from "@didit-protocol/sdk-node";

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

            const result = await didit.ageEstimation.estimate({
              user_image: await fileFromPath("user_image.jpg"),
              face_liveness_score_decline_threshold: 30.0,
              age_estimation_decline_threshold: 18,
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "age-gate" },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AgeEstimation.Estimate(ctx, didit.AgeEstimationEstimateParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tAgeEstimationDeclineThreshold:     didit.Int(18),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"age-gate\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.nio.file.Path;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.AgeEstimationEstimateParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.ageEstimation().estimate(AgeEstimationEstimateParams.builder()
                    .userImage(Path.of("user_image.jpg"))
                    .faceLivenessScoreDeclineThreshold(30.0)
                    .ageEstimationDeclineThreshold(18L)
                    .rotateImage(false)
                    .saveApiRequest(true)
                    .vendorData("user-123")
                    .metadata(Map.of("flow", "age-gate"))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;
            use Didit\File;

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

            $result = $didit->ageEstimation->estimate([
                'user_image' => File::fromPath('user_image.jpg'),
                'face_liveness_score_decline_threshold' => 30.0,
                'age_estimation_decline_threshold' => 18,
                'rotate_image' => false,
                'save_api_request' => true,
                'vendor_data' => 'user-123',
                'metadata' => ['flow' => 'age-gate'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.age_estimation.estimate(
              user_image: Pathname("user_image.jpg"),
              face_liveness_score_decline_threshold: 30.0,
              age_estimation_decline_threshold: 18,
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "age-gate" }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.AgeEstimation.EstimateAsync(new
            AgeEstimationEstimateParams

            {
                UserImage = FileUpload.FromPath("user_image.jpg"),
                FaceLivenessScoreDeclineThreshold = 30.0,
                AgeEstimationDeclineThreshold = 18,
                RotateImage = false,
                SaveApiRequest = true,
                VendorData = "user-123",
                Metadata = new Dictionary<string, object> { ["flow"] = "age-gate" },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  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.