Log in with email and password.
const url = 'https://api.opdns.io/v1/auth/login';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"email":"[email protected]","password":"example","totp_code":"example","recovery_code":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.opdns.io/v1/auth/login \ --header 'Content-Type: application/json' \ --data '{ "email": "[email protected]", "password": "example", "totp_code": "example", "recovery_code": "example" }'Sets the opdns_session cookie (HttpOnly, Secure, SameSite=Lax) and rotates any
previous session. When the account has TOTP enabled, totp_code (or
recovery_code) is required: 401 second_factor_required when missing,
invalid_second_factor when wrong or reused (attempts limited per account).
Outside dev, an account with neither TOTP nor a passkey past its grace period
(session.mfa_deadline) gets a session with restricted: true, usable only to
enrol one. A sign-in from a new browser and network emails a notice.
Failed attempts (unknown address, wrong password, wrong second factor) slow the next attempt from the same client IP or for the same address: 100 ms after one failure, doubling to at most 5 s; a success clears the address’s delay. Ten failures on an account within an hour email its owner, at most once an hour. Passkey sign-in is not delayed.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Required when the account has TOTP enabled (or send recovery_code).
A single-use recovery code, in place of totp_code.
Examplegenerated
{ "password": "example", "totp_code": "example", "recovery_code": "example"}Responses
Section titled “Responses”Logged in.
object
object
Operator account; may hold the admin scope.
Set while a deletion is pending; the account is erased at this time unless cancelled.
object
A restricted session may only enrol a second factor (TOTP setup/confirm,
passkey registration, GET /v1/auth/me, logout); every other call is 403
mfa_enrolment_required. Set for password-only sign-in after the grace
period, outside dev.
When password-only sign-in becomes restricted; null once a second factor exists, and in dev.
Example
{ "account": { "role": "owner" }, "session": { "auth_method": "password" }}Headers
Section titled “Headers”Malformed request.
object
Stable machine code.
object
Seconds, repeating the Retry-After header (rate limits, offline nodes).
Example
{ "type": "https://opdns.io/problems/bad_request", "title": "Bad Request", "status": 400, "code": "bad_request", "detail": "invalid JSON body", "request_id": "5f2c9a0e7b1d4c38"}Not authenticated.
object
Stable machine code.
object
Seconds, repeating the Retry-After header (rate limits, offline nodes).
Example
{ "type": "https://opdns.io/problems/unauthenticated", "title": "Unauthorized", "status": 401, "code": "unauthenticated", "detail": "authentication required", "request_id": "5f2c9a0e7b1d4c38"}Rate limited (rate_limited).
object
Stable machine code.
object
Seconds, repeating the Retry-After header (rate limits, offline nodes).
Example
{ "type": "https://opdns.io/problems/rate_limited", "title": "Too Many Requests", "status": 429, "code": "rate_limited", "detail": "too many requests", "request_id": "5f2c9a0e7b1d4c38", "retry_after": 6}