Skip to main content

Phone app sign-in and two-factor authentication (2FA)

The EquipDash phone app signs in with an email and password, or with Google, and gets a bearer token back. These endpoints are for the phone app. API keys are not affected by two-factor authentication (2FA): a key is not a person signing in, so it keeps working exactly as before.

When a person has 2FA on, a correct password returns a challenge instead of a token. The app swaps the challenge plus a code for the token.

Sign in with a passwordโ€‹

POST /api/v1/mobile/auth/login

FieldTypeRequiredNotes
emailstringyes
passwordstringyes
device_namestringyesShown to the person as the trusted device name.
trusted_device_tokenstringnoThe token this phone got the last time the person ticked Trust this device. A valid one skips the code for 30 days.

2FA off, or a trusted phone: the same response as always.

{
"data": {
"token": "12|q8F...",
"user": { "id": 1, "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.test" },
"suppliers": [ ... ],
"active_supplier": { ... }
}
}

2FA on: no token yet.

{
"data": {
"two_factor_required": true,
"challenge_token": "Xk2...",
"expires_in": 600,
"email_hint": "j***@example.test"
}
}

The challenge lasts 10 minutes.

The person's team requires 2FA and they have not set it up: 403 with two_factor_setup_required. They set it up by signing in on the website first, then sign in on the phone.

Swap the challenge and a code for the tokenโ€‹

POST /api/v1/mobile/auth/two-factor

FieldTypeRequiredNotes
challenge_tokenstringyesFrom the login response.
codestringyesAny of the three: the 6 digits from their authenticator app, the 6 digits from the emailed code, or one of their backup codes (with or without the dash).
trust_devicebooleannotrue returns a trusted_device_token to store on the phone.

Success returns the normal sign-in response, plus trusted_device_token when trust_device was true. Store it in the phone's secure storage and send it with the next login.

Email a code insteadโ€‹

POST /api/v1/mobile/auth/two-factor/email

FieldTypeRequired
challenge_tokenstringyes

Emails 6 digits to the person, good for 10 minutes and once. At most one email a minute.

{ "data": { "sent": true, "email_hint": "j***@example.test" } }

Google sign-inโ€‹

POST /api/v1/mobile/auth/google-login is unchanged. Google checks it is the person, so no code is asked.

Errorsโ€‹

Error codeHTTP statusMeaning
invalid_code422The code did not match.
too_many_attempts4295 wrong codes in a row. Wait 5 minutes. Also returned when an emailed code was sent less than a minute ago.
challenge_expired401The challenge is older than 10 minutes, or was already used. Sign in again.
two_factor_setup_required403The person's team requires 2FA and they have not set it up yet.