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

# Obtenir les claus de signatura (JWKS) | API de Didit

> GET /.well-known/jwks.json retorna les claus públiques ES256 de Didit. Desa-les per kid; roten cada 30 dies amb un solapament d'un dia.

> [!WARNING]
>
> L'autenticació és nova. Aquests endpoints els serveix l'emissor de la teva aplicació, com `https://<name>.auth.didit.me`, i mai no accepten la teva clau d'API de Didit.

Les claus es roten cada 30 dies, amb un dia de solapament a cada costat, de manera que una JWKS emmagatzemada a la memòria cau durant 5 minuts continua verificant tokens durant una rotació. Torna a obtenir la JWKS quan un token indiqui un `kid` que no tens, com a màxim un cop per minut. Consulta [Emmagatzematge a la memòria cau i rotació](https://docs.didit.me/ca/authentication/tokens-and-jwks.md#memòria-cau-i-rotació).


## OpenAPI

````yaml ca/openapi-authentication.json GET /.well-known/jwks.json
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Els endpoints adreçats al servidor de Didit Authentication, el producte
    d'inici de sessió per als usuaris finals de la teva aplicació.
    Authentication és **nou** i arriba a producció en el llançament del
    2026-11-01.


    ## URL base


    Cada aplicació és el seu propi emissor d'OpenID Connect, i cada endpoint
    següent se serveix a l'arrel d'aquest emissor:


    - `https://<name>.auth.didit.me` per a una aplicació de producció, o
    `https://<name>.sandbox.auth.didit.me` per a una aplicació de sandbox.

    - El teu propi domini personalitzat, un cop estigui actiu. Aleshores
    substitueix l'amfitrió per defecte com a emissor: els nous tokens l'anomenen
    a `iss`, el descobriment hi apunta i la clau publicable canvia. Els tokens
    d'accés emesos sota l'amfitrió per defecte fallen a `/session/`, `/step-up/`
    i `/monitoring-token/` fins que es renoven.


    Producció i sandbox són aplicacions separades, de manera que són emissors
    separats amb claus separades. La clau publicable és `pk_live_` (producció) o
    `pk_test_` (sandbox) seguida de la codificació base64url sense farciment de
    l'emissor, sense barra final: descodifica-la per trobar l'emissor. És un
    identificador públic, no una credencial.


    Els mateixos endpoints JSON també se serveixen sota
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`. Els tokens
    sempre anomenen l'emissor anterior, independentment de quina adreça els hagi
    emès.


    ## Credencials


    Aquests endpoints mai accepten la teva clau d'API de Didit ni un token de
    consola.


    - El descobriment, el JWKS i `POST /token/` no requereixen cap credencial.
    Els clients són públics: no hi ha cap secret de client, i un codi
    d'autorització està vinculat al seu verificador PKCE (`S256`). `client_id`
    és el teu ID d'aplicació.

    - `/session/`, `/step-up/` i `/monitoring-token/` requereixen el token
    d'accés de la persona: `Authorization: Bearer <access_token>`. Cada crida
    satisfactòria compta com a activitat a la sessió, de manera que reinicia el
    temps d'espera per inactivitat de la sessió.


    ## Cossos de sol·licitud


    Tots els endpoints que accepten un cos admeten cossos en JSON, codificats
    com a formulari i multipart. Aquest document descriu JSON, a més de la
    codificació com a formulari per a `POST /token/` tal com l'envien els
    clients OAuth. Un camp que l'endpoint no accepta rep `400 {"<field>":
    "unknown_field"}`.


    ## Tokens


    - **Token d'accés**: un JWT ES256 amb la capçalera `typ: at+jwt`, vàlid
    durant un màxim de 5 minuts i mai més temps que la seva sessió.
    Reclamacions: `AccessTokenClaims`.

    - **Token d'ID**: un JWT ES256 amb la capçalera `typ: JWT`. Reclamacions:
    `IDTokenClaims`. Mai s'accepta com a token d'accés.

    - **Token de renovació**: una cadena aleatòria que rota a cada ús. Enviar un
    token de renovació ja utilitzat revoca la sessió.


    Verifica un token amb les claus de `GET /.well-known/jwks.json`: l'algorisme
    ha de ser `ES256`, `typ` ha de coincidir amb el tipus de token, `iss` ha de
    ser igual a l'emissor que vas configurar i `aud` ha de ser el teu ID
    d'aplicació. La verificació fora de línia detecta una sessió revocada només
    un cop el seu token d'accés caduca; `GET /session/` és la comprovació
    instantània.


    ## Errors


    | Cos | Quan |

    | --- | --- |

    | `{"error": "<code>"}` | Errors de `POST /token/`, tots amb estat `400`,
    amb l'estructura de cos de la [secció 5.2 de la RFC
    6749](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client` i `mfa_required` de Didit. Errors de servei:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` o `{"<field>": "<code>"}` | Un camp de la
    sol·licitud ha fallat la validació. `non_field_errors` fa referència a una
    regla entre camps, i `unknown_field` a un camp que l'endpoint no accepta. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (aplicació o autenticació reforçada
    desconegudes) i `429` (límit de freqüència). També `400` per a un cos que no
    es pot analitzar (`JSON parse error - ...`), `405` per a un mètode que
    l'endpoint no ofereix i `415` per a un `Content-Type` no compatible. |


    Un `401` també inclou `WWW-Authenticate: Bearer`, i un `429` inclou
    `Retry-After` en segons.


    Hi ha dues denegacions que no són JSON. Una adreça que no sigui un emissor
    es denega abans d'arribar a aquests endpoints, per exemple amb un `404` buit
    per a un nom `*.auth.didit.me` no utilitzat. Un `step_up_id` que no sigui un
    UUID rep una pàgina `404`.


    ## Límits de freqüència


    Una sol·licitud ha de superar dues capes.


    **Límits d'endpoint**, comptats per adreça IP de client, per aplicació i per
    endpoint:


    - El descobriment i el JWKS: 1,200 sol·licituds per minut i 12,000 per hora.

    - La resta d'endpoints: 30 sol·licituds per minut i 300 per hora. `GET` i
    `DELETE /session/` comparteixen un mateix recompte.


    En superar un límit: `429 {"detail": "Too many requests from this IP
    address. Please wait before trying again. Expected available in 60
    seconds."}`, o `3600 seconds` per al límit per hora.


    **Protecció contra bots**, a cada `POST` i `DELETE`. Els seus dipòsits es
    comparteixen entre totes les sol·licituds `POST` i `DELETE` de l'aplicació,
    inclosos els passos d'inici de sessió allotjats, i es recarreguen
    contínuament:


    - 60 sol·licituds per minut per adreça IP de client.

    - 30 sol·licituds per minut per dispositiu, per a les sol·licituds que
    identifiquen el seu dispositiu, com fan els SDK de navegador i natius.

    - 3,000 sol·licituds per minut per a tota l'aplicació, entre totes les
    adreces IP. Les renovacions de tokens (`POST /token/` amb
    `grant_type=refresh_token`) utilitzen un dipòsit propi: 6,000 per minut per
    a tota l'aplicació.


    En superar un dipòsit: `429 {"detail": "rate_limited Expected available in N
    seconds."}` (`1 second.` quan N és 1). El dipòsit per IP abasta diversos
    endpoints, de manera que una sola adreça que combini crides de tokens,
    autenticació reforçada i tancament de sessió pot buidar-lo abans d'arribar a
    cap límit d'endpoint. El dipòsit de l'aplicació compta cada client de
    l'aplicació, navegadors inclosos.


    Totes dues capes responen abans que s'executi l'endpoint, de manera que una
    sol·licitud que hagi rebut un `429` no s'ha executat: reintenta-la després
    del temps indicat a `Retry-After`, inclosa una renovació.


    ## Sol·licituds de navegador


    Una sol·licitud que porti una capçalera `Origin` ha de provenir d'un dels
    orígens propis de l'aplicació o dels seus orígens permesos, o rebrà un `403
    origin_not_allowed`. Les sol·licituds de servidor a servidor no envien cap
    `Origin`.


    ## No cobert aquí


    Aquestes rutes serveixen les pàgines allotjades, els SDK de navegador i
    natius, i agents d'IA. No formen part del contracte de servidor, i els SDK
    de servidor no les criden:


    - Passos d'inici de sessió: `POST /authorize/`, `POST /password/`,
    `/email/*`, `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`,
    `/social/*` i `/protection/complete/`.

    - Pàgines allotjades i crides de retorn: `/sign-in`, `/magic`, `/invite`,
    `/reset`, `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/` i els fitxers
    d'associació d'aplicacions natives sota `/.well-known/`.

    - Accés d'agents: `/agents/*` i `/grants/`, incloent-hi `GET
    /agents/session/`, la comprovació en directe per al token d'accés d'un agent
    d'IA. L'accés d'agents no forma part d'aquesta versió del contracte.

    - L'API de gestió de la consola per a Authentication, que requereix sessions
    de consola.


    Els esdeveniments d'Authentication encara no es lliuren com a webhooks, de
    manera que aquest document no defineix cap webhook.
servers:
  - url: https://{issuer}
    description: 'L''emissor de la teva aplicació: el seu origen d''inici de sessió.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          L'amfitrió de l'emissor: `<name>.auth.didit.me` (producció),
          `<name>.sandbox.auth.didit.me` (sandbox) o el teu domini personalitzat
          actiu.
security: []
tags:
  - name: Issuer
    description: Claus de descobriment i de signatura, per verificar tokens.
  - name: Tokens
    description: El codi d'autorització i els permisos de renovació.
  - name: Sessions
    description: Comprova i finalitza la sessió associada a un token d'accés.
  - name: Step-ups
    description: Verificació abans d'una acció sensible.
  - name: Monitoring
    description: >-
      Credencials del dispositiu per a esdeveniments de monitoratge de
      transaccions.
paths:
  /.well-known/jwks.json:
    get:
      tags:
        - Issuer
      summary: Obtenir les claus de signatura
      description: >-
        Les claus ES256 públiques de l'aplicació. Cada token indica la seva clau
        a la capçalera `kid`.


        Les claus roten cada 30 dies. La clau següent es publica un dia abans de
        començar a signar, i la clau anterior es manté publicada durant un dia
        després de deixar de fer-ho, de manera que un JWKS emmagatzemat a la
        memòria cau fins a 5 minuts continua verificant durant una rotació.
        Emmagatzema les claus a la memòria cau per `kid` i torna a obtenir el
        JWKS quan un token indiqui un `kid` que no tinguis, com a màxim un cop
        per minut. Quan Didit revoca una clau compromesa, la clau desapareix
        d'aquest document immediatament i `GET /session/` rebutja tots els
        tokens que hagi signat. Una clau de substitució comença a signar
        immediatament, sense el dia de publicació anticipada, de manera que un
        JWKS emmagatzemat a la memòria cau fins a 5 minuts abans encara
        acceptarà la clau revocada i no coneixerà la de substitució.
      operationId: authentication_get_jwks
      responses:
        '200':
          description: Les claus publicades.
          headers:
            Cache-Control:
              description: >-
                `public, max-age=300`: tu i les memòries cau compartides podeu
                conservar una resposta satisfactòria durant 5 minuts, la durada
                d'un token d'accés.
              schema:
                type: string
                example: public, max-age=300
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JSONWebKeySet'
              examples:
                Keys:
                  summary: Una clau de signatura
                  value:
                    keys:
                      - kty: EC
                        crv: P-256
                        x: ZDN2unLMultuZwNY_ZKMvsKLRrlC_usPFZyK77cnDO8
                        'y': CfLKoaJNvhFpDWqG56H8dD_j0f1c93RdR63bhIdTh3I
                        kid: k_8sJ2dQvX0nLr5TfYb3HkPw
                        use: sig
                        alg: ES256
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - {}
components:
  schemas:
    JSONWebKeySet:
      type: object
      description: >-
        Les claus públiques de signatura publicades de l'aplicació. Normalment
        una clau; dues al voltant d'una rotació, quan la clau següent es publica
        un dia abans de signar i l'anterior es manté un dia després d'aturar-se.
      required:
        - keys
      properties:
        keys:
          type: array
          items:
            $ref: '#/components/schemas/JSONWebKey'
    JSONWebKey:
      type: object
      description: Una clau pública P-256 en format JWK (RFC 7517).
      required:
        - kty
        - crv
        - x
        - 'y'
        - kid
        - use
        - alg
      properties:
        kty:
          type: string
          enum:
            - EC
        crv:
          type: string
          enum:
            - P-256
        x:
          type: string
          description: La coordenada x del punt públic, en base64url.
          example: ZDN2unLMultuZwNY_ZKMvsKLRrlC_usPFZyK77cnDO8
        'y':
          type: string
          description: La coordenada y del punt públic, en base64url.
          example: CfLKoaJNvhFpDWqG56H8dD_j0f1c93RdR63bhIdTh3I
        kid:
          type: string
          description: >-
            ID de la clau, el `kid` a la capçalera de cada token que aquesta
            clau signa. Els nous ID de clau comencen per `k_`.
          example: k_8sJ2dQvX0nLr5TfYb3HkPw
        use:
          type: string
          enum:
            - sig
        alg:
          type: string
          enum:
            - ES256
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
    OAuthError:
      title: OAuth error
      type: object
      description: Un error d'OAuth (RFC 6749, secció 5.2) o un error de servei.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    OriginNotAllowed:
      description: >-
        La sol·licitud incloïa un `Origin` que no és el de la mateixa aplicació
        ni figura entre els seus orígens permesos. Les sol·licituds de servidor
        no envien cap `Origin`.
      headers:
        Cache-Control:
          description: >-
            Sempre `no-store`: no emmagatzemis mai aquesta resposta a la memòria
            cau.
          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: Origen no permès
              value:
                detail: origin_not_allowed
    ApplicationNotFound:
      description: >-
        L'adreça pertany a una aplicació, però Authentication no hi està actiu;
        a l'adreça `apx.didit.me`, l'ID d'aplicació és desconegut. Una adreça
        que no pertany a cap aplicació es rebutja abans d'arribar a l'endpoint,
        i aquesta resposta no és JSON.
      headers:
        Cache-Control:
          description: >-
            Sempre `no-store`: no emmagatzemis mai aquesta resposta a la memòria
            cau.
          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: Aplicació desconeguda
              value:
                detail: No Configuration matches the given query.
    RateLimited:
      description: >-
        Massa sol·licituds des d'aquesta adreça IP per a aquest endpoint o, en
        un `POST` o `DELETE`, un dipòsit de protecció contra bots està buit. No
        s'ha executat res: espera els segons indicats a `Retry-After` i torna-ho
        a provar.
      headers:
        Retry-After:
          description: Segons que cal esperar abans de reintentar.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: >-
            Sempre `no-store`: no emmagatzemis mai aquesta resposta a la memòria
            cau.
          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: Límit de l'endpoint
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Límit de protecció contra bots (POST i DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Un servei del qual depèn la sol·licitud no està disponible temporalment.
        Torna-ho a provar amb esperes progressives.
      headers:
        Cache-Control:
          description: >-
            Sempre `no-store`: no emmagatzemis mai aquesta resposta a la memòria
            cau.
          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: Reintenta-ho més tard
              value:
                error: temporarily_unavailable

````

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