Email & password
The default sign-in method. Argon2id-hashed passwords, constant-time verification, rate limiting, and a configurable password policy per instance.
Copy this quickstart guide as a prompt for LLMs to implement KolayLogin in your application.
Endpoints
POST /v1/auth/sign-up/email-password— create user + sessionPOST /v1/auth/sign-in/email-password— verify + sessionPOST /v1/auth/sign-out— end this clientPOST /v1/auth/sign-out/all— end every session for the user
Request shape
POST /v1/auth/sign-up/email-password
{
"email": "ada@example.com",
"password": "correct-horse-battery-staple"
}Both sign-up and sign-in respond with the created session shape and set __client + __session cookies:
{ "userId": "...", "sessionId": "..." }Client example
async function signIn(email: string, password: string) {
const res = await fetch(base + '/v1/auth/sign-in/email-password', {
method: 'POST',
credentials: 'include',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) throw new Error('invalid_credentials');
return res.json();
}Password policy
Per-instance policy configured from the dashboard. Hobby plans get the default; Pro+ can require uppercase / lowercase / digit / special.
instance sessionConfig.passwordPolicy
{
"minLength": 10,
"requireUppercase": true,
"requireLowercase": true,
"requireNumber": true,
"requireSpecial": false
}Errors
400 password_too_short— fails the configured policy.400 email_already_exists— on sign-up when the email is taken.401 invalid_credentials— on sign-in with wrong email/password (constant-time).429 signup_rate_limited / signin_rate_limited— sliding-window limit.
No user enumeration
Sign-in always runs
argon2.verifyagainst either the real hash or a dummy hash, so response time is identical whether the email exists. Your UI should not distinguish "wrong email" from "wrong password".