> ## 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 estado de step-up | API de autenticación Didit

> GET /step-up/{step_up_id}/ de Didit devuelve el estado, método y nivel de un step-up. Ejecuta la acción sensible solo si el estado es aprobado.

> [!WARNING]
>
> Authentication es una función nueva. Estos endpoints los sirve el emisor de tu aplicación, como `https://<name>.auth.didit.me`, y nunca aceptan tu clave de API de Didit.

Un step-up pertenece a la sesión que lo creó: el token de acceso de otra sesión obtiene un `404`. Un step-up `pending` aparece como `expired` una vez transcurridos sus 30 minutos.


## OpenAPI

````yaml es/openapi-authentication.json GET /step-up/{step_up_id}/
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:
  /step-up/{step_up_id}/:
    get:
      tags:
        - Step-ups
      summary: Obtener un step-up
      description: >-
        El estado actual del step-up. Llámalo con un token de acceso de la misma
        sesión que creó el step-up y actúa solo cuando `status` sea `approved`.
      operationId: authentication_retrieve_step_up
      parameters:
        - name: step_up_id
          in: path
          required: true
          description: >-
            El `id` de `POST /step-up/`, que también es el parámetro de consulta
            `step_up` en tu `return_to`. Un valor que no es un UUID obtiene una
            página `404`, no JSON.
          schema:
            type: string
            format: uuid
          example: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
      responses:
        '200':
          description: El step-up.
          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/StepUp'
              examples:
                Approved:
                  summary: 'Aprobado: adelante'
                  value:
                    id: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
                    rule: payout
                    method: selfie
                    status: approved
                    level: liveness_face_match
                    amount: '900.00'
                    currency: USD
                    created_at: '2026-10-17T10:41:14.894632Z'
                    completed_at: '2026-10-17T10:43:02.118204Z'
                    expires_at: '2026-10-17T11:11:14.894581Z'
                Pending:
                  summary: Aún no ha finalizado
                  value:
                    id: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
                    rule: payout
                    method: selfie
                    status: pending
                    level: null
                    amount: '900.00'
                    currency: USD
                    created_at: '2026-10-17T10:41:14.894632Z'
                    completed_at: null
                    expires_at: '2026-10-17T11:11:14.894581Z'
        '401':
          $ref: '#/components/responses/InvalidToken'
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          description: >-
            Ninguna verificación adicional (step-up) con este ID pertenece a
            esta sesión, o la aplicación es desconocida.
          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:
                StepUpNotFound:
                  summary: Step-up desconocido
                  value:
                    detail: No VerificationCheck matches the given query.
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - AccessToken: []
components:
  schemas:
    StepUp:
      type: object
      description: Una verificación que la persona tiene que superar antes de la acción.
      required:
        - id
        - rule
        - method
        - status
        - level
        - amount
        - currency
        - created_at
        - completed_at
        - expires_at
      properties:
        id:
          type: string
          format: uuid
          example: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
        rule:
          type: string
          enum:
            - payout
            - device
            - bank
            - contact
          description: >-
            La regla que lo solicitó. Cuando se aplican varias, la que tiene el
            método más robusto.
          example: payout
        method:
          type: string
          enum:
            - liveness
            - selfie
            - full_id
          description: >-
            Lo que hace la persona: `liveness`, `selfie` (prueba de vida
            comparada con el rostro que Didit ya tiene) o `full_id` (documento y
            selfie). Si Didit aún no tiene ningún rostro de la persona, `selfie`
            pasa a ser `full_id` en cuanto abre `verification_url`.
          example: selfie
        status:
          type: string
          enum:
            - pending
            - review
            - approved
            - declined
            - expired
            - superseded
          description: >-
            Actúa solo ante `approved`. `review` espera la revisión de tu
            equipo. `declined` no es definitivo mientras `verification_url`
            funcione: la persona puede volver a intentarlo y la verificación
            adicional vuelve a `pending`. `superseded` significa que otra
            comprobación asumió su verificación, o que el resultado no
            correspondía a esta verificación adicional: crea una nueva.
          example: pending
        level:
          type: string
          nullable: true
          enum:
            - liveness
            - liveness_face_match
            - full_id
            - null
          description: El nivel que alcanzó la verificación, una vez aprobada.
          example: null
        amount:
          type: string
          nullable: true
          description: El importe del pago, con dos decimales.
          example: '900.00'
        currency:
          type: string
          nullable: true
          example: USD
        created_at:
          type: string
          format: date-time
          example: '2026-10-17T10:41:14.894632Z'
        completed_at:
          type: string
          format: date-time
          nullable: true
          example: null
        expires_at:
          type: string
          format: date-time
          description: >-
            30 minutos después de la creación. Al leer una verificación step-up,
            primero se recopila cualquier resultado que haya alcanzado su
            verificación, por lo que todavía puede mostrar `approved`, `review`
            o `declined` después de ese momento; una que siga en `pending`
            muestra `expired`.
          example: '2026-10-17T11:11:14.894581Z'
    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
    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.