> ## 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.

# Stima dell'età API: verifica dell'età tramite selfie

> Didit stima l'età con AI e liveness passivo via POST /v3/age-estimation/. Nessun documento, inferenza sotto 2 s, prezzo a consumo.



## OpenAPI

````yaml it/openapi-25.json POST /v3/age-estimation/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API di verifica dell'identità. Autenticati con l'intestazione x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/age-estimation/:
    post:
      tags:
        - Standalone APIs
      summary: Stima dell'età (età del volto + vitalità passiva)
      description: >-
        Stima l'età di una persona a partire da una singola foto del volto ed
        esegue un controllo passivo di rilevamento della vitalità nella stessa
        chiamata — restituisce l'`age_estimation` prevista dal modello (in
        anni), uno `score` di vitalità (0–100) e uno `status`
        `Approved`/`Declined`. L'età è **prevista dal modello in base al volto,
        non verificata rispetto a un documento** — utilizzala per controlli
        sull'età minima e verifiche a basso attrito, non come prova legale
        dell'età.


        **Come funziona.** L'immagine viene analizzata alla ricerca di volti
        (imposta `rotate_image=true` se le acquisizioni potrebbero essere
        ruotate o capovolte); ogni volto rilevato riceve un'età stimata e il
        volto più grande nell'inquadratura determina `age_estimation`.
        Parallelamente, un modello passivo di rilevamento della vitalità valuta
        con un punteggio se la foto mostra una persona reale (senza richiedere
        alcuna interazione all'utente) e rileva attacchi di presentazione (foto
        di foto, schermi, maschere). Per ottenere i migliori risultati, invia un
        unico volto chiaro, frontale e ben illuminato per immagine.


        **Logica di decisione.** Qualsiasi avviso comporta un rifiuto: `status`
        è `Approved` solo quando l'array `warnings` è vuoto. Uno `score` di
        vitalità pari o inferiore a `face_liveness_score_decline_threshold`
        (predefinito `30`) aggiunge `LOW_LIVENESS_SCORE`; un attacco rilevato
        aggiunge `LIVENESS_FACE_ATTACK`; nessun volto trovato dal modello di
        vitalità aggiunge `NO_FACE_DETECTED`; nessuna età del volto stimabile
        aggiunge `AGE_NOT_DETECTED` (`age_estimation` è `null`); un'età stimata
        inferiore a `age_estimation_decline_threshold` (predefinito `18`)
        aggiunge `AGE_BELOW_MINIMUM`. Le età prossime alla soglia impostata
        richiedono un fallback alla verifica basata su documenti — il margine di
        errore del modello aumenta per i volti vicini al limite.


        **Fatturazione.** Ogni risposta `200` consuma un credito API di Stima
        dell'età (scalato dai crediti del piano o dal saldo di ricarica). Quando
        il saldo dell'organizzazione non è sufficiente a coprire la chiamata,
        l'endpoint restituisce `403` con l'errore di crediti insufficienti prima
        di qualsiasi elaborazione dell'immagine.


        **Persistenza della sessione (`save_api_request`, predefinito `true`).**
        Quando è `true`, la chiamata viene salvata come sessione di tipo API:
        appare nella Business Console, il `request_id` restituito è un ID
        sessione reale che puoi passare a `GET
        /v3/session/{sessionId}/decision/` (il risultato viene esposto lì in
        `liveness_checks[]`, con `features: ["AGE_ESTIMATION"]`), il ritaglio
        del volto e l'immagine di riferimento vengono archiviati, l'embedding
        facciale viene aggiunto all'indice dei volti della tua applicazione
        (utilizzato per la ricerca facciale e il rilevamento dei duplicati) e
        viene generato un webhook `status.updated`. Quando è `false`, non viene
        memorizzato nulla e `request_id` è un UUID di correlazione una tantum
        che non può essere cercato in seguito.


        **Sandbox.** Le chiavi API sandbox ignorano qualsiasi elaborazione e
        fatturazione: dopo la validazione della richiesta (l'input non valido
        restituisce comunque `400`), l'endpoint restituisce un payload mock
        statico `Approved` (`age_estimation: 30`, nessun avviso), nessuna
        sessione viene salvata e non viene consumato alcun credito.


        **Autenticazione.** Invia la chiave API della tua applicazione
        nell'intestazione `x-api-key`. Credenziali mancanti o non valide
        restituiscono `403` (`{"detail": "You do not have permission to perform
        this action."}`) — questa API non restituisce mai `401`.


        **Limite di frequenza.** Budget condiviso di scrittura di 300
        richieste/min per chiave API su tutti gli endpoint POST/PATCH/DELETE; il
        superamento restituisce `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: >-
                    Foto del volto da analizzare (ad es. un selfie). Invia una
                    singola foto frontale con il volto del soggetto chiaramente
                    visibile e ben illuminato. Estensioni consentite: `tiff`,
                    `jpg`, `jpeg`, `png`, `webp` (nessun PDF). Dimensione
                    massima di caricamento: **5 MB** (i file più grandi vengono
                    rifiutati con `400`). Le immagini vengono compresse
                    automaticamente a circa 0,3 MB prima dell'elaborazione,
                    pertanto risoluzioni molto elevate non migliorano
                    l'accuratezza.
                face_liveness_score_decline_threshold:
                  type: number
                  format: float
                  default: 30
                  minimum: 0
                  maximum: 100
                  description: >-
                    Soglia di rilevamento della vitalità (0–100). Un punteggio
                    (`score`) di vitalità **pari o inferiore** a questo valore
                    aggiunge un avviso `LOW_LIVENESS_SCORE` e rifiuta. Aumentala
                    per un livello anti-spoofing più restrittivo; i valori non
                    compresi tra 0 e 100 restituiscono `400`.
                  example: 30
                age_estimation_decline_threshold:
                  type: integer
                  default: 18
                  minimum: 0
                  maximum: 100
                  description: >-
                    Età stimata minima accettabile in anni. Un'età stimata
                    **inferiore** a questo valore aggiunge un avviso
                    `AGE_BELOW_MINIMUM` e rifiuta la verifica. Imposta `0` per
                    disattivare il controllo dell'età (la chiamata eseguirà
                    quindi solo rilevamento della vitalità + stima dell'età
                    senza una decisione basata sull'età).
                  example: 18
                rotate_image:
                  type: boolean
                  default: false
                  description: >-
                    Quando è `true`, il servizio prova l'immagine di input con
                    incrementi di 90 gradi (0, 90, 180, 270) e utilizza
                    l'orientamento che offre il miglior rilevamento del volto;
                    utile per le acquisizioni da dispositivo mobile prive di
                    orientamento EXIF. Aggiunge latenza, quindi attivalo solo se
                    non puoi garantire immagini orientate correttamente.
                  example: false
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    Quando è `true` (predefinito), rende persistente la chiamata
                    come sessione di tipo API — visibile nella Business Console,
                    recuperabile tramite `GET /v3/session/{sessionId}/decision/`
                    utilizzando il `request_id` restituito, notificata tramite
                    un webhook `status.updated`, e con il volto rilevato
                    aggiunto all'indice dei volti della tua applicazione. Quando
                    è `false`, non viene memorizzato nulla e `request_id` è un
                    UUID temporaneo utilizzabile solo per la correlazione della
                    risposta.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    Stringa opaca opzionale (il tuo ID utente interno, email,
                    UUID...) memorizzata nella sessione persistita e restituita
                    nella risposta. Usala per correlare le chiamate API con i
                    tuoi record e per filtrare le sessioni in un secondo
                    momento.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Oggetto JSON opzionale memorizzato con la sessione (quando
                    `save_api_request=true`) e restituito nella risposta. Nelle
                    richieste multipart, invialo come campo stringa con codifica
                    JSON (ad es. `metadata={"flow":"age-gate"}`): viene
                    interpretato come oggetto.
                  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: >-
            Stima dell'età e vitalità passiva completate.
            `age_estimation.age_estimation` è l'età prevista dal modello in anni
            del volto più grande rilevato (`null` se assente);
            `age_estimation.score` è il punteggio di vitalità passiva (0–100);
            `status` è `Approved` solo quando `warnings` è vuoto.
            Un'acquisizione di un minore o contraffatta restituisce comunque
            `200` con `status: "Declined"` — ispeziona il corpo della risposta,
            non solo il codice HTTP. Quando `save_api_request=true`,
            `request_id` è l'ID di sessione persistito.
          content:
            application/json:
              examples:
                Approved:
                  summary: Volto adulto dal vivo — entrambi i controlli superati
                  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: Età stimata inferiore a `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: >-
                    Punteggio di rilevamento della vitalità pari o inferiore
                    alla soglia di rifiuto (possibile spoofing)
                  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: >-
                      ID della sessione salvata quando `save_api_request=true`
                      (utilizzabile con `GET
                      /v3/session/{sessionId}/decision/`); altrimenti un UUID di
                      correlazione temporaneo.
                  age_estimation:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          `Approved` quando non è stato generato alcun avviso;
                          altrimenti `Declined` (ogni avviso generato da questo
                          endpoint comporta un rifiuto).
                      method:
                        type: string
                        enum:
                          - PASSIVE
                        description: >-
                          Metodo di rilevamento della vitalità. Sempre `PASSIVE`
                          su questo endpoint (immagine singola, nessuna verifica
                          interattiva dell'utente).
                      score:
                        type: number
                        format: float
                        nullable: true
                        minimum: 0
                        maximum: 100
                        description: >-
                          Punteggio del rilevamento passivo della vitalità da 0
                          a 100: il livello di affidabilità del modello che la
                          foto mostri una persona viva. Confrontato con
                          `face_liveness_score_decline_threshold`; se pari o
                          inferiore, la chiamata viene rifiutata con
                          `LOW_LIVENESS_SCORE`. È `null` quando il modello di
                          rilevamento della vitalità non restituisce alcuna
                          affidabilità: la chiamata viene comunque rifiutata con
                          `LOW_LIVENESS_SCORE` poiché null viene trattato come 0
                          per il confronto con la soglia.
                        example: 97.5
                      user_image:
                        type: object
                        description: >-
                          Risultati del rilevamento facciale per l'immagine
                          analizzata.
                        properties:
                          entities:
                            type: array
                            description: >-
                              Una voce per ogni volto rilevato. Vuoto se non è
                              stato trovato alcun volto (in tal caso
                              `age_estimation` è `null` e viene aggiunto un
                              avviso `AGE_NOT_DETECTED`).
                            items:
                              type: object
                              properties:
                                age:
                                  type: number
                                  format: float
                                  description: >-
                                    Età stimata dal modello per questo volto, in
                                    anni.
                                  example: 27.33
                                bbox:
                                  type: array
                                  items:
                                    type: integer
                                  minItems: 4
                                  maxItems: 4
                                  description: >-
                                    Riquadro di delimitazione del volto rilevato
                                    come coordinate in pixel `[x_min, y_min,
                                    x_max, y_max]` nell'immagine elaborata.
                                  example:
                                    - 40
                                    - 40
                                    - 100
                                    - 100
                                confidence:
                                  type: number
                                  format: float
                                  minimum: 0
                                  maximum: 1
                                  description: Affidabilità del rilevamento facciale (0–1).
                                  example: 0.7177750468254089
                                gender:
                                  type: string
                                  description: >-
                                    Genere previsto dal modello per il volto
                                    rilevato (`male` o `female`). Solo a scopo
                                    informativo.
                                  example: male
                          best_angle:
                            type: integer
                            nullable: true
                            description: >-
                              Rotazione (gradi: 0, 90, 180 o 270) che ha
                              prodotto il miglior rilevamento del volto. Diversa
                              da zero solo quando `rotate_image=true` ha
                              corretto l'orientamento.
                            example: 0
                      age_estimation:
                        type: number
                        format: float
                        nullable: true
                        description: >-
                          Età stimata dal modello in anni per il volto rilevato
                          **più grande**. `null` quando non è stato possibile
                          stimare l'età del volto (viene aggiunto un avviso
                          `AGE_NOT_DETECTED` e la chiamata viene rifiutata).
                        example: 27.33
                      warnings:
                        type: array
                        description: >-
                          Vuoto in caso di approvazione senza anomalie.
                          Qualsiasi voce imposta `status` su `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: >-
                                Codice di rischio leggibile dalla macchina.
                                `NO_FACE_DETECTED` — il modello di vitalità non
                                ha rilevato alcun volto; `LOW_LIVENESS_SCORE` —
                                `score` di vitalità pari o inferiore a
                                `face_liveness_score_decline_threshold`;
                                `LIVENESS_FACE_ATTACK` — è stato rilevato un
                                attacco di presentazione
                                (foto/schermo/maschera); `AGE_NOT_DETECTED` —
                                non è stato possibile stimare l'età del volto;
                                `AGE_BELOW_MINIMUM` — età stimata inferiore a
                                `age_estimation_decline_threshold`.
                                `NO_FACE_DETECTED` e `LOW_LIVENESS_SCORE` si
                                escludono a vicenda: se non viene trovato alcun
                                volto, viene emesso solo `NO_FACE_DETECTED`.
                            feature:
                              type: string
                              enum:
                                - LIVENESS
                              description: >-
                                Funzionalità che ha generato l'avviso. Sempre
                                `LIVENESS` su questo endpoint.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Sempre `null` per gli avvisi relativi alla stima
                                dell'età.
                            log_type:
                              type: string
                              enum:
                                - error
                              description: >-
                                Gravità. Ogni avviso generato da questo endpoint
                                è un `error` e imposta `status` su `Declined`.
                            short_description:
                              type: string
                              description: >-
                                Riepilogo del rischio su una riga leggibile
                                dall'utente.
                            long_description:
                              type: string
                              description: Spiegazione di facile lettura del rischio.
                  vendor_data:
                    type: string
                    nullable: true
                    description: Eco del `vendor_data` inviato, o `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: Eco dell'oggetto `metadata` inviato, o `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: Timestamp ISO 8601 (UTC) di generazione della risposta.
        '400':
          description: >-
            Errore di validazione. Restituito quando `user_image` è mancante,
            supera 5 MB, ha un'estensione non supportata o quando una soglia è
            fuori intervallo. Il corpo è l'envelope standard degli errori di
            campo di DRF: un array di messaggi per ciascun campo interessato.
          content:
            application/json:
              examples:
                Missing user image:
                  summary: '`user_image` non incluso nei dati del modulo'
                  value:
                    user_image:
                      - No file was submitted.
                Unsupported file extension:
                  summary: Estensione del file diversa da 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: Il caricamento supera il limite di 5 MB
                  value:
                    user_image:
                      - File size should not exceed 5 MB
                Threshold out of range:
                  summary: '`face_liveness_score_decline_threshold` al di fuori di 0–100'
                  value:
                    face_liveness_score_decline_threshold:
                      - Ensure this value is less than or equal to 100.
        '403':
          description: >-
            Autorizzazione negata. Restituito quando l'intestazione `x-api-key`
            è mancante e anche quando il saldo dell'organizzazione chiamante non
            è sufficiente a coprire la chiamata; una chiave errata, revocata o
            scaduta restituisce `401`. Una chiave mancante restituisce `403` con
            `{"detail": ...}`; una chiave errata, revocata o scaduta restituisce
            `401`. Crediti insufficienti restituiscono `403` con `{"error":
            ...}` prima che avvenga qualsiasi elaborazione delle immagini.
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: >-
                    Nessuna intestazione `x-api-key`, oppure la chiave non è
                    valida/revocata
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: >-
                    Il saldo dell'organizzazione non è sufficiente per coprire
                    la chiamata
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            Limite di frequenza superato. Gli endpoint POST/PATCH/DELETE
            condividono un budget di 300 richieste di scrittura al minuto per
            chiave API (la creazione di transazioni e l'ingestione di eventi
            hanno un budget separato di 600). La risposta contiene le
            intestazioni `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
            `X-RateLimit-Reset` e `Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: Più di 300 richieste di scrittura nel minuto corrente
                  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 chiave API della tua applicazione, da Developers -> API keys nella
        Business Console. La chiave primaria ha accesso completo. Una chiave con
        nome può avere un ambito definito: nessuno, lettura o scrittura per
        risorsa, limitata ad alcuni workflow o a sessioni approvate, a un elenco
        di indirizzi IP e a una data di scadenza. 401 indica che la chiave è
        errata, revocata o scaduta; 403 indica che non è stata inviata alcuna
        chiave, che la chiave non ha accesso a questa risorsa o azione, oppure
        che la richiesta proviene da un indirizzo non incluso nel suo elenco IP;
        404 su una route di sessione indica che la sessione non rientra nei
        workflow o negli stati previsti dalla chiave. Una chiave senza accesso
        ai media riceve gli URL di immagini, video e PDF come null, e una chiave
        senza permessi di scrittura sulle sessioni riceve link e token di
        sessione come null. Consulta https://docs.didit.me/console/api-keys.

````

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