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

# Verifica email API: ottenere le credenziali API di Didit

> Con POST /programmatic/verify-email/ confermi l'email e ricevi token di accesso, client_id e api_key di Didit. Onboarding nativo per agenti, prezzi a consumo.



Prompt per verificare l'email e ottenere le credenziali
        Copia il prompt negli appunti



      
      

\<pre>

\`Exchange the email verification code for usable Didit credentials — step 2 of programmatic onboarding.

Endpoint:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/

Authentication:
None. The email + code pair is the credential.

Request body:
\- email (string, required) — Same email used in /programmatic/register/.
\- code (string, required) — 6-character alphanumeric code from the registration email (e.g. "A3K9F2"). Valid for 15 minutes.

curl example:
curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/ \
-H "Content-Type: application/json" \
-d '{
"email": "you@yourdomain.com",
"code": "A3K9F2"
}'

Response (200 OK):
\{
"access_token": "eyJ...RS256 JWT",
"refresh_token": "eyJ...RS256 JWT",
"expires_in": 86400,
"organization": {
"uuid": "a1b2c3d4-5678-...",
"name": "you"
},
"application": {
"uuid": "b2c3d4e5-6789-...",
"name": "you",
"client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
"api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"data_location": "eu"
}
}

What happens server-side:
1\. The pending account is marked email-verified.
2\. A default organization is created (named after the local part of the email, e.g. "you" from "you@yourdomain.com").
3\. A default application is created inside the organization with a fresh client_id and api_key, in the European Union (data_location "eu"). Its location can be chosen once with PATCH /organizations/me/{org_id}/applications/{app_id}/ before the application is used; see /auth-api/update-application.
4\. JWTs are issued (RS256, default 24h / 86400 seconds lifetime).

How to use the response:
\- application.api_key → set as the x-api-key header on EVERY call to https://verification.didit.me/v3/... (sessions, workflows, questionnaires, billing, etc.). PERSIST IT SECURELY. You can read it again later with GET /organizations/me/{org_id}/applications/{app_id}/.
\- access_token → use as "Authorization: Bearer <access_token>" against Account Management endpoints on https://apx.didit.me/auth/v2 (e.g. to create more applications).
\- refresh_token → exchange for a new access_token after expiry.

Save the api_key, the organization.uuid (org_id), and the application.uuid (app_id) — you will need all three to manage applications later.

Failure modes (400 unless noted):
\- Field-level: { "email": ["Enter a valid email address."] } or { "code": ["Ensure this field has at least 6 characters."] }.
\- Wrong or expired code CURRENTLY returns a BARE ARRAY ["Invalid or expired verification code."] — known server-side inconsistency; treat as { "code": [...] } client-side.
\- Unknown email: { "detail": "User not found." }

Recovery if you lose the api_key later:
Call POST /programmatic/login/ with email + password to get a fresh access_token, then GET /organizations/me/{org_id}/applications/{app_id}/ to read the api_key back. See /auth-api/login and /auth-api/get-credentials.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`

\</pre>



      
      

Incolla in



## OpenAPI

