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

> POST /step-up/ aplica les teves regles de step-up abans d'una acció sensible. Retorna required false o un URL de verificació per a la persona.

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

Els paràmetres de consulta `step_up` i `status` del teu `return_to` només indiquen a la teva aplicació que ho ha de consultar. Abans d'actuar, consulta el pas d'autenticació reforçada amb [Obtén un pas d'autenticació reforçada](https://docs.didit.me/ca/authentication/api-reference/retrieve-step-up.md) i continua només quan `status` sigui `approved`.


## OpenAPI

````yaml ca/openapi-authentication.json POST /step-up/
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:
  /step-up/:
    post:
      tags:
        - Step-ups
      summary: Crea un step-up
      description: >-
        Pregunta si la persona s'ha de verificar abans d'una acció sensible,
        utilitzant les regles d'escalada que has definit per a l'aplicació.


        - `200 {"required": false}`: no s'aplica cap regla, endavant.

        - `201`: envia la persona a `verification_url`. Tornarà a `return_to`
        amb `step_up=<id>&status=approved`, però aquesta consulta no demostra
        res: llegeix l'escalada amb `GET /step-up/{step_up_id}/` i actua només
        quan sigui `approved`.


        Una escalada mai permet l'acció per error: quan la verificació no està
        disponible, l'acció es manté bloquejada.
      operationId: authentication_create_step_up
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StepUpRequest'
            examples:
              Payout:
                summary: Abans d'un pagament
                value:
                  action: payout
                  amount: '900.00'
                  currency: USD
                  return_to: https://app.example.com/payouts/confirm
              Bank:
                summary: Abans de canviar un compte bancari
                value:
                  action: bank
                  return_to: https://app.example.com/settings/bank
      responses:
        '200':
          description: Cap regla no és aplicable.
          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/StepUpNotRequired'
              examples:
                NotRequired:
                  summary: Continuar
                  value:
                    required: false
        '201':
          description: La persona s'ha de verificar primer.
          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/StepUpRequired'
              examples:
                Required:
                  summary: Una selfie abans d'un pagament
                  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'
                    required: true
                    verification_url: >-
                      https://your-app.auth.didit.me/verify/?verification=1nSX7HJCXAP9XPA9AeJfQxIuPk2GkG0dGSOzCA2Zpww
                    expires_in: 1800
        '400':
          description: >-
            Falta un camp o no és vàlid. `return_to: invalid_redirect_uri`
            significa que s'aplica una regla i `return_to` no és un dels URI de
            redirecció de l'aplicació.
          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/FieldErrors'
              examples:
                MissingAmount:
                  summary: Un pagament sense import
                  value:
                    amount:
                      - required
                InvalidReturnTo:
                  summary: return_to no registrat
                  value:
                    return_to: invalid_redirect_uri
                UnknownAction:
                  summary: Acció no admesa
                  value:
                    action:
                      - '"withdraw" is not a valid choice.'
        '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:
    StepUpRequest:
      type: object
      description: L'acció sensible que la persona està a punt de dur a terme.
      required:
        - action
        - return_to
      additionalProperties: false
      properties:
        action:
          type: string
          enum:
            - payout
            - bank
            - contact
          description: >-
            `payout` (una retirada o transferència), `bank` (afegir o canviar un
            compte bancari) o `contact` (canviar un correu electrònic o número
            de telèfon). Una retirada també aplica la regla del dispositiu nou.
        amount:
          type: string
          pattern: ^[0-9]{1,16}(\.[0-9]{1,2})?$
          description: >-
            Obligatori per a `payout`: l'import, fins a dos decimals. També
            s'accepta un número JSON.
          example: '900.00'
        currency:
          type: string
          pattern: ^[A-Z]{3}$
          description: >-
            Codi ISO 4217 de `amount`. El valor per defecte és la moneda de la
            regla de pagament; un pagament en una altra moneda sempre es
            comprova.
          example: USD
        return_to:
          type: string
          maxLength: 2048
          description: >-
            On torna la persona després de verificar-se, amb
            `step_up=<id>&status=approved` afegit. Quan s'aplica una regla, ha
            de ser un dels URI de redirecció de l'aplicació; quan no se n'aplica
            cap, no es comprova.
          example: https://app.example.com/payouts/confirm
    StepUpNotRequired:
      type: object
      description: 'Cap regla no és aplicable: continua amb l''acció.'
      required:
        - required
      properties:
        required:
          type: boolean
          enum:
            - false
    StepUpRequired:
      description: Un nou pas addicional. Envia la persona a `verification_url`.
      allOf:
        - $ref: '#/components/schemas/StepUp'
        - type: object
          required:
            - required
            - verification_url
            - expires_in
          properties:
            required:
              type: boolean
              enum:
                - true
            verification_url:
              type: string
              format: uri
              description: >-
                La pàgina allotjada on la persona es verifica; obre-la al
                navegador de la persona. Funciona fins que l'autenticació
                reforçada (step-up) s'aprova o caduca, de manera que una persona
                rebutjada pot tornar-ho a intentar des d'allà.
              example: >-
                https://your-app.auth.didit.me/verify/?verification=1nSX7HJCXAP9XPA9AeJfQxIuPk2GkG0dGSOzCA2Zpww
            expires_in:
              type: integer
              description: 'Segons que el pas addicional roman obert: 1800.'
              example: 1800
    FieldErrors:
      title: Field errors
      type: object
      description: >-
        Errors de validació per camp. Un valor és una llista de missatges o un
        sol codi (`unknown_field`, `invalid_redirect_uri`). `non_field_errors`
        conté regles globals entre camps.
      additionalProperties:
        oneOf:
          - type: string
          - type: array
            items:
              type: string
    StepUp:
      type: object
      description: Una verificació que la persona ha de superar abans de l'acció.
      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 ho ha sol·licitat. Quan se n'apliquen diverses, la que
            té el mètode més fort.
          example: payout
        method:
          type: string
          enum:
            - liveness
            - selfie
            - full_id
          description: >-
            El que fa la persona: `liveness`, `selfie` (prova de vida comparada
            amb la cara que Didit ja té) o `full_id` (document i selfie). Quan
            Didit encara no té cap cara associada a la persona, `selfie` passa a
            ser `full_id` un cop obre la `verification_url`.
          example: selfie
        status:
          type: string
          enum:
            - pending
            - review
            - approved
            - declined
            - expired
            - superseded
          description: >-
            Actua només sobre `approved`. `review` espera la revisió del teu
            equip. `declined` no és definitiu mentre `verification_url`
            funcioni: la persona pot tornar-ho a provar, i el pas addicional
            torna a `pending`. `superseded` significa que una altra comprovació
            ha assumit la seva verificació, o que el resultat no era per a
            aquest pas addicional: crea'n un de nou.
          example: pending
        level:
          type: string
          nullable: true
          enum:
            - liveness
            - liveness_face_match
            - full_id
            - null
          description: El nivell que ha assolit la verificació, un cop aprovada.
          example: null
        amount:
          type: string
          nullable: true
          description: L'import del pagament, amb dos decimals.
          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 minuts després de la creació. En consultar un pas d'escalat
            (step-up), primer es recopila qualsevol resultat que hagi assolit la
            seva verificació, de manera que encara pot mostrar `approved`,
            `review` o `declined` després d'aquest temps; un que encara estigui
            en estat `pending` mostrarà `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 d'OAuth (RFC 6749, secció 5.2) o un error de servei.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    InvalidToken:
      description: >-
        El token d'accés falta, està mal format, ha caducat, està signat per un
        altre emissor o clau, és un token d'ID, és un token d'agent o s'ha
        substituït per un token de renovació; o la seva sessió s'ha revocat, ha
        caducat per inactivitat, ha superat la seva vida útil o ja no compleix
        la teva política de MFA, o la persona s'ha bloquejat o el seu correu
        electrònic ja no està verificat. Fes que la persona torni a iniciar
        sessió.
      headers:
        WWW-Authenticate:
          description: '`Bearer`.'
          schema:
            type: string
            example: Bearer
        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:
            InvalidToken:
              summary: Token d'accés rebutjat
              value:
                detail: invalid_token
    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
  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        El token d'accés de la persona procedent de `POST /token/`: un JWT ES256
        amb la capçalera `typ: at+jwt`, vàlid durant un màxim de 5 minuts. No és
        la teva clau d'API de Didit.

````

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