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

# Step-Up-Status abrufen | Didit Authentication API

> GET /step-up/{step_up_id}/ liefert Status, Methode und Stufe eines Didit Step-Ups. Sensible Aktion nur bei Status genehmigt ausführen.

> [!WARNING]
>
> Die Authentifizierung ist neu. Diese Endpoints werden vom Aussteller Ihrer Anwendung bereitgestellt, etwa `https://<name>.auth.didit.me`, und akzeptieren niemals Ihren API-Schlüssel für Didit.

Ein Step-up gehört zu der Sitzung, die ihn erstellt hat. Das Access-Token einer anderen Sitzung erhält eine `404`-Antwort. Ein Step-up im Status `pending` gibt nach Ablauf seiner 30 Minuten den Status `expired` zurück.


## OpenAPI

````yaml de/openapi-authentication.json GET /step-up/{step_up_id}/
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Die serverseitigen Endpoints von Didit Authentication, dem Anmeldeprodukt
    für die Endbenutzer Ihrer Anwendung. Authentication ist **neu** und geht mit
    dem Release 2026-11-01 in Produktion.


    ## Basis-URL


    Jede Anwendung ist ihr eigener OpenID Connect Issuer, und jeder unten
    aufgeführte Endpoint wird unter dem Stamm dieses Issuers bereitgestellt:


    - `https://<name>.auth.didit.me` für eine Live-Anwendung oder
    `https://<name>.sandbox.auth.didit.me` für eine Sandbox-Anwendung.

    - Ihre eigene benutzerdefinierte Domain, sobald sie aktiv ist. Sie ersetzt
    dann den Standard-Host als Issuer: Neue Token geben sie in `iss` an,
    Discovery verweist auf sie und der veröffentlichbare Schlüssel ändert sich.
    Zugriffstoken, die unter dem Standard-Host ausgestellt wurden, schlagen bei
    `/session/`, `/step-up/` und `/monitoring-token/` fehl, bis sie aktualisiert
    werden.


    Live und Sandbox sind separate Anwendungen, also separate Issuer mit
    separaten Schlüsseln. Der veröffentlichbare Schlüssel lautet `pk_live_`
    (Live) oder `pk_test_` (Sandbox), gefolgt von der Base64url-Codierung ohne
    Padding des Issuers ohne abschließenden Schrägstrich: Decodieren Sie ihn, um
    den Issuer zu ermitteln. Es handelt sich um eine öffentliche Kennung, nicht
    um Anmeldedaten.


    Dieselben JSON-Endpoints werden auch unter
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`
    bereitgestellt. Token geben immer den obigen Issuer an, unabhängig davon,
    welche Adresse sie ausgestellt hat.


    ## Anmeldedaten


    Diese Endpoints akzeptieren niemals Ihren Didit-API-Schlüssel oder ein
    Konsolen-Token.


    - Discovery, das JWKS und `POST /token/` erfordern keine Anmeldedaten.
    Clients sind öffentlich: Es gibt kein Client-Secret, und ein
    Autorisierungscode ist an seinen PKCE-Verifier (`S256`) gebunden.
    `client_id` ist Ihre Anwendungs-ID.

    - `/session/`, `/step-up/` und `/monitoring-token/` erfordern das
    Zugriffstoken der Person: `Authorization: Bearer <access_token>`. Jeder
    erfolgreiche Aufruf zählt als Aktivität in der Sitzung und setzt daher den
    Inaktivitäts-Timeout der Sitzung zurück.


    ## Request-Bodys


    Jeder Endpoint, der einen Body akzeptiert, unterstützt JSON-, form-codierte
    und multipart-Bodys. Dieses Dokument führt JSON sowie form-codierte Anfragen
    für `POST /token/` auf, wie es von OAuth-Clients gesendet wird. Ein Feld,
    das der Endpoint nicht akzeptiert, führt zu `400 {"<field>":
    "unknown_field"}`.


    ## Token


    - **Access-Token**: ein ES256-JWT mit dem Header `typ: at+jwt`, maximal 5
    Minuten gültig und niemals länger als seine Sitzung. Claims:
    `AccessTokenClaims`.

    - **ID-Token**: ein ES256-JWT mit dem Header `typ: JWT`. Claims:
    `IDTokenClaims`. Es wird niemals als Zugriffstoken akzeptiert.

    - **Refresh-Token**: eine zufällige Zeichenfolge, die bei jeder Verwendung
    rotiert. Das erneute Senden eines bereits verwendeten Refresh-Tokens
    widerruft die Sitzung.


    Verifizieren Sie ein Token mit den Schlüsseln aus `GET
    /.well-known/jwks.json`: Der Algorithmus muss `ES256` sein, `typ` muss mit
    dem Token-Typ übereinstimmen, `iss` muss dem von Ihnen konfigurierten Issuer
    entsprechen und `aud` Ihrer Anwendungs-ID. Eine Offline-Verifizierung
    erkennt eine widerrufene Sitzung erst nach Ablauf ihres Zugriffstokens; `GET
    /session/` ist die sofortige Prüfung.


    ## Fehler


    | Body | Wann |

    | --- | --- |

    | `{"error": "<code>"}` | Fehler von `POST /token/`, alle mit Status `400`,
    im Body-Format von [RFC 6749 Abschnitt
    5.2](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client` und Didits `mfa_required`. Dienstfehler:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` oder `{"<field>": "<code>"}` | Ein
    Anfragefeld hat die Validierung nicht bestanden. `non_field_errors` benennt
    eine feldübergreifende Regel und `unknown_field` ein Feld, das der Endpoint
    nicht akzeptiert. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (unbekannte Anwendung oder Step-Up) und `429`
    (Rate-Limit). Außerdem `400` für einen Body, der nicht geparst werden kann
    (`JSON parse error - ...`), `405` für eine Methode, die der Endpoint nicht
    bedient, und `415` für einen nicht unterstützten `Content-Type`. |


    Ein `401` enthält außerdem `WWW-Authenticate: Bearer`, und ein `429` enthält
    `Retry-After` in Sekunden.


    Zwei Ablehnungen erfolgen nicht als JSON. Eine Adresse, die kein Issuer ist,
    wird abgelehnt, bevor sie diese Endpoints erreicht, beispielsweise mit einer
    leeren `404`-Antwort für einen ungenutzten `*.auth.didit.me`-Namen. Eine
    `step_up_id`, die keine UUID ist, erhält eine `404`-Seite.


    ## Rate-Limits


    Eine Anfrage muss zwei Ebenen durchlaufen.


    **Endpoint-Limits**, gezählt pro Client-IP-Adresse, pro Anwendung und pro
    Endpoint:


    - Discovery und das JWKS: 1.200 Anfragen pro Minute und 12.000 pro Stunde.

    - Jeder andere Endpoint: 30 Anfragen pro Minute und 300 pro Stunde. `GET`
    und `DELETE /session/` teilen sich eine Zählung.


    Bei Überschreitung eines Limits: `429 {"detail": "Too many requests from
    this IP address. Please wait before trying again. Expected available in 60
    seconds."}`, oder `3600 seconds` für das stündliche Limit.


    **Bot-Schutz**, bei jedem `POST` und `DELETE`. Seine Buckets werden von
    allen `POST`- und `DELETE`-Anfragen der Anwendung geteilt, einschließlich
    der gehosteten Anmeldeschritte, und füllen sich kontinuierlich wieder auf:


    - 60 Anfragen pro Minute pro Client-IP-Adresse.

    - 30 Anfragen pro Minute pro Gerät für Anfragen, die ihr Gerät
    identifizieren, wie dies bei Browsern und nativen SDKs der Fall ist.

    - 3.000 Anfragen pro Minute für die gesamte Anwendung über alle IP-Adressen
    hinweg. Token-Aktualisierungen (`POST /token/` mit
    `grant_type=refresh_token`) greifen stattdessen auf einen eigenen Bucket zu:
    6.000 pro Minute für die gesamte Anwendung.


    Bei Überschreitung eines Buckets: `429 {"detail": "rate_limited Expected
    available in N seconds."}` (`1 second.` wenn N gleich 1 ist). Der Bucket pro
    IP erstreckt sich über alle Endpoints, sodass eine einzelne Adresse, die
    Token-, Step-Up- und Abmeldeaufrufe mischt, ihn leeren kann, bevor sie ein
    Endpoint-Limit erreicht. Der Anwendungs-Bucket zählt jeden Client der
    Anwendung, einschließlich Browsern.


    Beide Ebenen antworten, bevor der Endpoint ausgeführt wird. Eine Anfrage,
    die `429` erhalten hat, wurde also nicht ausgeführt: Wiederholen Sie sie
    nach `Retry-After`, einschließlich einer Token-Aktualisierung.


    ## Browser-Anfragen


    Eine Anfrage, die einen `Origin`-Header enthält, muss von einem der
    anwendungseigenen Origins oder ihren erlaubten Origins stammen, andernfalls
    erhält sie `403 origin_not_allowed`. Server-zu-Server-Anfragen senden keinen
    `Origin`-Header.


    ## Hier nicht behandelt


    Diese Routen bedienen die gehosteten Seiten, die Browser- und nativen SDKs
    sowie KI-Agenten. Sie sind nicht Teil des Serververtrags und werden von
    Server-SDKs nicht aufgerufen:


    - Anmeldeschritte: `POST /authorize/`, `POST /password/`, `/email/*`,
    `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`, `/social/*` und
    `/protection/complete/`.

    - Gehostete Seiten und Callbacks: `/sign-in`, `/magic`, `/invite`, `/reset`,
    `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/` und die nativen
    App-Zuordnungsdateien unter `/.well-known/`.

    - Agentenzugriff: `/agents/*` und `/grants/`, einschließlich `GET
    /agents/session/`, der Live-Prüfung für das Zugriffstoken eines KI-Agenten.
    Agentenzugriff ist nicht Teil dieser Version des Vertrags.

    - Die Konsolen-Verwaltungs-API für Authentication, die Konsolensitzungen
    verwendet.


    Authentication-Ereignisse werden derzeit noch nicht als Webhooks zugestellt,
    daher definiert dieses Dokument keinen Webhook.
servers:
  - url: https://{issuer}
    description: 'Der Aussteller Ihrer Anwendung: ihr Anmeldeursprung.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          Der Host des Ausstellers: `<name>.auth.didit.me` (Produktion),
          `<name>.sandbox.auth.didit.me` (Sandbox) oder Ihre aktive
          benutzerdefinierte Domain.
security: []
tags:
  - name: Issuer
    description: Discovery- und Signaturschlüssel zur Überprüfung von Tokens.
  - name: Tokens
    description: Der Autorisierungscode und Refresh-Grants.
  - name: Sessions
    description: Die Sitzung hinter einem Zugriffstoken prüfen und beenden.
  - name: Step-ups
    description: Verifizierung vor einer sensiblen Aktion.
  - name: Monitoring
    description: Geräte-Anmeldedaten für Transaktionsüberwachungs-Ereignisse.
paths:
  /step-up/{step_up_id}/:
    get:
      tags:
        - Step-ups
      summary: Höhere Verifizierungsstufe abrufen
      description: >-
        Der aktuelle Status des Step-ups. Rufen Sie ihn mit einem Zugriffstoken
        derselben Sitzung auf, die das Step-up erstellt hat, und handeln Sie
        nur, wenn `status` auf `approved` steht.
      operationId: authentication_retrieve_step_up
      parameters:
        - name: step_up_id
          in: path
          required: true
          description: >-
            Die `id` von `POST /step-up/`, außerdem der Abfrageparameter
            `step_up` auf Ihrer `return_to`. Ein Wert, der keine UUID ist, führt
            zu einer `404`-Seite, kein JSON.
          schema:
            type: string
            format: uuid
          example: 94efc2c3-ca84-42fe-900b-6fb61669a7a1
      responses:
        '200':
          description: Das Step-up.
          headers:
            Cache-Control:
              description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
              schema:
                type: string
                example: no-store
            Pragma:
              description: Immer `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StepUp'
              examples:
                Approved:
                  summary: 'Genehmigt: fortfahren'
                  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: Noch nicht abgeschlossen
                  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: >-
            Kein Step-Up mit dieser ID gehört zu dieser Sitzung oder die
            Anwendung ist unbekannt.
          headers:
            Cache-Control:
              description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
              schema:
                type: string
                example: no-store
            Pragma:
              description: Immer `no-cache`.
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Detail'
              examples:
                StepUpNotFound:
                  summary: Unbekanntes Step-up
                  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: Eine Verifizierung, die die Person vor der Aktion bestehen muss.
      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: >-
            Die Regel, die dies angefordert hat. Wenn mehrere zutreffen,
            diejenige mit der stärksten Methode.
          example: payout
        method:
          type: string
          enum:
            - liveness
            - selfie
            - full_id
          description: >-
            Was die Person tut: `liveness`, `selfie` (Liveness-Abgleich mit dem
            Gesicht, das Didit bereits vorliegen hat) oder `full_id` (Dokument
            und Selfie). Wenn Didit noch kein Gesicht für die Person vorliegen
            hat, wird `selfie` zu `full_id`, sobald die Person die
            `verification_url` öffnet.
          example: selfie
        status:
          type: string
          enum:
            - pending
            - review
            - approved
            - declined
            - expired
            - superseded
          description: >-
            Reagieren Sie nur auf `approved`. `review` wartet auf die
            Überprüfung durch Ihr Team. `declined` ist nicht endgültig, solange
            die `verification_url` funktioniert: Die Person kann es erneut
            versuchen, und das Step-up wechselt wieder zu `pending`.
            `superseded` bedeutet, dass eine andere Prüfung die Verifizierung
            übernommen hat oder das Ergebnis nicht zu diesem Step-up gehörte:
            Erstellen Sie ein neues.
          example: pending
        level:
          type: string
          nullable: true
          enum:
            - liveness
            - liveness_face_match
            - full_id
            - null
          description: Die Stufe, die die Verifizierung nach der Genehmigung erreicht hat.
          example: null
        amount:
          type: string
          nullable: true
          description: Der Auszahlungsbetrag, zwei Dezimalstellen.
          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 Minuten nach der Erstellung. Beim Auslesen einer Step-up-Prüfung
            wird zunächst jedes Ergebnis erfasst, das die Verifizierung erreicht
            hat, sodass danach weiterhin `approved`, `review` oder `declined`
            angezeigt werden kann; eine Prüfung, die noch `pending` ist, wird
            als `expired` angezeigt.
          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: Ein OAuth-Fehler (RFC 6749 Abschnitt 5.2) oder ein Dienstfehler.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  responses:
    InvalidToken:
      description: >-
        Das Zugriffstoken fehlt, ist fehlerhaft, abgelaufen, von einem anderen
        Aussteller oder Schlüssel signiert, ein ID-Token, ein Agent-Token oder
        wurde durch einen Refresh ersetzt; oder seine Sitzung wurde widerrufen,
        ist wegen Inaktivität abgelaufen, hat ihre Lebensdauer überschritten
        oder erfüllt Ihre MFA-Richtlinie nicht mehr, oder die Person wurde
        gesperrt bzw. ihre E-Mail ist nicht mehr verifiziert. Leiten Sie die
        Person erneut durch die Anmeldung.
      headers:
        WWW-Authenticate:
          description: '`Bearer`.'
          schema:
            type: string
            example: Bearer
        Cache-Control:
          description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Immer `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            InvalidToken:
              summary: Abgelehntes Zugriffstoken
              value:
                detail: invalid_token
    OriginNotAllowed:
      description: >-
        Die Anfrage enthielt einen `Origin`, der weder der anwendungseigene ist
        noch zu den zulässigen Origins gehört. Server-Anfragen senden keinen
        `Origin`.
      headers:
        Cache-Control:
          description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Immer `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            OriginNotAllowed:
              summary: Origin nicht zulässig
              value:
                detail: origin_not_allowed
    RateLimited:
      description: >-
        Zu viele Anfragen von dieser IP-Adresse für diesen Endpoint, oder bei
        einem `POST` oder `DELETE` ist ein Bot-Schutz-Bucket leer. Es wurde
        nichts ausgeführt: Warten Sie `Retry-After` Sekunden und versuchen Sie
        es dann erneut.
      headers:
        Retry-After:
          description: Sekunden, die vor einem Wiederholungsversuch gewartet werden müssen.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Immer `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            RateLimited:
              summary: Endpoint-Limit
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Bot-Schutz-Limit (POST und DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Ein Dienst, von dem die Anfrage abhängt, ist vorübergehend nicht
        verfügbar. Versuchen Sie es mit Backoff erneut.
      headers:
        Cache-Control:
          description: 'Immer `no-store`: Diese Antwort niemals zwischenspeichern.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Immer `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
          examples:
            TemporarilyUnavailable:
              summary: Später erneut versuchen
              value:
                error: temporarily_unavailable
  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Das Access Token der Person von `POST /token/`: ein ES256-JWT mit dem
        Header `typ: at+jwt`, gültig für maximal 5 Minuten. Nicht Ihr
        Didit-API-Schlüssel.

````

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