````yaml it/openapi-auth.json POST /programmatic/verify-email/
openapi: 3.0.0
info:
  version: 1.0.0
  title: Didit Auth API
  description: >-
    API di registrazione e autenticazione programmatica per sviluppatori e
    agenti AI. Registrati in 2 chiamate API -- senza bisogno di browser. La
    piattaforma di verifica dell'identità più adatta agli agenti.


    ## Base URL


    Tutti gli endpoint di questa specifica sono ospitati su
    `https://apx.didit.me/auth/v2`. Si tratta di un host diverso rispetto a
    quello dell'API di verifica (`https://verification.didit.me/v3`).
    Distinguili chiaramente: questo host di autenticazione rilascia i tuoi
    **token di accesso JWT** e ti consente di elencare e gestire le tue
    **organizzazioni** e le tue **applicazioni**. L'host di verifica è il luogo
    in cui chiami sessioni, workflow, AML, ecc., autenticandoti con la
    **`api_key`** restituita da questa API.


    ## Come funziona il flusso di autenticazione


    1. `POST /programmatic/register/` — invia email + password.

    2. Ricevi un codice alfanumerico di 6 caratteri via email.

    3. `POST /programmatic/verify-email/` — invia il codice. Ricevi in risposta
    un `access_token` JWT, un `refresh_token`, un'organizzazione e
    un'applicazione predefinita con `client_id` + `api_key`.

    4. Salva la `api_key`. Usala come `x-api-key` per ogni chiamata a
    `https://verification.didit.me/v3/...`.

    5. Da qualsiasi macchina in futuro, `POST /programmatic/login/` scambia
    email + password con un nuovo JWT, quindi chiama `GET /organizations/me/` e
    gli endpoint dell'applicazione per recuperare o ruotare le credenziali.


    Il JWT serve solo per gli endpoint di **Gestione dell'account** in questa
    specifica; il traffico dell'API di verifica utilizza la `api_key` a lunga
    durata, non il JWT.


    ## Convenzioni


    - Tutti i corpi di richiesta e risposta sono in formato JSON (`Content-Type:
    application/json`).

    - **Usa un indirizzo email reale e recapitabile quando testi `POST
    /programmatic/register/`.** L'endpoint invia il codice di verifica in modo
    sincrono, quindi gli indirizzi su domini di test riservati (`@example.com`,
    `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) vengono rifiutati
    dalla consegna della posta e la richiesta restituisce `500`. Sostituisci il
    segnaposto `you@yourdomain.com` negli esempi con una casella di posta che
    puoi effettivamente consultare.

    - Gli errori di validazione restituiscono HTTP `400` con una delle due
    strutture: `{"field": ["message", ...]}` per problemi a livello di campo,
    oppure `{"detail": "message"}` per errori legati a regole aziendali. Alcuni
    validatori (robustezza della password in fase di registrazione, scadenza del
    codice su verify-email) attualmente rispondono con un array semplice
    `["message"]` anziché con il formato indicizzato per campo: si tratta di
    un'incoerenza nota lato server, pertanto il codice client dovrebbe accettare
    entrambi i formati.

    - Gli errori di autenticazione vengono restituiti come `{"detail": "..."}`
    con HTTP `401` (token bearer non valido) o `403` (token bearer mancante /
    autorizzazioni insufficienti).

    - Le risposte relative al limite di frequenza includono un campo `wait` con
    il tempo di attesa in secondi.
servers:
  - url: https://apx.didit.me/auth/v2
    description: Server di autenticazione di produzione
security: []
tags:
  - name: Programmatic Auth
    description: >-
      Ciclo di vita dell'account basato su email e password: registrazione,
      verifica, accesso. Restituisce il JWT `access_token` utilizzato per gli
      endpoint di gestione dell'account, oltre a (in fase di verifica)
      `client_id` e `api_key` della tua prima applicazione.
  - name: Account Management
    description: >-
      Endpoint autenticati (bearer JWT) che elencano le organizzazioni e creano,
      recuperano o aggiornano le applicazioni. Usali per recuperare o ruotare la
      `api_key` con cui autentichi le chiamate API di verifica.
paths:
  /programmatic/verify-email/:
    post:
      tags:
        - Programmatic Auth
      summary: Verifica email ed emetti credenziali
      description: >-
        Passaggio 2 dell'onboarding. Scambia il codice di 6 caratteri con un
        account verificato, un'organizzazione+app predefinita e una coppia di
        JWT. Salva la `api_key` restituita.
      operationId: programmatic_verify_email
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyEmailRequest'
            examples:
              Default:
                summary: Invia il codice ricevuto via email di registrazione
                value:
                  email: you@yourdomain.com
                  code: A3K9F2
      responses:
        '200':
          description: >-
            Email verificata. La risposta contiene i token per questa API di
            autenticazione oltre al `client_id` e alla `api_key` della nuova
            applicazione. Salva la `api_key` in modo sicuro: è la credenziale a
            lunga durata utilizzata da ogni chiamata API di verifica.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyEmailResponse'
              examples:
                Success:
                  value:
                    access_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
                    refresh_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
                    expires_in: 86400
                    organization:
                      uuid: a1b2c3d4-5678-90ab-cdef-111111111111
                      name: developer
                    application:
                      uuid: b2c3d4e5-6789-01bc-defg-222222222222
                      name: developer
                      client_id: S9LIYGSoWNuGMLHsvEt9dQ
                      api_key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                      data_location: eu
        '400':
          description: >-
            Errore di validazione. L'envelope previsto è `{"field": ["..."]}`
            per i problemi a livello di campo e `{"detail": "..."}` per gli
            errori delle regole aziendali (ad es. utente non trovato). Gli
            errori di codice errato o scaduto rispondono attualmente con un
            array semplice `["Invalid or expired verification code."]` --
            incoerenza nota lato server; trattala come `{"code": ["..."]}`
            finché non verrà corretta.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
              examples:
                MissingFields:
                  summary: Corpo vuoto
                  value:
                    email:
                      - This field is required.
                    code:
                      - This field is required.
                CodeTooShort:
                  summary: Codice di meno di 6 caratteri
                  value:
                    code:
                      - Ensure this field has at least 6 characters.
                InvalidEmail:
                  summary: Email non valida
                  value:
                    email:
                      - Enter a valid email address.
                InvalidCode:
                  summary: Codice errato o scaduto
                  value:
                    - Invalid or expired verification code.
                UserNotFound:
                  summary: Nessun account in sospeso per quell'email
                  value:
                    detail: User not found.
        '429':
          description: >-
            Il servizio sta temporaneamente verificando il maggior numero
            possibile di password o codici contemporaneamente. Inviato con
            un'intestazione `Retry-After: 5`; riprova dopo il numero di secondi
            indicato.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              examples:
                PasswordChecksBusy:
                  summary: Troppe verifiche della password in corso
                  value:
                    detail: >-
                      Too many sign-in attempts are being processed right now.
                      Please try again in a few seconds.
      security:
        - {}
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >-
            curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/
            \
              -H "Content-Type: application/json" \
              -d '{
                "email": "you@yourdomain.com",
                "code": "A3K9F2"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # This call needs no API key.
            client = Didit()

            result = client.account.verify_email(
                email="you@yourdomain.com",
                code="A3K9F2",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // This call needs no API key.
            const didit = new Didit();

            const result = await didit.account.verifyEmail({
              email: "you@yourdomain.com",
              code: "A3K9F2",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.VerifyEmail(ctx, didit.VerifyEmailRequest{\n\tEmail: \"you@yourdomain.com\",\n\tCode:  \"A3K9F2\",\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.VerifyEmailRequest;


            // This call needs no API key.

            Didit client = new Didit();


            var result =
            client.account().verifyEmail(VerifyEmailRequest.builder()
                    .email("you@yourdomain.com")
                    .code("A3K9F2")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // This call needs no API key.
            $didit = new DiditClient();

            $result = $didit->account->verifyEmail([
                'email' => 'you@yourdomain.com',
                'code' => 'A3K9F2',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # This call needs no API key.
            didit = Didit::Client.new

            result = didit.account.verify_email(
              email: "you@yourdomain.com",
              code: "A3K9F2"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // This call needs no API key.

            using var client = new DiditClient();


            var result = await client.Account.VerifyEmailAsync(new
            VerifyEmailRequest

            {
                Email = "you@yourdomain.com",
                Code = "A3K9F2",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    VerifyEmailRequest:
      type: object
      required:
        - email
        - code
      properties:
        email:
          type: string
          format: email
          description: Email utilizzata durante `POST /programmatic/register/`.
          example: you@yourdomain.com
        code:
          type: string
          minLength: 6
          maxLength: 6
          description: >-
            Codice alfanumerico di 6 caratteri proveniente dall'email di
            verifica. I codici scadono 10 minuti dopo l'invio del codice più
            recente.
          example: A3K9F2
    VerifyEmailResponse:
      type: object
      properties:
        access_token:
          type: string
          description: >-
            JWT firmato con RS256. Usa come `Authorization: Bearer <token>` per
            gli endpoint di Account Management su `apx.didit.me/auth/v2`.
        refresh_token:
          type: string
          description: Token di aggiornamento associato al token di accesso.
        expires_in:
          type: integer
          description: 'Durata del token di accesso in secondi (valore predefinito: 86400).'
          example: 86400
        organization:
          $ref: '#/components/schemas/OrganizationSummary'
        application:
          $ref: '#/components/schemas/ApplicationCredentialsSummary'
    ValidationError:
      description: >-
        Corpo dell'errore di validazione. La busta prevista è una mappa `{field:
        ["message", ...]}` per errori a livello di campo o una busta a chiave
        singola `{detail: "..."}` per errori sulle regole di business. Alcuni
        validatori (complessità della password alla registrazione, validità del
        codice in verify-email) attualmente rispondono con un array semplice
        `["message"]` -- incoerenza nota lato server. Lo schema seguente
        mantiene quel ramo con array semplice in modo che il codice client
        generato da questa specifica deserializzi le risposte correnti, ma il
        nuovo codice client dovrebbe trattarlo come la forma con chiave di campo
        pertinente (`{password: [...]}` o `{code: [...]}`) e il contratto del
        server convergerà su tale formato.
      oneOf:
        - type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            email:
              - Enter a valid email address.
        - type: object
          properties:
            detail:
              type: string
          example:
            detail: An account with this email already exists.
        - type: array
          items:
            type: string
          example:
            - Invalid or expired verification code.
    RateLimitError:
      type: object
      description: >-
        Risposta di limite di frequenza o blocco progressivo. `wait` è il tempo
        di attesa in secondi.
      properties:
        detail:
          type: string
          example: >-
            Too many login attempts from this IP address. Please wait before
            trying again.
    OrganizationSummary:
      type: object
      description: >-
        Struttura minima dell'organizzazione restituita inline da `POST
        /programmatic/verify-email/`.
      properties:
        uuid:
          type: string
          format: uuid
          example: a1b2c3d4-5678-90ab-cdef-111111111111
        name:
          type: string
          example: developer
    ApplicationCredentialsSummary:
      type: object
      description: >-
        Struttura minima dell'applicazione restituita inline da `POST
        /programmatic/verify-email/`. Salva immediatamente la `api_key`.
      properties:
        uuid:
          type: string
          format: uuid
          example: b2c3d4e5-6789-01bc-defg-222222222222
        name:
          type: string
          example: developer
        client_id:
          type: string
          example: S9LIYGSoWNuGMLHsvEt9dQ
        api_key:
          type: string
          description: >-
            Usa questo valore come `x-api-key` in ogni chiamata API di verifica.
            Le nuove chiavi iniziano con `sk_live_` (applicazione di produzione)
            o `sk_test_` (applicazione sandbox), seguite da 43 caratteri
            compatibili con gli URL (lettere, cifre, `-` e `_`). Le chiavi
            create prima di questo formato non hanno prefisso e continuano a
            funzionare invariate.
          example: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        data_location:
          $ref: '#/components/schemas/ApplicationDataLocation'
    ApplicationDataLocation:
      type: string
      enum:
        - eu
        - au
        - mx
      description: >-
        Dove vengono archiviati ed elaborati i dati di verifica
        dell'applicazione; questa posizione viene scelta al momento della
        creazione dell'applicazione. `eu` indica l'Unione Europea (Irlanda), il
        valore predefinito. `au` (Australia, Sydney) e `mx` (Messico) saranno
        presto disponibili: una richiesta che li specifica risponde con 400
        `This data location is not available yet.` L'applicazione Sandbox di
        un'organizzazione si trova sempre nell'Unione Europea.
      example: eu

````

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