SumoRouter
SumoRouter Customer API

Authentication

Server

Sign-up, sign-in (with optional or required two-factor step), email verification, password reset and Google sign-in. All of these are public; successful sign-in returns a session token (JWT) that is valid for 7 days and is sent as Authorization: Bearer <token>.


List available sign-in methods

GET
https://ai.brandkamu.id
/api/auth/methods

Public. Which sign-in options a login / sign-up page should show.

List available sign-in methods › Responses

200

Enabled methods.

email_password
​boolean · required

Email/password sign-in is enabled.

registration
​boolean · required

New accounts can sign up.

google
​boolean · required

Google sign-in is configured and enabled.

turnstile_site_key
​string | null · required

Cloudflare Turnstile site key when the security check is on; then send turnstile_token on login, register, resend-verification and forgot-password.


Sign up with email and password

POST
https://ai.brandkamu.id
/api/auth/register

Creates a (non-admin) account. Requires email/password sign-up to be enabled (403 otherwise) and the instance to be set up. Limited to 5 attempts per IP per minute. The operator may block disposable domains, certain domains and + aliases (400), and may require a Cloudflare Turnstile token (see GET /api/auth/methods).

  • When email verification is required, the response is {"verification_required": true, "email": …} and a link plus a 6-digit code are emailed; continue with POST /api/auth/verify-email. The same response is returned if the address is already registered, so the form reveals nothing.
  • Otherwise the response is {"token": …} — a session token; the user is signed in.

Sign up with email and password › Request Body

email
​string · email · maxLength: 254 · required
password
​string · minLength: 8 · required
name
​string · maxLength: 80
Default:
turnstile_token
​string | null

Cloudflare Turnstile response; required when turnstile_site_key is set.

referral_code
​string | null

Affiliate code from a ?ref= sign-up link (8 characters). Invalid codes are ignored.

Sign up with email and password › Responses

Signed in, or verification required.

oneOf
Exactly one variant must match.

Decision Table

VariantMatching Criteria
type = object · requires: token
type = object · requires: verification_required, email
Properties for Signed in:
token
​string · required

Session token (JWT, valid 7 days). Send as Authorization: Bearer <token>.


Sign in with email and password

POST
https://ai.brandkamu.id
/api/auth/login

Checks the password and returns one of three shapes:

  1. {"token": "<jwt>"} — signed in. Send Authorization: Bearer <jwt> on Dashboard requests. Sessions last 7 days and end early when the password is changed, 2FA is turned on or off, or the account is suspended.
  2. {"verification_required": true, "email": "…"} — the email isn't verified yet (only shown after a correct password). Continue with POST /api/auth/verify-email or POST /api/auth/resend-verification.
  3. {"mfa": {"token": "<mfa_token>", "setup": <bool>}} — a second factor is needed (always for admins, and for users who turned 2FA on). The challenge is valid for 10 minutes and allows 5 wrong codes.
    • setup: false → ask for a 6-digit authenticator code (or a recovery code) and call POST /api/auth/mfa/verify with {mfa_token, code}; it returns {"token": …}.
    • setup: true (an admin without 2FA) → call POST /api/auth/mfa/setup with {mfa_token} to get the secret / QR code, then POST /api/auth/mfa/verify with the first code; it returns {"token": …, "recovery_codes": [...]}.

Wrong email and wrong password both return 401 "wrong email or password". Limited to 30 attempts per IP and 10 per email per minute. A Turnstile token is required when enabled.

Sign in with email and password › Request Body

email
​string · email · required
password
​string · required
turnstile_token
​string | null

Sign in with email and password › Responses

A session, a verification hint or an MFA challenge.

oneOf
Exactly one variant must match.

Decision Table

VariantMatching Criteria
type = object · requires: token
type = object · requires: verification_required, email
type = object · requires: mfa
Properties for Signed in:
token
​string · required

Session token (JWT, valid 7 days). Send as Authorization: Bearer <token>.


Get the 2FA secret during sign-in enrolment

POST
https://ai.brandkamu.id
/api/auth/mfa/setup

For an MFA challenge with setup: true. Returns a new TOTP secret as text, otpauth:// URI and SVG QR code. Repeated calls during the same sign-in return the same secret. Finish with POST /api/auth/mfa/verify.

Get the 2FA secret during sign-in enrolment › Request Body

mfa_token
​string · required

The mfa.token from sign-in (43 characters).

Get the 2FA secret during sign-in enrolment › Responses

Enrolment details.

secret
​string · required

Base32 secret in groups of 4 characters, for manual entry.

