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

# Begin TOTP Enrollment

> This endpoint allows users to start adding an authenticator app (TOTP) factor.

```http theme={null}
POST /api/v1/account/2fa/totp/begin
```

Starts adding an authenticator app as a [two-factor](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor) factor. The response has a new TOTP secret. Add it to an authenticator app, then call [Finish TOTP enrollment](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor/finish-totp-enrollment.md) with a code within 10 minutes.

#### Operation Type (for Signing)

| Header Field | Type | Content |
| - | - | - |
| `"type"` | string | `"begin_totp_enrollment"` |

#### Request Body

<table><thead><tr><th width="176">Field</th><th width="98">Type</th><th width="95">Need</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>`"account"`</td><td>string</td><td>required</td><td>User's wallet address</td><td>`42trU9A5...`</td></tr><tr><td>`"signature"`</td><td>string</td><td>required</td><td>Cryptographic signature</td><td>`5j1Vy9Uq...`</td></tr><tr><td>`"timestamp"`</td><td>integer</td><td>required</td><td>Current timestamp in milliseconds</td><td>`1716200000000`</td></tr><tr><td>`"label"`</td><td>string</td><td>required</td><td>Your name for the factor. 1 to 64 characters, with no control characters and no leading or trailing spaces</td><td>`Authenticator app`</td></tr><tr><td>`"expiry_window"`</td><td>integer</td><td>optional</td><td>Signature expiry in milliseconds</td><td>`30000`</td></tr><tr><td>`"two_factor"`</td><td>object</td><td>conditional</td><td>Proof. Required while 2FA is on. Not part of the signed payload. See [Proofs](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor#proofs)</td><td>`{"type": "totp", "code": "123456"}`</td></tr></tbody></table>

```json theme={null}
{
  "account": "42trU9A5...",
  "signature": "5j1Vy9Uq...",
  "timestamp": 1716200000000,
  "label": "Authenticator app",
  "expiry_window": 30000
}
```

Sign this request with the account's own key. Agent wallets cannot sign it. The account must be a main account.

If 2FA is already on, send a proof in `two_factor`. Any proof type works, including a recovery key. After the proof passes, you can send the same request with the same `label` again for 5 minutes without a new proof.

An account has one authenticator app. If it already has one, the new one replaces it when you finish enrollment.

#### Signing

Sign `label` as the `data` object. Do not sign `two_factor`. For the request above, the message to sign is:

```json theme={null}
{"data":{"label":"Authenticator app"},"expiry_window":30000,"timestamp":1716200000000,"type":"begin_totp_enrollment"}
```

#### Response

* Status 200: Enrollment started

```json theme={null}
{
  "success": true,
  "data": {
    "enrollment_id": "8f14e45f-ceea-467a-9575-0b3a8d6c3f1e",
    "secret": "JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP",
    "otpauth_uri": "otpauth://totp/Pacifica:42trU9...xNc6?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP&issuer=Pacifica"
  },
  "error": null,
  "code": null
}
```

| Field | Type | Description |
| - | - | - |
| `'enrollment_id'` | string | Enrollment ID (UUID). Send it to [Finish TOTP enrollment](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor/finish-totp-enrollment.md) within 10 minutes |
| `'secret'` | string | TOTP secret in base32. Type it into an authenticator app if you cannot scan a QR code |
| `'otpauth_uri'` | string | `otpauth://` URI with the secret. Show it as a QR code for an authenticator app |

Codes use SHA-1, 6 digits, and a 30-second period. The authenticator app shows the issuer `Pacifica` and a short form of your wallet address.

Keep the secret private. Anyone who has it can make codes.

* Status 400: Invalid request parameters, label, or signature
* Status 401: The proof is wrong, expired, or already used
* Status 403: The account is a subaccount, or it does not exist
* Status 422: The account has no room for another factor (`a user can have at most 8 factors`)
* Status 428: 2FA is on, and the request has no `two_factor`

```json theme={null}
{
  "success": false,
  "data": null,
  "error": "two-factor proof is required",
  "code": 428,
  "error_id": "second_factor_required"
}
```

* Status 429: Too many proof attempts, or more than 20 enrollments started in 10 minutes
* Status 500: Internal server error
* Status 503: The two-factor service is unavailable. Retry later

#### Code Example (Python)

```python theme={null}
import requests

payload = {
    "account": "42trU9A5...",
    "signature": "5j1Vy9Uq...",
    "timestamp": 1716200000000,
    "label": "Authenticator app"
}

response = requests.post(
    "/api/v1/account/2fa/totp/begin",
    json=payload,
    headers={"Content-Type": "application/json"}
)

data = response.json()
```


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