2. Sign in (TOTP)
Businesses sign in with email and password. TOTP (Google Authenticator, Authy…) is mandatory: a full token is never returned directly, the response tells you the next step.
Sign in
POST/auth/loginPublic
Request body
{
"email": "[email protected]",
"password": "<mot-de-passe>"
}Case 1: TOTP not configured yet (first sign-in)
{
"success": true,
"data": {
"requires_totp_setup": true,
"setup_token": "..."
},
"meta": {
"request_id": "...",
"timestamp": "..."
}
}Case 2: TOTP already configured
{
"success": true,
"data": {
"requires_totp": true,
"challenge_token": "550e8400-e29b-41d4-a716-446655440000"
},
"meta": {
"request_id": "...",
"timestamp": "..."
}
}| Code | When |
|---|---|
| 422 | Wrong credentials, disabled account, or individual account (use phone sign-in). |
- Forgotten password:
POST /auth/password/forgotthenPOST /auth/password/reset.
First sign-in: enable TOTP
POST/auth/totp/setupsetup_token (Bearer)
With Authorization: Bearer {setup_token} (valid 15 min). Returns the secret to scan in Google Authenticator or Authy.
Response 200
{
"success": true,
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qr_url": "otpauth://totp/KratosPay:...",
"manual_entry_key": "JBSWY3DPEHPK3PXP"
},
"meta": {
"request_id": "...",
"timestamp": "..."
}
}| Code | When |
|---|---|
| 401 | Expired setup_token: sign in again. |
Confirm TOTP and get the token
POST/auth/totp/confirmsetup_token (Bearer)
Enter the first 6-digit code generated by the app. Setup expires after 10 minutes.
Request body
{
"code": "123456"
}Response 200
{
"success": true,
"data": {
"merchant": {
"...": "..."
},
"token": "<jeton-de-session>",
"token_type": "Bearer",
"recovery_codes": [
"XXXX-XXXX-XXXX",
"... 10 codes au total"
]
},
"meta": {
"request_id": "...",
"timestamp": "..."
}
}| Code | When |
|---|---|
| 422 | Invalid code or expired session. |
Keep the 10 recovery codes somewhere safe: they will never be shown again. Each one replaces a TOTP code, single-use.
Next sign-ins: answer the TOTP challenge
POST/auth/totp/challengePublic
Use after a sign-in that returned requires_totp. The challenge_token is single-use, valid 5 minutes.
Request body
{
"challenge_token": "550e8400-e29b-41d4-a716-446655440000",
"code": "123456"
}Response 200
{
"success": true,
"data": {
"requires_totp": false,
"merchant": {
"...": "..."
},
"token": "<jeton-de-session>",
"token_type": "Bearer"
},
"meta": {
"request_id": "...",
"timestamp": "..."
}
}| Code | When |
|---|---|
| 422 | Invalid code, expired or already used challenge (a XXXX-XXXX-XXXX recovery code is also accepted). |