otpauth_uri
​string · required

otpauth://totp/… URI.

qr_svg
​string · required

SVG markup of the QR code for otpauth_uri.

account
​string · required

The user's email.

issuer
​string · required

The site name.


Complete sign-in with a 2FA code

POST
https://ai.brandkamu.id
/api/auth/mfa/verify

Second sign-in step. code is a 6-digit TOTP code, or (when not enrolling) a single-use recovery code. When the challenge had setup: true, this also turns 2FA on and returns the recovery codes once. After 5 wrong codes the challenge ends and the user must sign in again. Limited to 10 attempts per user per minute.

Complete sign-in with a 2FA code › Request Body

mfa_token
​string · required
code
​string · required

6-digit code, or a recovery code.

Complete sign-in with a 2FA code › Responses

Signed in.

token
​string · required

Session token (JWT).

recovery_codes
​string[]

Only after enrolment (setup: true). Show them once; they are not retrievable.


Verify an email address

POST
https://ai.brandkamu.id
/api/auth/verify-email

Confirms the address with either the token from the emailed link (the link carries it in the URL fragment: '/verify-email#token=…) or the email plus the 6-digit code from the email. Links are' valid for 24 hours; a code dies after 5 wrong guesses. Limited to 20 attempts per IP per minute.

Users without 2FA are signed in (token is included). Admins and users with 2FA get only {"verified": true} and then sign in normally.

Verify an email address › Request Body

token
​string | null

Token from the emailed link.

email
​string | null · email
code
​string | null

6-digit code from the email; use together with email.

Verify an email address › Responses

Verified.

verified
​boolean · const · required
Const value:
token
​string

Session token; absent for admins and users with 2FA.


Resend the verification email

POST
https://ai.brandkamu.id
/api/auth/resend-verification

Sends a fresh verification link and code (earlier ones stop working) if the address belongs to an unverified, active account. Always answers {"ok": true} so it reveals nothing about which addresses exist. Limited to 5 per IP and 2 per address per minute; Turnstile token when enabled.

Resend the verification email › Request Body

email
​string · email · required
turnstile_token
​string | null

Cloudflare Turnstile response, when enabled.

Resend the verification email › Responses

Done.

ok
​boolean · const · required
Const value:

Request a password reset email

POST
https://ai.brandkamu.id
/api/auth/forgot-password

Emails a reset link (/reset-password#token=…, valid for 1 hour) if the address belongs to an active account. Always answers {"ok": true}. Returns 403 when the instance has no working email. Same rate limits and Turnstile rule as resend-verification.

Request a password reset email › Request Body

email
​string · email · required
turnstile_token
​string | null

Cloudflare Turnstile response, when enabled.

Request a password reset email › Responses

Done.

ok
​boolean · const · required
Const value:

POST
https://ai.brandkamu.id
/api/auth/reset-password

Sets the new password using the token from the reset link. Does not sign in; all existing sessions end and the user signs in with the new password. Also marks the email as verified. Minimum 8 characters (10 for admins). Limited to 10 attempts per IP per minute.

Set a new password from a reset link › Request Body

token
​string · required
password
​string · minLength: 8 · required

Set a new password from a reset link › Responses

Done.

ok
​boolean · const · required
Const value:

Start Google sign-in

GET
https://ai.brandkamu.id
/api/auth/google/start

Browser navigation endpoint (not for fetch). Redirects to Google's consent screen (OAuth 2.0 authorization code + PKCE). The flow must be finished within 10 minutes. Google then returns to GET /api/auth/google/callback.

Start Google sign-in › query Parameters

ref
​string · maxLength: 16

Affiliate referral code, kept across the redirect so a new account is attributed.

Start Google sign-in › Responses

Redirect to Google.

No data returned

Google sign-in callback

GET
https://ai.brandkamu.id
/api/auth/google/callback

Called by Google, not by your code. Always redirects back to the site's public URL:

  • /auth/callback#token=<jwt> — signed in (the token is in the URL fragment, never sent to servers).
  • /auth/callback#mfa=<mfa_token>&setup=<true|false> — continue with the two-factor step (see POST /api/auth/login).
  • /login?error=<code> — failure; code is one of google_cancelled, google_failed, google_disabled, google_expired, google_unverified, account_disabled, signup_disabled, email_not_allowed.

An existing account with the same (Google-verified) email is linked; otherwise a new account is created when registration is enabled.

Google sign-in callback › query Parameters

code
​string
state
​string
error
​string

Google sign-in callback › Responses

Redirect back to the dashboard.

No data returned