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

# Endpoint token: scambio codice e aggiornamento | Didit

> POST /token/ scambia un codice di autorizzazione PKCE o ruota un refresh token in Didit. Riutilizzare un refresh token revoca la sessione.

> [!WARNING]
>
> L'autenticazione è una nuova funzionalità. Questi endpoint sono forniti dall'emittente della tua applicazione, ad esempio `https://<name>.auth.didit.me`, e non accettano mai la tua chiave API di Didit.

Un token di aggiornamento funziona una sola volta. Inviare di nuovo un token di aggiornamento già usato revoca l'intera sessione, quindi esegui un solo aggiornamento alla volta per sessione e sostituisci insieme tutti e tre i token. Vedi [Token di aggiornamento](https://docs.didit.me/it/authentication/tokens-and-jwks.md#refresh-token).


## OpenAPI

````yaml it/openapi-authentication.json POST /token/
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Gli endpoint lato server di Didit Authentication, il prodotto di accesso per
    gli utenti finali della tua applicazione. Authentication è una funzionalità
    **nuova** e raggiungerà l'ambiente di produzione nella release 2026-11-01.


    ## URL di base


    Ogni applicazione è un proprio emittente OpenID Connect e ogni endpoint
    indicato di seguito è servito alla radice di tale emittente:


    - `https://<name>.auth.didit.me` per un'applicazione di produzione, o
    `https://<name>.sandbox.auth.didit.me` per un'applicazione sandbox.

    - Il tuo dominio personalizzato, una volta attivo. Quest'ultimo sostituisce
    quindi l'host predefinito come emittente: i nuovi token lo indicano in
    `iss`, la discovery punta ad esso e la chiave pubblicabile cambia. I token
    di accesso emessi sotto l'host predefinito falliscono su `/session/`,
    `/step-up/` e `/monitoring-token/` fino al loro rinnovo.


    L'ambiente di produzione e la sandbox sono applicazioni separate, quindi
    sono emittenti separati con chiavi separate. La chiave pubblicabile è
    `pk_live_` (produzione) o `pk_test_` (sandbox) seguita dalla codifica
    base64url senza padding dell'emittente, senza barra finale: decodificala per
    trovare l'emittente. Si tratta di un identificatore pubblico, non di una
    credenziale.


    Gli stessi endpoint JSON sono serviti anche sotto
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`. I token
    indicano sempre l'emittente sopra descritto, indipendentemente
    dall'indirizzo che li ha emessi.


    ## Credenziali


    Questi endpoint non richiedono mai la tua chiave API Didit o un token della
    console.


    - La discovery, il JWKS e `POST /token/` non richiedono credenziali. I
    client sono pubblici: non esiste alcun segreto client e il codice di
    autorizzazione è associato al relativo verificatore PKCE (`S256`).
    `client_id` è l'ID della tua applicazione.

    - `/session/`, `/step-up/` e `/monitoring-token/` richiedono il token di
    accesso della persona: `Authorization: Bearer <access_token>`. Ogni chiamata
    riuscita conta come attività sulla sessione, quindi azzera e riavvia il
    timeout di inattività della sessione.


    ## Body della richiesta


    Ogni endpoint che accetta un body supporta formati JSON, form-encoded e
    multipart. Questo documento elenca JSON, oltre al formato form-encoded per
    `POST /token/` come inviato dai client OAuth. Un campo non accettato
    dall'endpoint restituisce `400 {"<field>": "unknown_field"}`.


    ## Token


    - **Token di accesso**: un JWT ES256 con intestazione `typ: at+jwt`, valido
    per un massimo di 5 minuti e mai più a lungo della relativa sessione. Claim:
    `AccessTokenClaims`.

    - **ID token**: un JWT ES256 con intestazione `typ: JWT`. Claim:
    `IDTokenClaims`. Non viene mai accettato come token di accesso.

    - **Refresh token**: una stringa casuale che ruota a ogni utilizzo. L'invio
    di un refresh token già utilizzato revoca la sessione.


    Verifica un token con le chiavi restituite da `GET /.well-known/jwks.json`:
    l'algoritmo deve essere `ES256`, `typ` deve corrispondere al tipo di token,
    `iss` deve coincidere con l'emittente configurato e `aud` con l'ID della tua
    applicazione. La verifica offline rileva una sessione revocata solo dopo la
    scadenza del relativo token di accesso; `GET /session/` è il controllo
    istantaneo.


    ## Errori


    | Body | Quando |

    | --- | --- |

    | `{"error": "<code>"}` | Errori restituiti da `POST /token/`, tutti con
    stato `400`, nella struttura del body definita dalla sezione 5.2 della [RFC
    6749](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client` e l'errore `mfa_required` di Didit. Errori del servizio:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` o `{"<field>": "<code>"}` | La convalida di
    un campo della richiesta non è riuscita. `non_field_errors` indica una
    regola applicata su più campi e `unknown_field` un campo non accettato
    dall'endpoint. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (applicazione o step-up sconosciuto) e `429`
    (limite di frequenza). Anche `400` per un body che non può essere analizzato
    (`JSON parse error - ...`), `405` per un metodo non gestito dall'endpoint e
    `415` per un `Content-Type` non supportato. |


    Uno stato `401` include inoltre l'intestazione `WWW-Authenticate: Bearer`,
    mentre un `429` include `Retry-After` in secondi.


    Due tipi di rifiuto non restituiscono JSON. Un indirizzo che non corrisponde
    a un emittente viene rifiutato prima di raggiungere questi endpoint, ad
    esempio con un `404` vuoto per un nome `*.auth.didit.me` non utilizzato. Un
    parametro `step_up_id` che non è un UUID restituisce una pagina `404`.


    ## Limiti di frequenza


    Una richiesta deve superare due livelli.


    **Limiti dell'endpoint**, conteggiati per indirizzo IP del client, per
    applicazione e per endpoint:


    - Discovery e JWKS: 1.200 richieste al minuto e 12.000 all'ora.

    - Tutti gli altri endpoint: 30 richieste al minuto e 300 all'ora. `GET` e
    `DELETE /session/` condividono un unico conteggio.


    Al superamento di un limite: `429 {"detail": "Too many requests from this IP
    address. Please wait before trying again. Expected available in 60
    seconds."}`, oppure `3600 seconds` per il limite orario.


    **Protezione bot**, attiva su ogni `POST` e `DELETE`. I suoi bucket sono
    condivisi da tutte le richieste `POST` e `DELETE` dell'applicazione, inclusi
    i passaggi di accesso ospitati, e si ricaricano continuamente:


    - 60 richieste al minuto per indirizzo IP del client.

    - 30 richieste al minuto per dispositivo, per le richieste che identificano
    il dispositivo, come fanno gli SDK per browser e nativi.

    - 3.000 richieste al minuto per l'intera applicazione, considerando tutti
    gli indirizzi IP. I rinnovi dei token (`POST /token/` con
    `grant_type=refresh_token`) attingono invece a un bucket dedicato: 6.000 al
    minuto per l'intera applicazione.


    Al superamento di un bucket: `429 {"detail": "rate_limited Expected
    available in N seconds."}` (`1 second.` quando N è 1). Il bucket per IP si
    applica a diversi endpoint, quindi un singolo indirizzo che combina chiamate
    di token, step-up e disconnessione può esaurirlo prima di raggiungere il
    limite del singolo endpoint. Il bucket dell'applicazione conteggia ogni
    client dell'applicazione, inclusi i browser.


    Entrambi i livelli rispondono prima che l'endpoint venga eseguito, quindi
    una richiesta che ha ricevuto un codice `429` non è stata elaborata:
    effettua un nuovo tentativo dopo il tempo indicato in `Retry-After`, rinnovo
    incluso.


    ## Richieste del browser


    Una richiesta contenente un'intestazione `Origin` deve provenire da una
    delle origini dell'applicazione o dalle sue origini consentite, altrimenti
    riceve `403 origin_not_allowed`. Le richieste da server a server non inviano
    alcun `Origin`.


    ## Non trattati in questa sezione


    Questi percorsi servono le pagine ospitate, gli SDK nativi e per browser e
    gli agenti IA. Non fanno parte del contratto server e gli SDK server non li
    chiamano:


    - Passaggi di accesso: `POST /authorize/`, `POST /password/`, `/email/*`,
    `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`, `/social/*` e
    `/protection/complete/`.

    - Pagine ospitate e callback: `/sign-in`, `/magic`, `/invite`, `/reset`,
    `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/` e i file di associazione
    delle app native sotto `/.well-known/`.

    - Accesso agenti: `/agents/*` e `/grants/`, compreso `GET /agents/session/`,
    il controllo in tempo reale del token di accesso di un agente IA. L'accesso
    degli agenti non fa parte di questa versione del contratto.

    - L'API di gestione della console per Authentication, che accetta sessioni
    della console.


    Gli eventi di Authentication non vengono ancora inviati come webhook,
    pertanto questo documento non definisce alcun webhook.
