Skip to main content

Two-Factor Authentication - API

Checking status, generating QR code, and enabling/disabling user two-factor authentication (2FA) via REST API

Written by Petr Pech

Two-factor authentication (2FA) can be enabled for individual users not only in the application, but also via the REST API. This article describes the endpoints for checking the status, issuing a QR code, and enabling and disabling two-factor authentication.

⚠️ Enabled two-factor authentication also applies to REST API calls with HTTP authentication. Every request from the given user must then include the query parameter otp with the current one-time password value. Without it, even previously working integrations will stop functioning.

Setting up two-factor authentication directly in the application is described in two-factor authentication.


Checking the Status

You can check whether a user has two-factor authentication enabled from the user detail in the twoPhaseAuthEnabled element:

GET /u/{username}.xml

<user> 
<username>novak</username>
<twoPhaseAuthEnabled>false</twoPhaseAuthEnabled>
</user>

The same element can also be found in the list of all users at /u. The usual output formats are supported.


Issuing a QR Code

Issues a QR code with a newly generated private key for the specified user:

GET /u/{username}/qrcode-2fa.png

The response is an image in image/png format (400 × 400 px). You can find the private key in text form in the Secret HTTP response header — you will need this value to enable authentication.

Example response headers:

HTTP/1.1 200 OK 
Secret: C66NFUGRCLIB5DOM
Content-Type: image/png

ℹ️ Include the .png extension in the URL, or send the Accept: image/png header instead. Without one of these, the request will fail with a 404 error.

If the user already has two-factor authentication active, the operation returns status code 403.


Enabling

PUT /u/{username}/enable-2fa?secret={secret}&otp={otp-code}

Parameters:

Parameter

Required

Description

username

yes

Username of the currently logged-in user

secret

yes

The user's private key from the Secret header when the QR code was issued

otp

yes

One-time password generated from the private key

In XML or JSON format, a success flag for the operation, success, and a message, message, are returned:

{ 
"winstrom": {
"@version": "1.0",
"success": "true",
"message": "Dvoufázové ověření bylo úspěšně nastaveno."
}
}

The server validates the one-time password against the provided private key. If the code doesn't match, the operation is not performed and an error Nesouhlasí kód pro dvoufázové ověření. is returned.


Disabling

PUT /u/{username}/disable-2fa?otp={otp-code}

Parameters:

Parameter

Required

Description

username

yes

Username of the currently logged-in user

otp

yes

One-time password

Result:

<winstrom version="1.0"> 
<success>true</success>
<message>Dvoufázové ověření bylo úspěšně vypnuto.</message>
</winstrom>

If the one-time password is incorrect, the operation returns status code 403.

Disabling by an Administrator

A user with the Change User Passwords permission can disable two-factor authentication for another user without knowing that user's one-time password:

PUT /u/disable-2fa?username={username}

The username parameter is required and specifies the user whose authentication should be disabled. Without the required permission, the operation returns status code 403.


FAQ

I enabled 2FA and my integration stopped working. Why?

Two-factor authentication also applies to the REST API. Every request from a user with HTTP authentication must carry the query parameter otp with the current one-time password. For service accounts, therefore, consider whether you should enable two-factor authentication for them at all.

A user has lost access to the app with the one-time passwords. What now?

A user with the Change User Passwords permission can disable their authentication via PUT /u/disable-2fa?username={username}. They can then have a new QR code issued and re-enable authentication.

Do I need to keep the private key?

You only need the key at the moment you enable authentication. Store it securely and never send it in a URL that gets logged.

Did this answer your question?