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

# Crear token de monitorización | Didit Authentication API

> POST /monitoring-token/ de Didit cambia un token de acceso por una credencial de 15 minutos vinculada a vendor_data y al origen del navegador.

> [!WARNING]
>
> La autenticación es nueva y este endpoint permanece desactivado hasta que Didit lo active: hasta entonces responde `503 monitoring_unavailable`.

Los SDK de navegador y nativos llaman a este endpoint desde el dispositivo de la persona; tu servidor no necesita hacerlo. Cada evento enviado con la credencial se registra en el `vendor_data` de la persona, independientemente de lo que declare el dispositivo.


## OpenAPI

````yaml es/openapi-authentication.json POST /monitoring-token/
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:
  /monitoring-token/:
    post:
      tags:
        - Monitoring
      summary: Crear un token de monitorización
      description: >-
        Intercambia el token de acceso de la persona por una credencial de
        dispositivo de corta duración, para que el navegador o la aplicación de
        la persona pueda enviar eventos de actividad a la monitorización de
        transacciones sin pasar por tu backend. La credencial está vinculada al
        `vendor_data` de la persona y al `Origin` de la solicitud.


        Los SDK de navegador y nativos llaman a este endpoint; los SDK de
        servidor no. Está desactivado hasta que Didit lo activa y, mientras
        tanto, responde `503 monitoring_unavailable`.
      operationId: authentication_create_monitoring_token
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitoringTokenRequest'
            example: {}
      responses:
        '201':
          description: Una credencial de dispositivo para la persona.
          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/MonitoringToken'
              examples:
                MonitoringToken:
                  summary: Una credencial para el navegador de la persona
                  value:
                    monitoring_token: mt_2f8c1d9e7b6a5f4e3d2c1b0a
                    expires_at: '2026-10-17T10:56:14Z'
                    allowed_event_categories:
                      - session
                      - gameplay
                      - bonus
                      - affiliate
                      - payment
                      - dispute
                      - responsible_gambling
                      - custom
                    max_uses: 1000
                    bind_to_origin: https://app.example.com
                    vendor_data: user-42
        '400':
          description: El cuerpo incluía un campo. Envía un objeto vacío.
          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/FieldErrors'
              examples:
                UnknownField:
                  summary: Un campo del cuerpo
                  value:
                    vendor_data: unknown_field
        '401':
          $ref: '#/components/responses/InvalidToken'
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '409':
          description: >-
            La monitorización de eventos está desactivada para la aplicación.
            Activa la ingesta de eventos en la configuración de monitorización
            de transacciones.
          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:
                MonitoringDisabled:
                  summary: Ingesta de eventos desactivada
                  value:
                    error: monitoring_disabled
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          description: >-
            Los tokens de monitorización no están habilitados, la monitorización
            no pudo emitir uno (`monitoring_unavailable`) o un servicio del que
            depende la solicitud no está disponible temporalmente
            (`temporarily_unavailable`). Vuelve a intentarlo más tarde.
          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:
                MonitoringUnavailable:
                  summary: No disponible
                  value:
                    error: monitoring_unavailable
                TemporarilyUnavailable:
                  summary: Reintentar más tarde
                  value:
                    error: temporarily_unavailable
      security:
        - AccessToken: []
components:
  schemas:
    MonitoringTokenRequest:
      type: object
      description: 'Vacío: el token de acceso identifica a la persona.'
      additionalProperties: false
      properties: {}
    MonitoringToken:
      type: object
      description: >-
        Una credencial de dispositivo de corta duración para enviar a la
        monitorización de transacciones los eventos de actividad de la persona
        desde su dispositivo. No está vinculada a la sesión: sigue siendo válida
        hasta `expires_at`, incluso después de cerrar la sesión.
      required:
        - monitoring_token
        - expires_at
        - allowed_event_categories
        - max_uses
        - bind_to_origin
        - vendor_data
      properties:
        monitoring_token:
          type: string
          description: La credencial del dispositivo. Trátala como un secreto.
          example: mt_2f8c1d9e7b6a5f4e3d2c1b0a
        expires_at:
          type: string
          format: date-time
          description: Como máximo 15 minutos después de su emisión.
          example: '2026-10-17T10:56:14Z'
        allowed_event_categories:
          type: array
          items:
            type: string
          description: >-
            Las categorías de eventos que puede enviar. Los eventos de
            autenticación y seguridad siempre provienen de Didit, nunca del
            dispositivo.
          example:
            - session
            - gameplay
            - bonus
            - affiliate
            - payment
            - dispute
            - responsible_gambling
            - custom
        max_uses:
          type: integer
          example: 1000
        bind_to_origin:
          type: string
          nullable: true
          description: >-
            El origen del navegador desde el que funciona la credencial: el
            `Origin` de la solicitud, o `null` cuando no había ninguno.
          example: https://app.example.com
        vendor_data:
          type: string
          description: >-
            La persona para la que se registra cada evento, independientemente
            de lo que envíe el dispositivo.
          example: user-42
    FieldErrors:
      title: Field errors
      type: object
      description: >-
        Errores de validación por campo. Un valor es una lista de mensajes o un
        único código (`unknown_field`, `invalid_redirect_uri`).
        `non_field_errors` contiene las reglas que afectan a varios campos.
      additionalProperties:
        oneOf:
          - type: string
          - type: array
            items:
              type: string
    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
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
  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.
  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.