servers:
  - url: https://{issuer}
    description: 'L''emittente (issuer) della tua applicazione: la sua origine di accesso.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          L'host dell'emittente: `<name>.auth.didit.me` (produzione),
          `<name>.sandbox.auth.didit.me` (sandbox) o il tuo dominio
          personalizzato attivo.
security: []
tags:
  - name: Issuer
    description: Chiavi di discovery e di firma, per verificare i token.
  - name: Tokens
    description: I grant di tipo authorization code e refresh.
  - name: Sessions
    description: Verifica e termina la sessione associata a un token di accesso.
  - name: Step-ups
    description: Verifica prima di un'azione sensibile.
  - name: Monitoring
    description: >-
      Credenziali del dispositivo per gli eventi di monitoraggio delle
      transazioni.
paths:
  /token/:
    post:
      tags:
        - Tokens
      summary: Scambia un codice o rinnova i token
      description: >-
        L'endpoint del token, per entrambi i grant.


        - `authorization_code` scambia il codice ricevuto dal tuo `redirect_uri`
        con un token di accesso, un token ID e un token di aggiornamento. Il
        codice funziona una sola volta, entro 60 secondi, con il verificatore
        PKCE e l'esatto `redirect_uri` del relativo accesso. Quando
        l'applicazione consente una sola sessione per persona, lo scambio
        termina le altre sessioni della persona.

        - `refresh_token` restituisce un nuovo token di accesso, un nuovo token
        ID e un nuovo token di aggiornamento, e il token di aggiornamento
        inviato smette di funzionare. **Inviare nuovamente un token di
        aggiornamento già utilizzato revoca la sessione** e restituisce
        `invalid_grant`, quindi esegui un solo aggiornamento alla volta per
        sessione e sostituisci tutti e tre i token insieme. Dopo che un
        aggiornamento fallisce con `400`, o non riceve risposta, riavvia
        l'accesso anziché riprovare: un nuovo tentativo dopo un aggiornamento
        riuscito costituisce un riutilizzo. Una risposta `429` viene restituita
        prima che l'aggiornamento venga eseguito, quindi è sicuro riprovare dopo
        `Retry-After`. Un errore `503` indica che l'aggiornamento non è avvenuto
        e il token di aggiornamento funziona ancora: riprova con backoff.


        Il corpo può essere in formato JSON o con codifica form.
      operationId: authentication_token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenRequest'
            examples:
              AuthorizationCode:
                summary: Scambia il codice di autorizzazione
                value:
                  grant_type: authorization_code
                  code: Vb0bVt4CLlr8ZL0kE5mAxv8gS6R0rW3hYqC1pN7dJ2s
                  code_verifier: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
                  redirect_uri: https://app.example.com/auth/callback
              RefreshToken:
                summary: Aggiorna i token
                value:
                  grant_type: refresh_token
                  refresh_token: >-
                    N4yZTl6y24YKYq77X_SOrBn1q2Lit81WBQMOay7dq_IVfTnxyY8ZGcJk-6-fcmWW
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TokenRequest'
      responses:
        '200':
          description: Nuovi token per la sessione.
          headers:
            Cache-Control:
              description: >-
                Sempre `no-store`: non memorizzare mai nella cache questa
                risposta.
              schema:
                type: string
                example: no-store
            Pragma:
              description: Sempre `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
              examples:
                Tokens:
                  summary: Token per una nuova sessione
                  value:
                    access_token: >-
                      eyJhbGciOiJFUzI1NiIsImtpZCI6ImtfOHNKMmRRdlgwbkxyNVRmWWIzSGtQdyIsInR5cCI6ImF0K2p3dCJ9.eyJpc3MiOiJodHRwczovL3lvdXItYXBwLmF1dGguZGlkaXQubWUiLCJhdWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQiLCJzdWIiOiIxYzlkOGI4OC0xYmZmLTQzZDEtYWQ3YS04OGIyYmMwMDI0ZTkiLCJzaWQiOiJjOWFiZjZjYy0yZDY0LTRiZjItYjMxZS1hNGQwOWEwNzBhYjEiLCJqdGkiOiJSZ3F1NzE3OWUtbGhKMGJ2VmVELVlnIiwiaWF0IjoxNzkyMjMzNjc0LCJleHAiOjE3OTIyMzM5NzQsInZlbmRvcl9kYXRhIjoidXNlci00MiIsIm9yZyI6bnVsbCwidmVyaWZpZWQiOnt9LCJhbXIiOlsicGFzc3dvcmQiXSwiYWN0IjpudWxsLCJjbGllbnRfaWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQifQ.AxrqN8Pm-Op-3OayZk8HcvlFQZhozRiOvQ0SgQsGgrz4UNeJlUEeSlq9B8WcYUuM8naRaY5kQt_TUofnsYcyYQ
                    id_token: >-
                      eyJhbGciOiJFUzI1NiIsImtpZCI6ImtfOHNKMmRRdlgwbkxyNVRmWWIzSGtQdyIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3lvdXItYXBwLmF1dGguZGlkaXQubWUiLCJhdWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQiLCJzdWIiOiIxYzlkOGI4OC0xYmZmLTQzZDEtYWQ3YS04OGIyYmMwMDI0ZTkiLCJzaWQiOiJjOWFiZjZjYy0yZDY0LTRiZjItYjMxZS1hNGQwOWEwNzBhYjEiLCJqdGkiOiJNTHRPNHM4SHItQnJrcDd2NTlPV0Z3IiwiaWF0IjoxNzkyMjMzNjc0LCJleHAiOjE3OTIyMzM5NzQsInZlbmRvcl9kYXRhIjoidXNlci00MiIsIm9yZyI6bnVsbCwidmVyaWZpZWQiOnt9LCJhbXIiOlsicGFzc3dvcmQiXSwiYWN0IjpudWxsLCJhdXRoX3RpbWUiOjE3OTIyMzM2NzQsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJlbWFpbCI6InBlcnNvbkBleGFtcGxlLmNvbSIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.avhfDFp_aUV5_1ssYzwDcIA7H6Waf19P0bn5GCg25FhLIZBGIlwc8HiUPGj1j26r21OkP4FQnS_jM1Ho3dHtKQ
                    refresh_token: >-
                      N4yZTl6y24YKYq77X_SOrBn1q2Lit81WBQMOay7dq_IVfTnxyY8ZGcJk-6-fcmWW
                    token_type: Bearer
                    expires_in: 299
                    session_id: c9abf6cc-2d64-4bf2-b31e-a4d09a070ab1
        '400':
          description: >-
            L'autorizzazione non è riuscita. `invalid_grant`: il codice o il
            refresh token è sconosciuto, già utilizzato o scaduto; il
            verificatore PKCE o `redirect_uri` non corrisponde, oppure
            `redirect_uri` non è più registrato; la persona è stata bloccata o
            la sua email non è più verificata; la sessione è terminata o non
            rispetta più la tua policy MFA; oppure, nel caso di un codice, hai
            disattivato il metodo di accesso da cui proveniva. La disattivazione
            di un metodo non interrompe il refresh delle sessioni che ha già
            avviato. `invalid_client`: `client_id` non è l'ID della tua
            applicazione. `mfa_required`: l'accesso non ha rispettato la tua
            policy MFA. Gli errori di campo indicano un campo mancante o non
            valido. Un corpo non analizzabile restituisce un messaggio di
            `detail`.
          headers:
            Cache-Control:
              description: >-
                Sempre `no-store`: non memorizzare mai nella cache questa
                risposta.
              schema:
                type: string
                example: no-store
            Pragma:
              description: Sempre `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/OAuthError'
                  - $ref: '#/components/schemas/FieldErrors'
                  - $ref: '#/components/schemas/Detail'
              examples:
                InvalidGrant:
                  summary: Codice o token di aggiornamento rifiutato
                  value:
                    error: invalid_grant
                InvalidClient:
                  summary: client_id errato
                  value:
                    error: invalid_client
                MfaRequired:
                  summary: Criterio MFA non soddisfatto
                  value:
                    error: mfa_required
                MissingFields:
                  summary: Una concessione priva dei campi obbligatori
                  value:
                    non_field_errors:
                      - invalid_request
                UnknownGrant:
                  summary: grant_type non supportato
                  value:
                    grant_type:
                      - '"password" is not a valid choice.'
                UnknownField:
                  summary: Un campo non accettato dall'endpoint
                  value:
                    foo: unknown_field
                MalformedBody:
                  summary: Un corpo JSON che non può essere analizzato
                  value:
                    detail: >-
                      JSON parse error - Expecting property name enclosed in
                      double quotes: line 1 column 2 (char 1)
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - {}
components:
  schemas:
    TokenRequest:
      description: >-
        Uno dei due grant, scelto da `grant_type`. L'endpoint accetta i campi di
        entrambi i grant e valida ogni campo ricevuto; pertanto, una richiesta
        di refresh che contiene anche un `code_verifier` malformato riceve un
        errore relativo al campo. Invia solo i campi del tuo grant; qualsiasi
        altro campo riceve `unknown_field`.
      oneOf:
        - $ref: '#/components/schemas/AuthorizationCodeGrantRequest'
        - $ref: '#/components/schemas/RefreshTokenGrantRequest'
      discriminator:
        propertyName: grant_type
        mapping:
          authorization_code: '#/components/schemas/AuthorizationCodeGrantRequest'
          refresh_token: '#/components/schemas/RefreshTokenGrantRequest'
    TokenResponse:
      type: object
      description: Token per una sessione. Sostituisci tutti e tre insieme dopo un rinnovo.
      required:
        - access_token
        - id_token
        - refresh_token
        - token_type
        - expires_in
        - session_id
      properties:
        access_token:
          type: string
          description: >-
            JWT ES256, intestazione `typ: at+jwt`. Invialo come `Authorization:
            Bearer <access_token>`. Claim: `AccessTokenClaims`.
          example: >-
            eyJhbGciOiJFUzI1NiIsImtpZCI6ImtfOHNKMmRRdlgwbkxyNVRmWWIzSGtQdyIsInR5cCI6ImF0K2p3dCJ9.eyJpc3MiOiJodHRwczovL3lvdXItYXBwLmF1dGguZGlkaXQubWUiLCJhdWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQiLCJzdWIiOiIxYzlkOGI4OC0xYmZmLTQzZDEtYWQ3YS04OGIyYmMwMDI0ZTkiLCJzaWQiOiJjOWFiZjZjYy0yZDY0LTRiZjItYjMxZS1hNGQwOWEwNzBhYjEiLCJqdGkiOiJSZ3F1NzE3OWUtbGhKMGJ2VmVELVlnIiwiaWF0IjoxNzkyMjMzNjc0LCJleHAiOjE3OTIyMzM5NzQsInZlbmRvcl9kYXRhIjoidXNlci00MiIsIm9yZyI6bnVsbCwidmVyaWZpZWQiOnt9LCJhbXIiOlsicGFzc3dvcmQiXSwiYWN0IjpudWxsLCJjbGllbnRfaWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQifQ.AxrqN8Pm-Op-3OayZk8HcvlFQZhozRiOvQ0SgQsGgrz4UNeJlUEeSlq9B8WcYUuM8naRaY5kQt_TUofnsYcyYQ
          x-didit-jwt:
            header: '#/components/schemas/AccessTokenHeader'
            claims: '#/components/schemas/AccessTokenClaims'
        id_token:
          type: string
          description: >-
            JWT ES256, intestazione `typ: JWT`, affinché la tua applicazione
            possa leggere chi ha effettuato l'accesso. Non inviarlo mai come
            token di accesso. Claim: `IDTokenClaims`.
          example: >-
            eyJhbGciOiJFUzI1NiIsImtpZCI6ImtfOHNKMmRRdlgwbkxyNVRmWWIzSGtQdyIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3lvdXItYXBwLmF1dGguZGlkaXQubWUiLCJhdWQiOiI3YjBhNmMyZS0zZjQxLTRjOWEtOGQ1NS0xZTJmM2E0YjVjNmQiLCJzdWIiOiIxYzlkOGI4OC0xYmZmLTQzZDEtYWQ3YS04OGIyYmMwMDI0ZTkiLCJzaWQiOiJjOWFiZjZjYy0yZDY0LTRiZjItYjMxZS1hNGQwOWEwNzBhYjEiLCJqdGkiOiJNTHRPNHM4SHItQnJrcDd2NTlPV0Z3IiwiaWF0IjoxNzkyMjMzNjc0LCJleHAiOjE3OTIyMzM5NzQsInZlbmRvcl9kYXRhIjoidXNlci00MiIsIm9yZyI6bnVsbCwidmVyaWZpZWQiOnt9LCJhbXIiOlsicGFzc3dvcmQiXSwiYWN0IjpudWxsLCJhdXRoX3RpbWUiOjE3OTIyMzM2NzQsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJlbWFpbCI6InBlcnNvbkBleGFtcGxlLmNvbSIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.avhfDFp_aUV5_1ssYzwDcIA7H6Waf19P0bn5GCg25FhLIZBGIlwc8HiUPGj1j26r21OkP4FQnS_jM1Ho3dHtKQ
          x-didit-jwt:
            header: '#/components/schemas/IDTokenHeader'
            claims: '#/components/schemas/IDTokenClaims'
        refresh_token:
          type: string
          description: >-
            Monouso. È valido fino al termine della sessione e ogni
            aggiornamento ne restituisce uno nuovo.
          example: N4yZTl6y24YKYq77X_SOrBn1q2Lit81WBQMOay7dq_IVfTnxyY8ZGcJk-6-fcmWW
        token_type:
          type: string
          enum:
            - Bearer
        expires_in:
          type: integer
          minimum: 0
          maximum: 300
          description: >-
            Secondi prima della scadenza del token di accesso: al massimo 300,
            meno se la sessione termina prima.
          example: 299
        session_id:
          type: string
          format: uuid
          description: >-
            La sessione a cui appartengono questi token, lo stesso valore del
            claim `sid`.
          example: c9abf6cc-2d64-4bf2-b31e-a4d09a070ab1
    OAuthError:
      title: OAuth error
      type: object
      description: Un errore OAuth (RFC 6749 sezione 5.2) o un errore di servizio.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
    FieldErrors:
      title: Field errors
      type: object
      description: >-
        Errori di validazione per campo. Un valore è un elenco di messaggi o un
        singolo codice (`unknown_field`, `invalid_redirect_uri`).
        `non_field_errors` contiene regole relative a più campi.
      additionalProperties:
        oneOf:
          - type: string
          - type: array
            items:
              type: string
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
    AuthorizationCodeGrantRequest:
      title: Authorization code grant
      type: object
      description: >-
        Scambia il codice di autorizzazione ottenuto dal reindirizzamento con i
        token. Il codice funziona una sola volta, per 60 secondi.
      required:
        - grant_type
        - code
        - code_verifier
        - redirect_uri
      properties:
        grant_type:
          type: string
          enum:
            - authorization_code
        code:
          type: string
          maxLength: 128
          description: >-
            Il parametro di query `code` ricevuto dal tuo `redirect_uri`.
            Verifica lo `state` del callback prima di scambiarlo.
          example: Vb0bVt4CLlr8ZL0kE5mAxv8gS6R0rW3hYqC1pN7dJ2s
        code_verifier:
          type: string
          minLength: 43
          maxLength: 128
          pattern: ^[A-Za-z0-9._~-]{43,128}$
          description: >-
            Il verificatore PKCE il cui hash S256 era il `code_challenge`
            dell'accesso.
          example: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
        redirect_uri:
          type: string
          maxLength: 2048
          description: >-
            L'esatto `redirect_uri` con cui è iniziato l'accesso. Deve comunque
            essere uno degli URI di reindirizzamento dell'applicazione.
          example: https://app.example.com/auth/callback
        client_id:
          type: string
          maxLength: 64
          description: >-
            Opzionale. Se inviato, deve corrispondere all'ID della tua
            applicazione, altrimenti la richiesta fallisce con `invalid_client`.
          example: 7b0a6c2e-3f41-4c9a-8d55-1e2f3a4b5c6d
        scope:
          type: string
          maxLength: 512
          description: >-
            Opzionale e accettato dai client standard OpenID Connect. Non amplia
            mai ciò che l'accesso ha concesso.
          example: openid email
    RefreshTokenGrantRequest:
      title: Refresh token grant
      type: object
      description: >-
        Scambia un refresh token con un nuovo token di accesso, token ID e
        refresh token. Il refresh token funziona una sola volta: inviarlo di
        nuovo revoca la sessione, quindi esegui un solo aggiornamento alla volta
        per sessione.
      required:
        - grant_type
        - refresh_token
      properties:
        grant_type:
          type: string
          enum:
            - refresh_token
        refresh_token:
          type: string
          maxLength: 128
          description: Il `refresh_token` della risposta del token precedente.
          example: N4yZTl6y24YKYq77X_SOrBn1q2Lit81WBQMOay7dq_IVfTnxyY8ZGcJk-6-fcmWW
        client_id:
          type: string
          maxLength: 64
          description: >-
            Opzionale. Se inviato, deve corrispondere all'ID della tua
            applicazione, altrimenti la richiesta fallisce con `invalid_client`.
          example: 7b0a6c2e-3f41-4c9a-8d55-1e2f3a4b5c6d
        scope:
          type: string
          maxLength: 512
          description: >-
            Opzionale e accettato dai client standard OpenID Connect. Un
            aggiornamento non amplia mai ciò che la sessione contiene.
          example: openid email
  responses:
    OriginNotAllowed:
      description: >-
        La richiesta conteneva un `Origin` che non appartiene all'applicazione
        né è tra le origini consentite. Le richieste server non inviano alcun
        `Origin`.
      headers:
        Cache-Control:
          description: 'Sempre `no-store`: non memorizzare mai nella cache questa risposta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Sempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            OriginNotAllowed:
              summary: Origine non consentita
              value:
                detail: origin_not_allowed
    ApplicationNotFound:
      description: >-
        L'indirizzo appartiene a un'applicazione, ma l'Autenticazione non è
        attiva per essa; sull'indirizzo `apx.didit.me`, l'ID applicazione è
        sconosciuto. Un indirizzo che non appartiene ad alcuna applicazione
        viene rifiutato prima di raggiungere l'endpoint, e tale risposta non è
        in formato JSON.
      headers:
        Cache-Control:
          description: 'Sempre `no-store`: non memorizzare mai nella cache questa risposta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Sempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            ApplicationNotFound:
              summary: Applicazione sconosciuta
              value:
                detail: No Configuration matches the given query.
    RateLimited:
      description: >-
        Troppe richieste da questo indirizzo IP per questo endpoint oppure, su
        un `POST` o un `DELETE`, un bucket di protezione dai bot è vuoto.
        Nessuna operazione eseguita: attendi `Retry-After` secondi, poi riprova.
      headers:
        Retry-After:
          description: Secondi da attendere prima di effettuare un nuovo tentativo.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 'Sempre `no-store`: non memorizzare mai nella cache questa risposta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Sempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            RateLimited:
              summary: Limite dell'endpoint
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Limite di protezione dai bot (POST e DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Un servizio da cui dipende la richiesta è temporaneamente non
        disponibile. Riprova con backoff.
      headers:
        Cache-Control:
          description: 'Sempre `no-store`: non memorizzare mai nella cache questa risposta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Sempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
          examples:
            TemporarilyUnavailable:
              summary: Riprova più tardi
              value:
                error: temporarily_unavailable

````

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