> ## Documentation Index
> Fetch the complete documentation index at: https://docs.outseta.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Begin authenticator-app (TOTP) enrollment during a forced-2FA login.

> Call this when `POST /api/v1/tokens` returned
`two_factor_enrollment_required` and the user chooses an authenticator
app. Post the enrollment token from that response:

```json
{ "enrollment_token": "eyJ..." }
```

A fresh shared secret is generated and returned in three forms so you
can present it however suits your client:

```json
{
  "challenge_token": "eyJ...",
  "secret": "JBSWY3DPEHPK3PXP",
  "otpauth_uri": "otpauth://totp/Acme:user@example.com?secret=...&issuer=Acme&...",
  "qr_code_png_base64": "iVBORw0KGgo...",
  "expires_in": 600
}
```

Have the user add the secret to their authenticator app (by scanning
`qr_code_png_base64`, opening `otpauth_uri`, or typing `secret`), then
confirm a code via `POST /api/v1/tokens/two-factor/enroll/totp/confirm`.
Returns `401` if the enrollment token is invalid/expired and `403` if
forced enrollment does not apply to this user. Rate limited to 5
requests per minute (`429`).



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/tokens/two-factor/enroll/totp/begin
openapi: 3.0.0
info:
  title: Outseta API
  description: >-
    Outseta REST API. See the [API
    overview](https://docs.outseta.com/api-reference/overview) for
    authentication, field selection, pagination, filtering, errors, rate limits
    and webhooks.
  version: v1
servers:
  - url: https://{subdomain}.outseta.com
    description: Your Outseta account
    variables:
      subdomain:
        default: your-subdomain
        description: >-
          Your Outseta account subdomain — the part before ".outseta.com" in
          your admin URL.
security: []
paths:
  /api/v1/tokens/two-factor/enroll/totp/begin:
    post:
      tags:
        - Public
      summary: Begin authenticator-app (TOTP) enrollment during a forced-2FA login.
      description: |-
        Call this when `POST /api/v1/tokens` returned
        `two_factor_enrollment_required` and the user chooses an authenticator
        app. Post the enrollment token from that response:

        ```json
        { "enrollment_token": "eyJ..." }
        ```

        A fresh shared secret is generated and returned in three forms so you
        can present it however suits your client:

        ```json
        {
          "challenge_token": "eyJ...",
          "secret": "JBSWY3DPEHPK3PXP",
          "otpauth_uri": "otpauth://totp/Acme:user@example.com?secret=...&issuer=Acme&...",
          "qr_code_png_base64": "iVBORw0KGgo...",
          "expires_in": 600
        }
        ```

        Have the user add the secret to their authenticator app (by scanning
        `qr_code_png_base64`, opening `otpauth_uri`, or typing `secret`), then
        confirm a code via `POST /api/v1/tokens/two-factor/enroll/totp/confirm`.
        Returns `401` if the enrollment token is invalid/expired and `403` if
        forced enrollment does not apply to this user. Rate limited to 5
        requests per minute (`429`).
      operationId: TokenTwoFactorEnrollment_BeginTotp
      parameters:
        - name: data
          in: query
          required: true
          schema:
            nullable: true
          x-position: 1
      responses:
        '200':
          description: The shared secret and enrollment-test challenge are returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TwoFactorTotpEnrollmentPayload'
        '401':
          description: The enrollment token is missing, invalid or expired.
          content:
            application/json:
              schema:
                type: string
                example: string
        '403':
          description: Forced 2FA enrollment does not apply to this user.
          content:
            application/json:
              schema:
                type: string
                example: string
components:
  schemas:
    TwoFactorTotpEnrollmentPayload:
      type: object
      description: >-
        Returned from POST /api/v1/tokens/two-factor/enroll/totp/begin when a

        user forced into 2FA chooses to enroll an authenticator app. Carries the

        shared secret in the three forms a client may need to present it, plus
        the

        challenge token the user's first generated code is confirmed against.
        The

        property names are snake_case to match the wire format of the other
        token

        endpoints (see TokenPayload).
      example:
        challenge_token: string
        secret: string
        otpauth_uri: string
        qr_code_png_base64: string
        expires_in: 0
      additionalProperties: false
      properties:
        challenge_token:
          type: string
          description: |-
            Short-lived signed JWT identifying the enrollment-test challenge.
            Echo it back to POST /api/v1/tokens/two-factor/enroll/totp/confirm
            along with the first code from the authenticator app.
          nullable: true
        secret:
          type: string
          description: >-
            The Base32-encoded shared secret. Offer this for manual entry by
            users

            who cannot scan the QR code.
          nullable: true
        otpauth_uri:
          type: string
          description: >-
            The full otpauth://totp/... URI encoding the secret, issuer and

            parameters. Most authenticator apps add an account directly from
            this.
          nullable: true
        qr_code_png_base64:
          type: string
          description: |-
            A QR code rendering of otpauth_uri as a PNG, Base64
            encoded — render it as an <img> for the user to scan.
          nullable: true
        expires_in:
          type: integer
          description: Seconds until the enrollment-test challenge expires (600).
          format: int32

````

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