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

# Obtener sesión | API de autenticación de Didit

> GET /session/ de Didit valida un token de acceso contra la sesión activa: falla al instante tras revocación, inactividad, bloqueo o refresco.

> [!WARNING]
>
> La autenticación es nueva. El emisor de tu aplicación proporciona estos endpoints, como `https://<name>.auth.didit.me`, y nunca aceptan tu clave de API de Didit.

Esta es la comprobación de revocación instantánea. Permite 30 solicitudes por minuto y 300 por hora por dirección IP, así que verifica los tokens sin conexión en cada solicitud y invoca este endpoint antes de realizar acciones sensibles. Consulta [Comprobar la sesión](https://docs.didit.me/es/authentication/tokens-and-jwks.md#comprobar-la-sesión).


## OpenAPI

````yaml es/openapi-authentication.json GET /session/
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Los endpoints de servidor de Didit Authentication, el producto de inicio de
    sesión para los usuarios finales de tu aplicación. Authentication es
    **nuevo** y llega a producción en la versión 2026-11-01.


    ## URL base


    Cada aplicación es su propio emisor de OpenID Connect, y cada endpoint que
    aparece a continuación se sirve en la raíz de ese emisor:


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

    - Tu propio dominio personalizado, una vez que esté activo. A partir de ese
    momento sustituye al host predeterminado como emisor: los nuevos tokens lo
    indican en `iss`, el discovery apunta a él y la clave publicable cambia. Los
    tokens de acceso emitidos con el host predeterminado fallan en `/session/`,
    `/step-up/` y `/monitoring-token/` hasta que se renuevan.


    Producción y sandbox son aplicaciones distintas, por lo que son emisores
    distintos con claves distintas. La clave publicable es `pk_live_`
    (producción) o `pk_test_` (sandbox) seguida de la codificación base64url sin
    relleno del emisor, sin barra final: decodifícala para obtener el emisor. Es
    un identificador público, no una credencial.


    Los mismos endpoints JSON también se sirven en
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`. Los tokens
    siempre indican el emisor anterior, sea cual sea la dirección que los
    emitió.


    ## Credenciales


    Estos endpoints nunca aceptan tu clave de API de Didit ni un token de la
    consola.


    - El discovery, el JWKS y `POST /token/` no requieren credenciales. Los
    clientes son públicos: no hay secreto de cliente, y un código de
    autorización está vinculado a su verificador PKCE (`S256`). `client_id` es
    el ID de tu aplicación.

    - `/session/`, `/step-up/` y `/monitoring-token/` requieren el token de
    acceso de la persona: `Authorization: Bearer <access_token>`. Cada llamada
    exitosa cuenta como actividad en la sesión, por lo que reinicia el tiempo de
    inactividad de la sesión.


    ## Cuerpos de las solicitudes


    Todos los endpoints que aceptan un cuerpo admiten cuerpos JSON, codificados
    como formulario y multipart. Este documento describe JSON, además de la
    codificación como formulario para `POST /token/`, tal como la envían los
    clientes OAuth. Un campo que el endpoint no acepta recibe `400 {"<field>":
    "unknown_field"}`.


    ## Tokens


    - **Token de acceso**: un JWT ES256 con el encabezado `typ: at+jwt`, válido
    durante 5 minutos como máximo y nunca más que su sesión. Claims:
    `AccessTokenClaims`.

    - **Token de ID**: un JWT ES256 con el encabezado `typ: JWT`. Claims:
    `IDTokenClaims`. Nunca se acepta como token de acceso.

    - **Token de actualización**: una cadena aleatoria que rota en cada uso.
    Volver a enviar un token de actualización ya usado revoca la sesión.


    Verifica un token con las claves de `GET /.well-known/jwks.json`: el
    algoritmo debe ser `ES256`, `typ` debe coincidir con el tipo de token, `iss`
    debe ser igual al emisor que configuraste y `aud`, al ID de tu aplicación.
    La verificación offline solo detecta una sesión revocada cuando su token de
    acceso expira; `GET /session/` es la comprobación inmediata.


    ## Errores


    | Cuerpo | Cuándo |

    | --- | --- |

    | `{"error": "<code>"}` | Errores de `POST /token/`, todos con estado `400`,
    con la forma de cuerpo de la [sección 5.2 de RFC
    6749](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client` y `mfa_required` de Didit. Errores del servicio:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` o `{"<field>": "<code>"}` | Un campo de la
    solicitud no superó la validación. `non_field_errors` indica una regla que
    afecta a varios campos, y `unknown_field`, un campo que el endpoint no
    acepta. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (aplicación o step-up desconocidos) y `429`
    (límite de solicitudes). También `400` para un cuerpo que no se puede
    analizar (`JSON parse error - ...`), `405` para un método que el endpoint no
    sirve y `415` para un `Content-Type` no admitido. |


    Un `401` también incluye `WWW-Authenticate: Bearer`, y un `429` incluye
    `Retry-After` en segundos.


    Dos rechazos no son JSON. Una dirección que no es un emisor se rechaza antes
    de llegar a estos endpoints, por ejemplo con un `404` vacío para un nombre
    `*.auth.didit.me` sin usar. Un `step_up_id` que no es un UUID recibe una
    página `404`.


    ## Límites de solicitudes


    Una solicitud tiene que superar dos capas.


    **Límites por endpoint**, contados por dirección IP del cliente, por
    aplicación y por endpoint:


    - Discovery y el JWKS: 1,200 solicitudes por minuto y 12,000 por hora.

    - Todos los demás endpoints: 30 solicitudes por minuto y 300 por hora. `GET`
    y `DELETE /session/` comparten un mismo recuento.


    Al superar un límite: `429 {"detail": "Too many requests from this IP
    address. Please wait before trying again. Expected available in 60
    seconds."}`, o `3600 seconds` para el límite por hora.


    **Protección contra bots**, en cada `POST` y `DELETE`. Sus cubetas las
    comparten todas las solicitudes `POST` y `DELETE` de la aplicación,
    incluidos los pasos del inicio de sesión alojado, y se rellenan de forma
    continua:


    - 60 solicitudes por minuto por dirección IP del cliente.

    - 30 solicitudes por minuto por dispositivo, para las solicitudes que
    identifican su dispositivo, como hacen los SDK de navegador y nativos.

    - 1,000 solicitudes por minuto para toda la aplicación, sumando todas las
    direcciones IP.


    Al superar una cubeta: `429 {"detail": "rate_limited Expected available in N
    seconds."}` (`1 second.` cuando N es 1). La cubeta por IP abarca todos los
    endpoints, por lo que una misma dirección que combine llamadas de token,
    step-up y cierre de sesión puede vaciarla antes de alcanzar cualquier límite
    por endpoint. La cubeta de la aplicación cuenta todos los clientes de la
    aplicación, navegadores incluidos.


    Ambas capas responden antes de que se ejecute el endpoint, por lo que una
    solicitud que recibió `429` no se ejecutó: reinténtala después de
    `Retry-After`, incluida una renovación.


    ## Solicitudes desde el navegador


    Una solicitud que incluye un encabezado `Origin` debe proceder de uno de los
    orígenes propios de la aplicación o de sus orígenes permitidos; de lo
    contrario, recibe `403 origin_not_allowed`. Las solicitudes de servidor a
    servidor no envían `Origin`.


    ## Fuera del alcance de este documento


    Estas rutas sirven a las páginas alojadas, a los SDK de navegador y nativos,
    y a los agentes de IA. No forman parte del contrato de servidor, y los SDK
    de servidor no las llaman:


    - Pasos de inicio de sesión: `POST /authorize/`, `POST /password/`,
    `/email/*`, `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`,
    `/social/*` y `/protection/complete/`.

    - Páginas alojadas y callbacks: `/sign-in`, `/magic`, `/invite`, `/reset`,
    `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/` y los archivos de
    asociación de apps nativas en `/.well-known/`.

    - Acceso de agentes: `/agents/*` y `/grants/`, incluido `GET
    /agents/session/`, la comprobación en tiempo real del token de acceso de un
    agente de IA. El acceso de agentes no forma parte de esta versión del
    contrato.

    - La API de gestión de la consola para Authentication, que utiliza sesiones
    de la consola.


    Los eventos de Authentication todavía no se entregan como webhooks, por lo
    que este documento no define ningún webhook.
servers:
  - url: https://{issuer}
    description: 'El emisor de tu aplicación: su origen de inicio de sesión.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          El host del emisor: `<name>.auth.didit.me` (producción),
          `<name>.sandbox.auth.didit.me` (sandbox) o tu dominio personalizado
          activo.
security: []
tags:
  - name: Issuer
    description: Claves de descubrimiento y de firma para verificar tokens.
  - name: Tokens
    description: Las concesiones de código de autorización y de actualización.
  - name: Sessions
    description: Comprueba y finaliza la sesión asociada a un token de acceso.
  - name: Step-ups
    description: Verificación antes de una acción sensible.
  - name: Monitoring
    description: >-
      Credenciales del dispositivo para los eventos de monitorización de
      transacciones.
paths:
  /session/:
    get:
      tags:
        - Sessions
      summary: Obtener la sesión
      description: >-
        Comprueba el token de acceso con la sesión activa y lo devuelve. Es más
        estricto que verificar el JWT por tu cuenta: también falla de inmediato
        cuando la sesión se revocó, quedó inactiva o superó su duración máxima,
        cuando la persona fue bloqueada o su correo electrónico ya no está
        verificado, cuando la sesión ya no cumple tu política de MFA (por
        ejemplo, después de que la persona añadiera una aplicación de
        autenticación o pasara a ser administradora de la organización), o
        cuando el token fue reemplazado por una renovación. Úsalo antes de una
        acción sensible, por ejemplo un pago. Una comprobación correcta cuenta
        como actividad, por lo que reinicia el tiempo de inactividad de la
        sesión.
      operationId: authentication_get_session
      responses:
        '200':
          description: La sesión está activa.
          headers:
            Cache-Control:
              description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
              schema:
                type: string
                example: no-store
            Pragma:
              description: Siempre `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Session'
              examples:
                Session:
                  summary: Una sesión con contraseña
                  value:
                    sub: 1c9d8b88-1bff-43d1-ad7a-88b2bc0024e9
                    sid: c9abf6cc-2d64-4bf2-b31e-a4d09a070ab1
                    application_id: 7b0a6c2e-3f41-4c9a-8d55-1e2f3a4b5c6d
                    vendor_data: user-42
                    amr:
                      - password
                    mfa_verified: false
                    email: person@example.com
                    email_verified: true
                    phone: null
                    verified_identity: null
                    verified: null
                    expires_at: '2026-11-16T10:41:14.347557Z'
                    post_logout_redirect_uri: ''
                    organizations: []
                VerifiedMember:
                  summary: Un miembro de la organización verificado
                  value:
                    sub: 1c9d8b88-1bff-43d1-ad7a-88b2bc0024e9
                    sid: c9abf6cc-2d64-4bf2-b31e-a4d09a070ab1
                    application_id: 7b0a6c2e-3f41-4c9a-8d55-1e2f3a4b5c6d
                    vendor_data: user-42
                    amr:
                      - passkey
                    mfa_verified: true
                    email: person@example.com
                    email_verified: true
                    phone: '+34600000000'
                    verified_identity: null
                    verified:
                      level: full_id
                      over_18: true
                      given_name: Alex
                      country: ES
                    expires_at: '2026-11-16T10:41:14.347557Z'
                    post_logout_redirect_uri: https://app.example.com/
                    organizations:
                      - organization_id: 3e9a1f0b-5c2d-4e7f-8a6b-9c0d1e2f3a4b
                        organization__name: Northwind
                        role: admin
                        custom_role: null
        '401':
          $ref: '#/components/responses/InvalidToken'
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - AccessToken: []
components:
  schemas:
    Session:
      type: object
      description: La sesión activa asociada a un token de acceso.
      required:
        - sub
        - sid
        - application_id
        - vendor_data
        - amr
        - mfa_verified
        - email
        - email_verified
        - phone
        - verified_identity
        - verified
        - expires_at
        - post_logout_redirect_uri
        - organizations
      properties:
        sub:
          type: string
          format: uuid
          description: El ID de la identidad.
          example: 1c9d8b88-1bff-43d1-ad7a-88b2bc0024e9
        sid:
          type: string
          format: uuid
          description: El ID de la sesión.
          example: c9abf6cc-2d64-4bf2-b31e-a4d09a070ab1
        application_id:
          type: string
          format: uuid
          example: 7b0a6c2e-3f41-4c9a-8d55-1e2f3a4b5c6d
        vendor_data:
          type: string
          description: >-
            La referencia de la persona en todos los productos de Didit, igual
            que en los tokens.
          example: user-42
        amr:
          $ref: '#/components/schemas/AuthenticationMethods'
        mfa_verified:
          type: boolean
          description: >-
            Si la sesión superó un segundo factor. Siempre es `true` en un
            inicio de sesión con passkey.
          example: false
        email:
          type: string
          format: email
          nullable: true
          example: person@example.com
        email_verified:
          type: boolean
          example: true
        phone:
          type: string
          nullable: true
          description: Número de teléfono en formato E.164, o `null`.
          example: null
        verified_identity:
          $ref: '#/components/schemas/WalletVerification'
        verified:
          type: object
          nullable: true
          description: >-
            Nivel de verificación y claims seleccionados, el mismo objeto que
            los tokens incluyen como `verified`, o `null` cuando no hay ninguno.
            Consulta este campo, y no `email_verified`, para saber si la persona
            verificó su identidad.
          properties:
            level:
              type: string
              enum:
                - liveness
                - liveness_face_match
                - full_id
              description: >-
                El nivel más alto superado. Del más débil al más fuerte:
                `liveness`, `liveness_face_match`, `full_id`.
              example: full_id
            over_18:
              type: boolean
              example: true
            over_21:
              type: boolean
              example: true
            given_name:
              type: string
              example: Alex
            family_name:
              type: string
              example: Doe
            birthdate:
              type: string
              description: Fecha de nacimiento del documento, `YYYY-MM-DD`.
              example: '1990-04-12'
            nationality:
              type: string
              description: Código de país ISO 3166-1 alfa-2.
              example: ES
            country:
              type: string
              description: Código ISO 3166-1 alfa-2 del país del documento.
              example: ES
            document_verified:
              type: boolean
              example: true
            liveness:
              type: boolean
              example: true
        expires_at:
          type: string
          format: date-time
          description: >-
            Fecha y hora límite en que termina la sesión. El tiempo de
            inactividad puede terminarla antes.
          example: '2026-11-16T10:41:14.347557Z'
        post_logout_redirect_uri:
          type: string
          description: >-
            Adónde envía tu aplicación a la persona después de cerrar sesión.
            Cadena vacía si no se ha configurado.
          example: https://app.example.com/
        organizations:
          type: array
          description: >-
            Todas las organizaciones cliente a las que pertenece la persona, si
            las organizaciones están activadas. Vacío en caso contrario.
          items:
            $ref: '#/components/schemas/SessionOrganization'
    AuthenticationMethods:
      type: array
      description: >-
        Cómo inició sesión la sesión, como un único valor: por ejemplo
        `password`, `code` (código por correo electrónico), `magic` (enlace
        mágico), `passkey`, `phone`, `sso`, `wallet` (Didit ID Wallet) o el
        nombre de un método de inicio de sesión social. Vacío para un token de
        agente.
      items:
        type: string
      example:
        - password
    WalletVerification:
      type: object
      description: >-
        Lo que Didit ID Wallet compartió al iniciar sesión. `null` cuando la
        persona inició sesión de otra forma.
      nullable: true
      required:
        - issuer
        - subject
      properties:
        issuer:
          type: string
          description: El emisor de la wallet.
          example: https://apx.didit.me/auth/idv
        subject:
          type: string
          description: El ID de la persona en la wallet.
          example: 8b7f5c1e-2d3a-4b5c-9e8f-7a6b5c4d3e2f
        shared_session:
          type: object
          description: >-
            Una verificación que la persona eligió compartir y que canjeas con
            tu propia clave de API.
          properties:
            share_token:
              type: string
            session_id:
              type: string
            from_application_id:
              type: string
        claims:
          type: object
          description: >-
            Los datos verificados que la persona aceptó compartir, limitados a
            lo que solicitó tu aplicación.
          additionalProperties:
            oneOf:
              - type: boolean
              - type: string
          example:
            over_18: true
            given_name: Alex
    SessionOrganization:
      type: object
      required:
        - organization_id
        - organization__name
        - role
        - custom_role
      properties:
        organization_id:
          type: string
          format: uuid
          example: 3e9a1f0b-5c2d-4e7f-8a6b-9c0d1e2f3a4b
        organization__name:
          type: string
          description: El nombre de la organización.
          example: Northwind
        role:
          type: string
          enum:
            - admin
            - member
            - billing
          example: admin
        custom_role:
          type: object
          nullable: true
          description: El rol personalizado asignado al miembro, o `null`.
          required:
            - key
            - permissions
          properties:
            key:
              type: string
              example: approver
            permissions:
              type: array
              items:
                type: string
              example:
                - payouts.approve
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
    OAuthError:
      title: OAuth error
      type: object
      description: Un error de OAuth (RFC 6749, sección 5.2) o un error del servicio.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    InvalidToken:
      description: >-
        Falta el token de acceso, o está mal formado, ha expirado, está firmado
        por otro emisor u otra clave, es un token de ID o un token de agente, o
        fue sustituido por una renovación; o bien su sesión se revocó, expiró
        por inactividad, superó su vida útil o ya no cumple tu política de MFA,
        o la persona fue bloqueada o su correo electrónico ya no está
        verificado. Haz que la persona vuelva a iniciar sesión.
      headers:
        WWW-Authenticate:
          description: '`Bearer`.'
          schema:
            type: string
            example: Bearer
        Cache-Control:
          description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Siempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            InvalidToken:
              summary: Token de acceso rechazado
              value:
                detail: invalid_token
    OriginNotAllowed:
      description: >-
        La solicitud incluía un `Origin` que no es el de la propia aplicación ni
        está entre sus orígenes permitidos. Las solicitudes de servidor no
        envían `Origin`.
      headers:
        Cache-Control:
          description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Siempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            OriginNotAllowed:
              summary: Origen no permitido
              value:
                detail: origin_not_allowed
    ApplicationNotFound:
      description: >-
        La dirección pertenece a una aplicación, pero Authentication no está
        activa para ella; en la dirección `apx.didit.me`, el ID de aplicación es
        desconocido. Una dirección que no pertenece a ninguna aplicación se
        rechaza antes de llegar al endpoint, y esa respuesta no es JSON.
      headers:
        Cache-Control:
          description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Siempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            ApplicationNotFound:
              summary: Aplicación desconocida
              value:
                detail: No Configuration matches the given query.
    RateLimited:
      description: >-
        Demasiadas solicitudes desde esta dirección IP para este endpoint o, en
        un `POST` o un `DELETE`, un bucket de protección contra bots está vacío.
        No se ejecutó nada: espera `Retry-After` segundos y vuelve a intentarlo.
      headers:
        Retry-After:
          description: Segundos que hay que esperar antes de reintentar.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Siempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            RateLimited:
              summary: Límite del endpoint
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Límite de protección contra bots (POST y DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Un servicio del que depende la solicitud no está disponible
        momentáneamente. Reintenta con backoff.
      headers:
        Cache-Control:
          description: 'Siempre `no-store`: nunca almacenes en caché esta respuesta.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Siempre `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
          examples:
            TemporarilyUnavailable:
              summary: Reintentar más tarde
              value:
                error: temporarily_unavailable
  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        El token de acceso de la persona obtenido de `POST /token/`: un JWT
        ES256 con el encabezado `typ: at+jwt`, válido durante un máximo de 5
        minutos. No es tu clave de API de Didit.

````

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