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

# Registrazione programmatica: API KYC per agenti AI

> Registrati e ottieni le credenziali API di Didit in 2 chiamate, senza browser. Verifica KYC nativa per agenti Cursor, Claude e Devin.

## Panoramica

Didit è la **piattaforma di verifica dell'identità più adatta agli agenti**. Gli agenti di programmazione basati sull'IA (Cursor, Claude Code, GitHub Copilot, Devin, OpenHands, Codex) possono registrarsi, configurare workflow e avviare verifiche dell'identità, tutto in modo programmatico e senza mai aprire un browser.

**Perché agli agenti piace Didit:**

* **2 chiamate API** dal punto di partenza alle credenziali (registrazione + verify-email).
* **Nessun browser richiesto**: completamente senza interfaccia grafica, ideale per CI/CD e per i workflow degli agenti.
* **Nessun secondo fattore per un nuovo account API**: i token vengono restituiti subito dopo la verifica dell'email.
* **Organizzazione e applicazione create automaticamente**, con `api_key` nella risposta della verifica.
* **API di gestione completa**: configura workflow, questionari, liste e fatturazione, tutto via API.
* **Server MCP** disponibile: gli agenti possono scoprire e usare gli strumenti di Didit in modo nativo.

Il contratto completo è pubblicato come [openapi-auth.json](https://docs.didit.me/openapi-auth.json); gli endpoint riportati di seguito sono verificati rispetto ad esso.

## URL di base

Tutti gli endpoint di questa guida si trovano sull'**host di autenticazione**:

```
https://apx.didit.me/auth/v2
```

Si tratta di un host diverso dall'API di verifica (`https://verification.didit.me/v3`). L'host di autenticazione emette i token di accesso JWT e gestisce le applicazioni. L'host di verifica gestisce sessioni, AML, workflow ecc., ed è autenticato con la `api_key` a lunga durata che ottieni con questo flusso.

## Avvio rapido

> [!WARNING]
>
> **Usa un indirizzo email reale e recapitabile.** L'endpoint invia il codice di verifica in modo sincrono, quindi i domini di test riservati (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) vengono rifiutati dal sistema di recapito e la chiamata restituisce un `500`. Sostituisci il segnaposto `you@yourdomain.com` qui sotto con una casella di posta che puoi leggere.

### Passaggio 1: Registrazione

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

**Risposta** (`201 Created`):

```json theme={null}
{
  "message": "Registration successful. Check your email for the verification code.",
  "email": "you@yourdomain.com"
}
```

Un codice di verifica alfanumerico di 6 caratteri (ad es. `A3K9F2`) viene inviato via email all'indirizzo. **Il codice scade 10 minuti dopo l'invio**: se scade, richiama questo endpoint con la stessa email e la stessa password. Per un account non ancora verificato restituisce `200` con `"A new verification code has been sent to your email."` e un nuovo codice. Anche l'endpoint dedicato `POST /programmatic/resend-otp/` (corpo: `{"email", "password"}`) reinvia il codice, con un intervallo di 60 secondi tra un invio e l'altro; entrambi gli endpoint condividono il limite di frequenza per la registrazione descritto sotto.

### Passaggio 2: Verifica del codice e ottenimento delle credenziali

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

**Risposta** (`200 OK`):

```json theme={null}
{
  "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"
  }
}
```

Ora hai tutto ciò che ti serve. Conserva `application.api_key` in modo sicuro e inviala come intestazione `x-api-key` in ogni chiamata all'API di verifica.

> [!NOTE]
>
> I token sono **JWT firmati RS256**. `expires_in` vale per impostazione predefinita **86400 secondi (24 ore)**. Il token di accesso serve solo per gli endpoint di gestione su `apx.didit.me/auth/v2`: il traffico dell'API di verifica su `verification.didit.me/v3` viene autenticato con la `api_key` a lunga durata, non con il JWT.

### Passaggio 3: Usa l'API

```bash theme={null}
curl https://verification.didit.me/v3/sessions/ \
  -H "x-api-key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

## Accessi successivi

Da qualsiasi macchina, scambia la tua email e la tua password con un nuovo JWT:

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

Restituisce direttamente `access_token` e `refresh_token`, senza browser. Da lì, richiama `GET /organizations/me/` per scoprire il tuo `org_id` (l'`uuid` dell'organizzazione), poi `GET /organizations/me/{org_id}/applications/` per elencare le applicazioni dell'organizzazione (l'`uuid` di ogni voce è un `app_id`), e infine `GET /organizations/me/{org_id}/applications/{app_id}/` per recuperare la `api_key`.

> [!NOTE]
>
> Gli account creati nella console con email e password possono usare anche `POST /programmatic/login/` dopo la verifica dell'email. Gli account della console che usano solo OAuth devono impostare una password prima di poter usare questo endpoint di accesso senza interfaccia grafica.

### Quando l'accesso richiede altro

`POST /programmatic/login/` restituisce token solo quando l'account non ha un secondo fattore.
Sono possibili altre tre risposte, che un agente che automatizza l'accesso deve gestire:

| Account | Risposta |
| - | - |
| Ha un'app di autenticazione o una passkey | `200` con `{"2fa_required": true, "temp_token": "...", "has_passkeys": true, "has_authenticator": false}` e nessun token |
| La sua organizzazione applica SSO | `403` con `{"error": "sso_required", "message": "...", "organization_name": "...", "organization_slug": "...", "sso_url": "/sso/<slug>"}` |
| È stato recuperato e non ha ancora un metodo di accesso | `403` con `"code": "recovery_setup_required"`, e un link per configurarne uno viene inviato all'indirizzo dell'account |

Una chiave API non richiede l'accesso, quindi usala per qualsiasi operazione automatizzata: un account con un secondo fattore non può completare l'accesso tramite questo endpoint.

## Requisiti della password

Applicati lato server, **una regola alla volta**: al primo errore la verifica si interrompe e viene restituito un array semplice, ad esempio `["Password must contain at least one uppercase letter."]`. (Gli altri errori di validazione su questo endpoint usano la struttura `{"password": [...]}` con chiave di campo. La forma ad array semplice sulle regole di robustezza della password è una nota incongruenza lato server; nel codice client trattala come `{"password": [...]}`.)

| Regola | Dettaglio |
| - | - |
| Lunghezza minima | 8 caratteri |
| Lettera maiuscola | Almeno una `A–Z` |
| Lettera minuscola | Almeno una `a–z` |
| Cifra | Almeno una `0–9` |
| Carattere speciale | Almeno uno tra `!@#$%^&*()_+-=[]{}\|;:,.<>?` |

## Limiti di frequenza e blocchi

Tre controlli indipendenti proteggono l'host di autenticazione. Ognuno di essi può generare una risposta `429`; l'intestazione di risposta `Retry-After` indica per quanto tempo attendere prima di riprovare.

| Superficie | Limite |
| - | - |
| Registrazione | **5** tentativi per **IP** all'**ora** (condivisi con `POST /programmatic/resend-otp/`). |
| Verifica email | **10** tentativi di codice per **email** all'**ora** e **50** per **IP** di origine all'**ora**, più un backoff esponenziale tra un tentativo e l'altro (30 s, raddoppiato a ogni errore, con un massimo di 1 ora). |
| Accesso (IP) | **20** tentativi per **IP** al **minuto** e **100** per **IP** all'**ora**. |
| Accesso (email) | Blocco progressivo dell'account: **5** errori consecutivi → blocco di 15 min; **10** → 1 ora; **20** → 24 ore. |

Il corpo di una risposta `429` ha questo aspetto:

```json theme={null}
{ "detail": "Too many login attempts from this IP address. Please wait before trying again." }
```

I limiti di frequenza dell'API di verifica (ad esempio 600 sessioni/min) sono indipendenti e documentati in [Limitazione della frequenza](https://docs.didit.me/it/integration/rate-limiting.md).

## Gestione delle applicazioni

Una volta autenticato, puoi recuperare, creare o aggiornare le applicazioni all'interno della tua organizzazione.

Questa soluzione è ideale per i **rivenditori** che vogliono un'applicazione per ogni cliente. Ogni applicazione ha il proprio `client_id`, `api_key`, metadati e impostazioni. È utile anche quando la tua organizzazione ha prodotti, marchi, regioni, ambienti o casi d'uso diversi che vuoi tenere separati.

```bash theme={null}
# 1. Discover your org_id
curl https://apx.didit.me/auth/v2/organizations/me/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 2. List the organization's applications (each entry's uuid is an app_id)
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 3. Create an application for a customer, product, or environment
curl -X POST "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Customer App",
    "website_url": "https://acme.example",
    "redirect_uris": ["https://acme.example/callback"],
    "terms_url": "https://acme.example/terms",
    "privacy_url": "https://acme.example/privacy"
  }'

# 4. Recover credentials (client_id + api_key) for an existing application
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 5. Update application metadata (PATCH — uuid, client_id, api_key never change)
curl -X PATCH "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Production App",
    "website_url": "https://app.acme.example"
  }'
```

Per elencare, creare o aggiornare le applicazioni, l'utente deve essere **proprietario** o **amministratore** dell'organizzazione di destinazione; in caso contrario la risposta è `403`.

## Cosa possono fare gli agenti dopo la registrazione?

Con la `api_key`, gli agenti hanno accesso completo all'API di verifica. Endpoint sottoposti ad audit su `https://verification.didit.me/v3`:

| API | Cosa fa |
| - | - |
| `POST /v3/session/` | Crea una sessione di verifica. |
| `GET /v3/sessions/` | Elenca le sessioni. |
| `GET /v3/session/{id}/decision/` | Ottiene la decisione V3 (array al plurale: vedi Modelli di dati). |
| `GET /v3/workflows/` | Elenca i workflow di verifica. |
| `GET /v3/questionnaires/` | Elenca i questionari personalizzati. |
| `GET /v3/users/` | Elenca gli utenti finali (indicizzati da `vendor_data`). |
| `GET /v3/billing/balance/` | Controlla il saldo crediti. |
| `POST /v3/billing/top-up/` | Ricarica i crediti. |
| `GET /v3/webhook/destinations/` | Gestisce le destinazioni webhook (elenca / crea / aggiorna / elimina). |

Per l'elenco completo, consulta il [riferimento dell'API di gestione](https://docs.didit.me/it/sessions-api/management-api.md).

## Integrazione con il server MCP

Per la migliore esperienza con gli agenti, usa il server MCP Didit ospitato su `https://mcp.didit.me/mcp`. Non richiede una chiave API: alla prima connessione il tuo client apre il browser, tu **Accedi con Didit** (OAuth 2.1 con PKCE) e il server agisce per conto tuo, con i permessi del ruolo che hai nella console. I client con supporto nativo per MCP remoto (Cursor, VS Code) usano questa voce; Claude web e Desktop la aggiungono come connettore personalizzato:

```json theme={null}
{
  "mcpServers": {
    "didit": {
      "url": "https://mcp.didit.me/mcp"
    }
  }
}
```

Claude Code: `claude mcp add --transport http didit https://mcp.didit.me/mcp`. I client che supportano solo stdio (Windsurf, Zed) passano dal bridge `mcp-remote`, che esegue il flusso OAuth al posto tuo.

La chiave API che ricevi dal flusso di registrazione descritto sopra serve per chiamare la REST API dal tuo backend; MCP non la usa mai. Per i dettagli, consulta la [panoramica MCP](https://docs.didit.me/it/integration/mcp/overview.md) e l'[installazione per client](https://docs.didit.me/it/integration/mcp/installation.md).

## Riferimento della struttura degli errori

Tutti gli endpoint `apx.didit.me/auth/v2` condividono le stesse tre strutture di risposta (vedi `openapi-auth.json`):

* **Validazione a livello di campo**: `{"field": ["message", ...]}` con HTTP `400`.
* **Validazione a livello di modulo** (in particolare per la robustezza della password e per gli errori del codice di verifica): array semplice `["Invalid or expired verification code."]` con HTTP `400`.
* **Autenticazione / regole di business**: `{"detail": "..."}` con `400`, `401`, `403`, `404` o `429`. Le risposte `429` includono l'intestazione `Retry-After`, che indica per quanto tempo attendere prima di riprovare (il corpo contiene solo `detail`).

L'host di verifica restituisce gli errori come `{"detail": "..."}` e le risposte 429 includono `X-RateLimit-*` e `Retry-After`: vedi [Limitazione della frequenza](https://docs.didit.me/it/integration/rate-limiting.md).


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