Challenge risky logins.
Send a normal verification token with action: "login" and account: {id: "your-account-id"} (or an email). Password checks and session creation remain on your backend. Only create a session after an allow or a verified step-up proof.
Login signals
| Reason | Trigger |
|---|---|
| new_device · 30 | No matching visitor or fingerprint membership in 90 days, with an existing known device. Alone this does not challenge; combined with a suspicious verdict or another login reason it does. |
| impossible_travel · 40 | A different country less than two hours after the last allowed login. |
| credential_stuffing · 60 | One device or network prefix attempts the same login action for more than ten distinct accounts in an hour. |
| stale_account · 30 | Last allowed login more than 180 days ago and no matching known device. This challenges even when all memberships have expired. |
Login reasons do not change the bot score. Risky human logins get challenge in block mode; bots keep their bot decision. Observe and shadow modes report wouldDecide: "challenge". Customer rules can match these reason IDs.
Response
{ "success": true, "decision": "challenge", "ref": "ev_123", "login": { "knownDevices": 2, "newDevice": true } }
Known devices counts hashed visitor/fingerprint memberships rather than physical hardware. First login has no new-device reason. Allowed logins and successful step-up checks remember the device; challenges do not.
Actions
Defaults: ["login","signin","sign_in"]. Set loginActions with the authenticated dashboard PATCH /api/sites/:key: an array of up to 20 lowercase action names (letters, digits, underscore or hyphen; 1–64 characters). An empty array disables login checks. Action matching is exact.
Stored data
Account and device memberships are per-site keyed HMACs. History contains only the last allowed country and time. No raw email, IP address, phone number or user agent is added. Device memberships expire after 90 days; last-login history remains available for dormant-account detection. Storage failures degrade without blocking verification.