Stop account takeovers without locking out real users
A stolen password looks exactly like your user. LoginLlama checks every login against that person's history and live threat data, gives your app a risk score and the reasons, and asks the real owner “Was this you?”
Logs
Logins, 7 days
184,392
Flagged
2,417
Alert emails
1,286
Blocked
812
Chrome on macOS, 197.210.8.24
- Your app
- Ask for MFA
- "Was this you?" sent
{
"status": "fail",
"risk_score": 7,
"risk_codes": [
"ip_address_not_used_before",
"new_login_location",
"impossible_travel_detected"
],
"unrecognized_device": false
}Integrate today
One call after your password check. SDKs for your language, and plugins for the auth library you already use.
import { LoginLlama } from 'loginllama';
const loginllama = new LoginLlama({
apiKey: process.env.LOGINLLAMA_API_KEY
});
// Use middleware for automatic IP/User-Agent detection
app.use(loginllama.middleware());
// Pre + Post Auth Pattern - Most complete protection
app.post('/login', async (req, res) => {
const { email, password } = req.body;
try {
// Step 1: Pre-auth check (before verifying credentials)
const preCheck = await loginllama.check(email, {
authenticationOutcome: 'pending' // Mark as pre-auth check
});
// Block high-risk attempts before authentication
if (preCheck.risk_score > 7) {
return res.status(403).json({ error: 'Login blocked' });
}
// Step 2: Authenticate with your system
const authResult = await authenticate(email, password);
// Step 3: Report outcome to LoginLlama
if (authResult.success) {
await loginllama.reportSuccess(authResult.user.id);
return res.json({ success: true });
} else {
// Report failed auth - helps detect brute force attacks
await loginllama.reportFailure(email);
return res.status(401).json({ error: 'Invalid credentials' });
}
} catch (error) {
console.error('LoginLlama error:', error);
return res.json({ success: true }); // Fail open on errors
}
});01Detect
Every login, scoredbefore you hand over the session
Send the user, the IP and the user agent after your password check. LoginLlama compares them with that person's history and our threat lists, and answers before your code creates a session.
Impossible travel
Two logins too far apart to be the same person. The account has one owner, and they did not fly to Lagos in 12 minutes.
A score your code can act on
0 to 10 and the reasons, in the response. Stricter for accounts you send as privileged.
A new phone in a new country
Impossible travel
Password spraying from a cloud server
Every signal has a name
Each code tells you why a login looked wrong, so you can act on it and explain it to a customer.
Password guessing
Bursts of failures on one account, and one address failing across many.
IP reputation
260,000+ addresses and ranges from Tor, Mullvad, Spamhaus and FireHOL, kept up to date for you.
179.228.33.24
Vivo (AS26599)
São Paulo, Brazil
- ip_address_not_used_before
- new_login_location
- device_fingerprint_not_used_before
New device and location
A first-time browser, operating system, address or country for this user. Device means the user agent. There is no client-side script to install.
02Alert
Your user hears firstwith an email you don't have to build
A branded email goes out when a sign-in looks wrong, so the real owner can reset their password before any harm is done. You don't design it, send it or keep it out of spam.
From Acme Security
New login detected on your account

- Near
- London, UK
- Device
- Apple MacBook
- Browser
- Firefox
If this wasn't you, someone may have your login details. Reset your password as soon as you can.
03Decide
The decision stays in your codeon thresholds you set
LoginLlama never touches your session, so nothing changes until you say so. Watch the scores for a week, see what would have been flagged, then turn on your thresholds. If we can't answer, the SDKs and plugins let the login through, so an outage never locks your users out.
risk_score 0 to 4
Allow
Let them in. Nothing changes for your user.
risk_score 5 to 7
Challenge
Your choice of MFA, an email code, a CAPTCHA or proof of work.
risk_score 8 to 10
Block
Refuse it, and offer a password reset.
An example. Set your own numbers.
04Agents
Install it with one promptthen ask your login data questions
Hand the prompt to your coding agent. It finds your stack, installs the SDK, adds the check after auth and asks you to approve an API key. The prompt holds no key.
Integrate LoginLlama (suspicious login detection) into this project.
1. Detect the language/framework and install the official SDK:
- Better Auth (any framework): npm install better-auth-loginllama,
then add loginLlama() to plugins
- Clerk: npm install clerk-loginllama,
then export POST = loginLlamaWebhook()
from a session.created webhook route
- Auth.js (NextAuth) Credentials: npm install authjs-loginllama,
then wrap authorize in withLoginLlama()
- Node.js / Next.js / Express: npm install loginllama
- Python / Django / Flask: pip install loginllama
- PHP / Laravel: composer require joshghent/loginllama
2. Read the live API reference and examples from https://loginllama.app/docs (the machine-readable
summary is at https://loginllama.app/llms.txt).
3. Get an API key with the device flow. POST to https://loginllama.app/api/v1/oauth/device with
JSON { "client_name": "<your name>", "project_name": "<this repository's name, or
the website's name for WordPress>" }. Show me verification_uri_complete and wait
while I approve it. Poll https://loginllama.app/api/v1/oauth/token with { "grant_type":
"urn:ietf:params:oauth:grant-type:device_code", "device_code": "<device_code>" }
at the given interval until it returns access_token. If I have no account, the
approval page asks me to sign up, with 100 free checks and no card.
Save it as LOGINLLAMA_API_KEY in the environment. Never hard-code the key.
4. After my auth step succeeds, call LoginLlama with the user's identity_key,
email, IP address and user agent. Branch on the result:
- risk_score > 5 -> require MFA / extra verification or block
- otherwise -> allow the login
Always FAIL OPEN: if LoginLlama errors or times out, log it and let the user in.
5. Add a short comment linking to https://loginllama.app/docs and show me how to test it locally.Connect the MCP server
It reads only, and only your team's data.
- > What's my average login risk score for Chrome?
- > Show me the riskiest logins this week.
- > How many Tor or VPN logins did we see in the last 7 days?
A stolen password logs in like your user
Your login form sees the right password and lets them in. The first you hear of it is a support ticket: a customer locked out, their data changed, a refund to explain, and someone asking if you've been hacked.
AI makes this cheaper. Okta has seen attackers use it to write working credential stuffing configurations, and Push Security ran stuffing through OpenAI Operator in a real browser, where rate limits and CAPTCHAs catch less. The login still comes from the wrong place, on the wrong device, and the owner still gets the email.
Start with 100 free checksNo card. Then from $9 a month.
Starter
Professional
Enterprise
All plans include upgrade, downgrade, and cancel anytime.
Score your first login today
100 free checks. No card. Then from $9 a month.