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 |
| yes | Username of the currently logged-in user |
| yes | The user's private key from the |
| 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 |
| yes | Username of the currently logged-in user |
| 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.
