Skip to Content
🔐 Faable AuthOAuth 2.0 FlowsPassword (first-party apps)

Password Grant

The password grant (grant_type=password, Resource Owner Password Credentials in RFC 6749 §4.3) lets your application send a user’s email — or username — and password straight to /oauth/token and get tokens back, with no browser redirect.

Use it only when your own app cannot open the hosted login — a legacy client, an embedded device, a migration. Your app sees the password, and the user gets none of what the hosted screen gives: passkeys, social sign-in, single sign-on across your apps, the login flows you configure. For a user signing in, Authorization Code with PKCE is the default.

Turn it on for a client

It is off for every client until you add password to the client’s grant_types:

POST /client/<client_id> Content-Type: application/json { "grant_types": ["authorization_code", "refresh_token", "password"] }

A client that has not opted in gets 400 unauthorized_client.

Request tokens

curl -X POST https://<your-auth-domain>/oauth/token \ -H 'content-type: application/x-www-form-urlencoded' \ -d grant_type=password \ -d client_id=<client_id> \ -d client_secret=<client_secret> \ -d username=ana@example.com \ -d password='the-password' \ -d scope='openid profile email offline_access'
ParameterRequiredNotes
grant_typeyespassword
client_idyes
client_secretfor confidential clientsNot needed for a public client (registered with token_endpoint_auth_method: none)
usernameyesAn email or a username, as the database connection’s sign-in identifier allows
passwordyes
realmnoThe name of the database connection. Defaults to the first database connection offered to the client
scopenoAs in any other grant
audiencenoThe API the access token is for

The response is the same as any other user grant:

{ "token_type": "Bearer", "access_token": "eyJ…", "expires_in": 3600, "id_token": "eyJ…", "refresh_token": "…" }

Two-step verification

If the tenant’s policy asks this user for a second factor, the grant stops with 403 and error: mfa_required, carrying an mfa_token and the factors the user can use (mfa_required_factors). Send the code with grant_type=http://auth0.com/oauth/grant-type/mfa-otp and that token to finish — the same second step as the emailed-code grant. See Two-Step Verification.

Failed attempts

After 10 failed attempts in 15 minutes for the same email or username from the same network, every attempt — even with the right password — gets 429 with error_code: too_many_login_attempts until the window passes. A successful sign-in resets the count. The hosted login form shares the same count, so switching between the two does not reset it.

Counting per network as well as per user means someone who knows an email cannot lock that person out from everywhere.

Errors

Errors follow RFC 6749 §5.2 — error and error_description — plus error_code when error is too coarse:

Statuserrorerror_codeWhy
400unauthorized_clientunauthorized_clientThe client did not opt in to the password grant
401invalid_clientinvalid_clientMissing or wrong client_secret for a confidential client
400invalid_requestinvalid_connectionrealm does not name a database connection offered to the client
400invalid_grantinvalid_credentialsWrong email/username or password
403invalid_grantuser_suspendedThe user is suspended
403mfa_requiredA second factor is needed — see above
429invalid_granttoo_many_login_attemptsToo many failed attempts from this network — see above

Last updated on