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

# Obter estado do step-up | API de Autenticação Didit

> GET /step-up/{step_up_id}/ devolve o estado, o método e o nível do step-up na Didit. Execute a ação sensível só quando o estado for aprovada.

> [!WARNING]
>
> A autenticação é uma novidade. Estes endpoints são servidos pelo emissor da sua aplicação, como `https://<name>.auth.didit.me`, e nunca aceitam a sua chave de API da Didit.

Um step-up pertence à sessão que o criou: o token de acesso de outra sessão recebe `404`. Um step-up com estado `pending` passa a `expired` ao fim de 30 minutos.


## OpenAPI

````yaml pt/openapi-authentication.json GET /step-up/{step_up_id}/
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Os endpoints do lado do servidor do Didit Authentication, o produto de
    início de sessão para os utilizadores finais da sua aplicação. O
    Authentication é **novo** e chega a produção na versão de 2026-11-01.


    ## URL base


    Cada aplicação é o seu próprio emissor OpenID Connect, e cada endpoint
    abaixo é disponibilizado na raiz desse emissor:


    - `https://<name>.auth.didit.me` para uma aplicação de produção, ou
    `https://<name>.sandbox.auth.didit.me` para uma aplicação de sandbox.

    - O seu próprio domínio personalizado, assim que estiver ativo. Este
    substitui o anfitrião predefinido como emissor: os novos tokens indicam-no
    em `iss`, a descoberta aponta para ele e a chave publicável é alterada. Os
    access tokens emitidos sob o anfitrião predefinido falham em `/session/`,
    `/step-up/` e `/monitoring-token/` até serem renovados.


    Produção e sandbox são aplicações separadas, pelo que são emissores
    separados com chaves separadas. A chave publicável é `pk_live_` (produção)
    ou `pk_test_` (sandbox) seguida pela codificação base64url sem preenchimento
    do emissor, sem barra final: descodifique-a para encontrar o emissor.
    Trata-se de um identificador público, não de uma credencial.


    Os mesmos endpoints JSON também são disponibilizados em
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`. Os tokens
    indicam sempre o emissor acima, independentemente do endereço que os emitiu.


    ## Credenciais


    Estes endpoints nunca aceitam a sua chave de API da Didit nem um token da
    consola.


    - A descoberta, o JWKS e o `POST /token/` não requerem credenciais. Os
    clientes são públicos: não existe segredo de cliente, e um código de
    autorização está vinculado ao seu verificador PKCE (`S256`). O `client_id` é
    o ID da sua aplicação.

    - `/session/`, `/step-up/` e `/monitoring-token/` aceitam o access token da
    pessoa: `Authorization: Bearer <access_token>`. Cada chamada bem-sucedida
    conta como atividade na sessão, reiniciando o tempo limite de inatividade da
    sessão.


    ## Corpos dos pedidos


    Todos os endpoints que aceitam um corpo suportam corpos em JSON, codificados
    como formulário e multipart. Este documento lista JSON, além de codificados
    como formulário para `POST /token/` tal como os clientes OAuth os enviam. Um
    campo que o endpoint não aceite recebe `400 {"<field>": "unknown_field"}`.


    ## Tokens


    - **Access token**: um JWT ES256 com o cabeçalho `typ: at+jwt`, válido
    durante no máximo 5 minutos e nunca mais do que a sua sessão. Declarações:
    `AccessTokenClaims`.

    - **ID token**: um JWT ES256 com o cabeçalho `typ: JWT`. Declarações:
    `IDTokenClaims`. Nunca é aceite como um access token.

    - **Refresh token**: uma string aleatória que é substituída a cada
    utilização. O envio de um refresh token já utilizado revoga a sessão.


    Verifique um token com as chaves de `GET /.well-known/jwks.json`: o
    algoritmo deve ser `ES256`, `typ` deve corresponder ao tipo de token, `iss`
    deve ser igual ao emissor que configurou e `aud` ao ID da sua aplicação. A
    verificação offline só deteta uma sessão revogada após a expiração do
    respetivo access token; `GET /session/` é a verificação instantânea.


    ## Erros


    | Corpo | Quando |

    | --- | --- |

    | `{"error": "<code>"}` | Erros de `POST /token/`, todos com o estado `400`,
    no formato do corpo definido na [secção 5.2 do RFC
    6749](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client` e `mfa_required` da Didit. Erros de serviço:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` ou `{"<field>": "<code>"}` | A validação de
    um campo do pedido falhou. `non_field_errors` indica uma regra entre campos,
    e `unknown_field` um campo que o endpoint não aceita. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (aplicação desconhecida ou step-up
    desconhecido) e `429` (limite de pedidos). Também `400` para um corpo que
    não possa ser analisado (`JSON parse error - ...`), `405` para um método que
    o endpoint não disponibiliza e `415` para um `Content-Type` não suportado. |


    Um `401` também inclui `WWW-Authenticate: Bearer`, e um `429` inclui
    `Retry-After` em segundos.


    Duas recusas não estão em JSON. Um endereço que não seja um emissor é
    recusado antes de chegar a estes endpoints, por exemplo com um `404` vazio
    para um nome `*.auth.didit.me` não utilizado. Um `step_up_id` que não seja
    um UUID recebe uma página `404`.


    ## Limites de pedidos


    Um pedido tem de passar por duas camadas.


    **Limites de endpoint**, contabilizados por endereço IP do cliente, por
    aplicação e por endpoint:


    - Descoberta e o JWKS: 1 200 pedidos por minuto e 12 000 por hora.

    - Todos os outros endpoints: 30 pedidos por minuto e 300 por hora. `GET` e
    `DELETE /session/` partilham uma única contagem.


    Ao exceder um limite: `429 {"detail": "Too many requests from this IP
    address. Please wait before trying again. Expected available in 60
    seconds."}`, ou `3600 seconds` para o limite horário.


    **Proteção contra bots**, em cada `POST` e `DELETE`. Os seus contentores são
    partilhados por todos os pedidos `POST` e `DELETE` da aplicação, incluindo
    os passos de início de sessão alojados, e reabastecem continuamente:


    - 60 pedidos por minuto por endereço IP do cliente.

    - 30 pedidos por minuto por dispositivo, para pedidos que identificam o
    respetivo dispositivo, tal como fazem os SDKs nativos e para navegadores.

    - 3 000 pedidos por minuto para toda a aplicação, em todos os endereços IP.
    As renovações de tokens (`POST /token/` com `grant_type=refresh_token`)
    recorrem a um contentor próprio: 6 000 por minuto para toda a aplicação.


    Ao exceder um contentor: `429 {"detail": "rate_limited Expected available in
    N seconds."}`, (`1 second.` quando N é 1). O contentor por IP abrange vários
    endpoints, pelo que um único endereço que misture chamadas de token, step-up
    e encerramento de sessão pode esgotá-lo antes de atingir qualquer limite de
    endpoint. O contentor da aplicação contabiliza todos os clientes da
    aplicação, incluindo navegadores.


    Ambas as camadas respondem antes de o endpoint ser executado, pelo que um
    pedido que tenha recebido `429` não foi executado: tente novamente após o
    tempo indicado em `Retry-After`, incluindo uma renovação.


    ## Pedidos do navegador


    Um pedido que contenha um cabeçalho `Origin` deve provir de uma das origens
    da própria aplicação ou das suas origens permitidas, caso contrário recebe
    `403 origin_not_allowed`. Os pedidos servidor a servidor não enviam
    `Origin`.


    ## Não abrangido aqui


    Estas rotas servem as páginas alojadas, os SDKs nativos e para navegadores,
    e agentes de IA. Não fazem parte do contrato de servidor, e os SDKs de
    servidor não as chamam:


    - Passos de início de sessão: `POST /authorize/`, `POST /password/`,
    `/email/*`, `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`,
    `/social/*` e `/protection/complete/`.

    - Páginas alojadas e retornos de chamada: `/sign-in`, `/magic`, `/invite`,
    `/reset`, `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/` e os ficheiros
    de associação de aplicações nativas em `/.well-known/`.

    - Acesso de agentes: `/agents/*` e `/grants/`, incluindo `GET
    /agents/session/`, a verificação em tempo real do access token de um agente
    de IA. O acesso de agentes não faz parte desta versão do contrato.

    - A API de gestão da consola para o Authentication, que aceita sessões da
    consola.


    Os eventos de autenticação ainda não são entregues como webhooks, pelo que
    este documento não define nenhum webhook.
servers:
  - url: https://{issuer}
    description: 'O emissor da sua aplicação: a sua origem de início de sessão.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          O host do emissor: `<name>.auth.didit.me` (produção),
          `<name>.sandbox.auth.didit.me` (sandbox) ou o seu domínio
          personalizado ativo.
security: []
tags:
  - name: Issuer
    description: Chaves de descoberta e de assinatura, para verificar tokens.
  - name: Tokens
    description: As concessões de código de autorização e de atualização.
  - name: Sessions
    description: Verificar e terminar a sessão associada a um token de acesso.
  - name: Step-ups
    description: Verificação antes de uma ação sensível.
  - name: Monitoring
    description: Credenciais do dispositivo para eventos de monitorização de transações.
paths:
  /step-up/{step_up_id}/:
    get:
      tags:
        - Step-ups
      summary: Obter escalonamento
      description: >-
        O estado atual do step-up. Chame-o com um token de acesso da mesma
        sessão que criou o step-up e atue apenas quando o `status` for
        `approved`.
      operationId: authentication_retrieve_step_up
      parameters:
        - name: step_up_id
          in: path
          required: true
          description: >-
            O `id` de `POST /step-up/`, também o parâmetro de consulta `step_up`
            no seu `return_to`. Um valor que não seja um UUID recebe uma página
            `404`, não JSON.
          schema:
            type: string
            format: uuid
          example: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
      responses:
        '200':
          description: O step-up.
          headers:
            Cache-Control:
              description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
              schema:
                type: string
                example: no-store
            Pragma:
              description: Sempre `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StepUp'
              examples:
                Approved:
                  summary: 'Aprovada: avançar'
                  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: Ainda não terminada
                  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: >-
            Nenhum step-up com este ID pertence a esta sessão, ou a aplicação é
            desconhecida.
          headers:
            Cache-Control:
              description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
              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:
                StepUpNotFound:
                  summary: Step-up desconhecido
                  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: Uma verificação pela qual a pessoa tem de passar antes da ação.
      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: >-
            A regra que o solicitou. Quando se aplicam várias, a que tiver o
            método mais forte.
          example: payout
        method:
          type: string
          enum:
            - liveness
            - selfie
            - full_id
          description: >-
            O que a pessoa faz: `liveness`, `selfie` (prova de vida comparada
            com o rosto que a Didit já possui) ou `full_id` (documento e
            selfie). Quando a Didit ainda não possui nenhum rosto da pessoa,
            `selfie` torna-se `full_id` assim que esta abre o
            `verification_url`.
          example: selfie
        status:
          type: string
          enum:
            - pending
            - review
            - approved
            - declined
            - expired
            - superseded
          description: >-
            Atue apenas sobre `approved`. `review` aguarda a revisão da sua
            equipa. `declined` não é definitivo enquanto `verification_url`
            estiver funcional: a pessoa pode tentar novamente e a verificação
            adicional regressa a `pending`. `superseded` significa que outra
            verificação assumiu o controlo da mesma, ou que o resultado não era
            para esta verificação adicional: crie uma nova.
          example: pending
        level:
          type: string
          nullable: true
          enum:
            - liveness
            - liveness_face_match
            - full_id
            - null
          description: O nível que a verificação atingiu, após ser aprovada.
          example: null
        amount:
          type: string
          nullable: true
          description: O montante do pagamento, com duas casas decimais.
          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 após a criação. A leitura de uma verificação adicional
            recolhe primeiro qualquer resultado a que a respetiva verificação
            tenha chegado, pelo que ainda pode devolver `approved`, `review` ou
            `declined` após este período; uma que ainda esteja `pending` devolve
            `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: Um erro de OAuth (RFC 6749 secção 5.2) ou um erro de serviço.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    InvalidToken:
      description: >-
        O token de acesso está em falta, malformado, expirado, assinado por
        outro emissor ou chave, é um token de ID, um token de agente, ou foi
        substituído por uma atualização; ou a sua sessão foi revogada, expirou
        por inatividade, ultrapassou a sua duração ou já não cumpre a sua
        política de MFA, ou a pessoa em questão foi bloqueada ou o respetivo
        e-mail já não está verificado. Envie a pessoa novamente pelo fluxo de
        início de sessão.
      headers:
        WWW-Authenticate:
          description: '`Bearer`.'
          schema:
            type: string
            example: Bearer
        Cache-Control:
          description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
          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 de acesso rejeitado
              value:
                detail: invalid_token
    OriginNotAllowed:
      description: >-
        O pedido continha um `Origin` que não é o da própria aplicação nem está
        entre as respetivas origens permitidas. Os pedidos de servidor não
        enviam `Origin`.
      headers:
        Cache-Control:
          description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
          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: Origem não permitida
              value:
                detail: origin_not_allowed
    RateLimited:
      description: >-
        Demasiados pedidos a partir deste endereço IP para este endpoint ou, num
        `POST` ou `DELETE`, um bucket de proteção contra bots está vazio. Nada
        foi executado: aguarde `Retry-After` segundos e, em seguida, tente
        novamente.
      headers:
        Retry-After:
          description: Segundos a aguardar antes de tentar novamente.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
          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: Limite de pedidos do endpoint
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Limite de proteção contra bots (POST e DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Um serviço do qual o pedido depende está temporariamente indisponível.
        Tente novamente com recuo progressivo.
      headers:
        Cache-Control:
          description: 'Sempre `no-store`: nunca guarde esta resposta em cache.'
          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: Tentar novamente mais tarde
              value:
                error: temporarily_unavailable
  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        O token de acesso da pessoa a partir de `POST /token/`: um JWT ES256 com
        cabeçalho `typ: at+jwt`, válido no máximo por 5 minutos. Não é a sua
        chave de API Didit.

````

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