POST /api/me/2fa/enroll — begin enrolment. Returns the otpauth provisioning URI (for the QR code) and the base32 secret (for manual entry). The secret is stored encrypted+pending; 2FA is not yet armed until confirmed.
POST
/api/me/2fa/enroll
const url = 'https://example.com/api/me/2fa/enroll';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"current_code":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/me/2fa/enroll \ --header 'Content-Type: application/json' \ --data '{ "current_code": "example" }'If the account already has armed 2FA the request body MUST include
current_code (a live TOTP or recovery code) so the existing protection
cannot be silently rotated by a session that was not 2FA-challenged.
Request Bodyrequired
Section titled “Request Bodyrequired”Media typeapplication/json
Body for the enroll endpoint. current_code is required only when the
account already has armed 2FA (re-enroll scenario).
object
current_code
string | null
Examplegenerated
{ "current_code": "example"}Responses
Section titled “Responses”Media typeapplication/json
POST /me/2fa/enroll response — the provisioning URI (QR) + base32 secret.
object
otpauth_uri
required
string
secret
required
string
Examplegenerated
{ "otpauth_uri": "example", "secret": "example"}