API Reference
All API endpoints are served under /api/. Requests and responses use JSON. Admin routes use cookie-based sessions; project auth routes use public key + bearer tokens.
Base URL
| Environment | URL | Notes |
|---|---|---|
| Kyqu Cloud | https://api.kyqu.dev | Set this as baseUrl in the SDK |
| Self-hosted | https://auth.example.com | Set API_BASE_URL to match |
Project auth routes return 403 when the project is suspended or auth is disabled.
Admin Routes
Authentication
GET /api/admin/me
Restore admin session from cookie. Sets CSRF cookie.
Response: 200 { admin } or 401 { error }
POST /api/admin/signup
Create admin account. First signup becomes superadmin. Returns 403 when ADMIN_REGISTRATION_OPEN=false.
Request: { email, password, name }
Response: 201 { admin } + Set-Cookie session + CSRF
POST /api/admin/login
Authenticate admin.
Request: { email, password }
Response: 200 { admin } + Set-Cookie session + CSRF
POST /api/admin/logout
Revoke admin session. Requires CSRF token.
Response: 200 { ok } + Clear-Cookie
MFA (Admin 2FA)
POST /api/admin/mfa/enroll
Start TOTP enrollment for admin.
Response: 200 { enrollmentUrl }
POST /api/admin/mfa/verify
Verify TOTP code during login (after email/password step).
Request: { code }
Response: 200 { admin } + Set-Cookie session
POST /api/admin/mfa/confirm
Confirm TOTP enrollment with code from authenticator app.
Request: { code }
Response: 200 { ok, backupCodes: [...] }
POST /api/admin/mfa/disable
Disable TOTP for admin.
Request: { code }
Response: 200 { ok: true }
Overview
GET /api/admin/overview
Cross-project platform statistics.
Response: 200 { totalProjects, totalUsers, totalSessions, recentSignups, recentLogins }
Projects
GET /api/admin/projects
List projects for the authenticated admin.
Response: 200 { projects: [...] }
POST /api/admin/projects
Create a new project.
Request: { name, productType, domain }
Response: 201 { project } (includes publicKey and secretKey, shown once)
GET /api/admin/projects/:id
Get project details.
Response: 200 { project } or 404
PATCH /api/admin/projects/:id
Update project settings.
Request: { name?, domain?, productType?, authSettings?, redirectUrls? }
Response: 200 { project }
GET /api/admin/projects/:id/onboarding
Get project onboarding status.
Response: 200 { onboarding }
PATCH /api/admin/projects/:id/onboarding
Update project onboarding step.
Request: { step?: string, completed?: boolean, data?: object }
Response: 200 { onboarding }
Project Users
GET /api/admin/projects/:id/users
List users for a project.
Response: 200 { users: [...] }
POST /api/admin/projects/:id/users
Create a user in a project.
Request: { email, password?, name?, metadata?, skipVerification? }
Response: 201 { user }
PATCH /api/admin/projects/:id/users/:userId/metadata
Update user metadata.
Request: { metadata: { ... } }
Response: 200 { user }
POST /api/admin/projects/:id/users/:userId/resend-verification
Resend verification email.
Response: 200 { ok: true }
POST /api/admin/projects/:id/users/:userId/force-password-reset
Force password reset.
Response: 200 { ok: true }
POST /api/admin/projects/:id/users/:userId/reset-2fa
Reset TOTP 2FA for user.
Response: 200 { ok: true }
POST /api/admin/projects/:id/users/:userId/unlock
Unlock a locked user account.
Response: 200 { ok: true }
POST /api/admin/projects/:id/users/:userId/suspend
Suspend a user.
Request: { reason?: string }
Response: 200 { ok: true }
POST /api/admin/projects/:id/users/:userId/reactivate
Reactivate a suspended user.
Response: 200 { ok: true }
DELETE /api/admin/projects/:id/users/:userId
Delete a project user (admin).
Response: 200 { ok: true }
Auth Settings
PATCH /api/admin/projects/:id/auth/settings
Update project auth settings.
Request: Partial auth settings object (see Configuration Reference)
Response: 200 { project }
API Keys
POST /api/admin/projects/:id/api-keys/rotate
Rotate project API key pair.
Response: 200 { project } (includes new publicKey and secretKey)
User Fields
GET /api/admin/projects/:id/user-fields
List custom field definitions.
Response: 200 { fields: [...] }
POST /api/admin/projects/:id/user-fields
Create a custom field definition.
Request: { name, label, fieldType, required?, defaultValue?, sortOrder? }
Response: 201 { field }
DELETE /api/admin/projects/:id/user-fields/:fieldId
Delete a custom field definition.
Response: 200 { ok: true }
Impersonation
POST /api/admin/projects/:id/users/:userId/impersonate
Impersonate a project user (superadmin only).
Response: 200 { session: { token, expiresAt }, user }
POST /api/admin/projects/:id/impersonation/end
End active impersonation session.
Response: 200 { ok: true }
OAuth Providers
GET /api/admin/projects/:id/oauth-providers
List OAuth provider configurations.
Response: 200 { providers: [...] }
POST /api/admin/projects/:id/oauth-providers
Upsert OAuth provider configuration.
Request: { provider: "google" | "github", clientId, clientSecret, enabled? }
Response: 200 { provider }
DELETE /api/admin/projects/:id/oauth-providers/:provider
Remove OAuth provider configuration.
Response: 200 { ok: true }
Audit
GET /api/admin/projects/:id/logs
Get audit logs. Supports ?limit=N&offset=N query params.
Response: 200 { logs: [...], total: N }
GET /api/admin/projects/:id/stats
Get project statistics.
Response: 200 { stats: { totalUsers, activeSessions, authEvents, ... } }
GET /api/admin/projects/:id/email-outbox
List sent/stored email records.
Response: 200 { messages: [...] }
Webhooks
GET /api/admin/projects/:id/webhooks
List webhook endpoints. Also returns availableEvents.
Response: 200 { webhooks: [...], availableEvents: [...] }
POST /api/admin/projects/:id/webhooks
Create a webhook endpoint.
Request: { url, events?: string[] }
Response: 201 { webhook } (includes secret, shown once)
PATCH /api/admin/projects/:id/webhooks/:webhookId
Update a webhook.
Request: { url?, events?, enabled? }
Response: 200 { webhook }
DELETE /api/admin/projects/:id/webhooks/:webhookId
Delete a webhook.
Response: 200 { ok: true }
GET /api/admin/projects/:id/webhooks/:webhookId/deliveries
List recent webhook delivery records.
Response: 200 { deliveries: [...] }
GET /api/admin/webhook-events
List all available webhook event types.
Response: 200 { events: [...] }
Email Templates
GET /api/admin/projects/:id/email-templates
List email templates with purposes.
Response: 200 { templates: [...], purposes: [...] }
PUT /api/admin/projects/:id/email-templates/:purpose
Save custom email template.
Request: { subject, htmlBody, textBody }
Response: 200 { template }
DELETE /api/admin/projects/:id/email-templates/:purpose
Reset template to default.
Response: 200 { ok: true }
Superadmin Routes
All superadmin routes require the authenticated admin to have isSuperadmin: true.
GET /api/admin/superadmin/projects
List all projects across the platform.
Response: 200 { projects: [...] }
GET /api/admin/superadmin/users
List all project users across the platform.
Response: 200 { users: [...] }
POST /api/admin/superadmin/projects/:id/suspend
Suspend a project.
Response: 200 { ok: true }
POST /api/admin/superadmin/projects/:id/reactivate
Reactivate a project.
Response: 200 { ok: true }
POST /api/admin/superadmin/projects/:projectId/users/:userId/{action}
Superadmin user actions:
suspend— requires body{ reason: string }reactivateunlockreset-2faresend-verificationforce-password-reset
Response: 200 { result }
GET /api/admin/superadmin/email-templates
List all custom email templates across all projects.
Response: 200 { templates: [...], purposes: [...] }
GET /api/admin/superadmin/default-templates
List platform-wide default templates.
Response: 200 { templates: [...], purposes: [...] }
PUT /api/admin/superadmin/default-templates/:purpose
Save platform-wide default template.
Request: { subject, htmlBody, textBody }
Response: 200 { template }
DELETE /api/admin/superadmin/default-templates/:purpose
Reset platform default to built-in.
Response: 200 { ok: true }
GET /api/admin/superadmin/ip-allowlist
List IP allowlist entries.
Response: 200 { entries: [...] }
POST /api/admin/superadmin/ip-allowlist
Add IP to allowlist.
Request: { ipAddress, description?, expiresAt? }
Response: 201 { entry }
DELETE /api/admin/superadmin/ip-allowlist/:entryId
Remove IP from allowlist.
Response: 200 { ok: true }
Project Auth Routes
All project routes require x-kyqu-public-key header (or publicKey in body).
Authentication
POST /api/projects/:id/auth/signup
Register a new project user.
Request: { email, password, name?, ...customFields }
Response: 201 { user, session?, verificationRequired, verificationQueued? }
POST /api/projects/:id/auth/login
Authenticate a project user.
Request: { email, password, totpCode?, backupCode? }
Response: 200 { user, session } or 403 { error: "TOTP_REQUIRED" }
GET /api/projects/:id/auth/me
Get current user from bearer token.
Headers: Authorization: Bearer <token>
Response: 200 { user } or 401
DELETE /api/projects/:id/auth/me
Permanently delete the authenticated user's account.
Headers: Authorization: Bearer <token>
Request: { password: string }
Response: 200 { ok: true } or 401/403/400
POST /api/projects/:id/auth/logout
Revoke session token.
Headers: Authorization: Bearer <token>
Response: 200 { ok: true }
Email Verification
POST /api/projects/:id/auth/verify-email/request
Send verification email.
Request: { email }
Response: 200 { ok: true }
POST /api/projects/:id/auth/verify-email/confirm
Confirm email verification with token.
Request: { token }
Response: 200 { user }
GET /api/projects/:id/auth/verify-email/confirm?token=...
Browser redirect handler for email link clicks.
Success: 302 → email_verified_url?verified=1
Failure: 302 → login_url?error=...
Password Reset
POST /api/projects/:id/auth/password-reset/request
Request password reset email.
Request: { email }
Response: 200 { ok: true }
POST /api/projects/:id/auth/password-reset/confirm
Confirm password reset.
Request: { token, password }
Response: 200 { user, session }
GET /api/projects/:id/auth/password-reset/confirm?token=...
Browser redirect handler.
Redirect: 302 → password_reset_url?token=...
Change Password
POST /api/projects/:id/auth/password/change
Change password (authenticated).
Headers: Authorization: Bearer <token>
Request: { currentPassword, newPassword }
Response: 200 { ok: true }
Magic Link
POST /api/projects/:id/auth/magic-link/request
Request magic link email.
Request: { email }
Response: 200 { ok: true }
POST /api/projects/:id/auth/magic-link/confirm
Confirm magic link token (API / server-side).
Request: { token }
Response: 200 { user, session }
GET /api/projects/:id/auth/magic-link/confirm?token=...
Browser redirect handler for email link clicks.
Success: 302 → login_url?session_code={oneTimeCode} (5-minute TTL)
Failure: 302 → login_url?error=...
The redirect does not include the bearer session token. Exchange the code server-side or from your app:
POST /api/projects/:id/auth/session/exchange
Exchange a browser session_code for a bearer session.
Request: { sessionCode } (or { code })
Response: 200 { user, session }
TOTP 2FA
POST /api/projects/:id/auth/totp/enroll
Start TOTP enrollment (authenticated).
Headers: Authorization: Bearer <token>
Response: 200 { enrollmentUrl }
POST /api/projects/:id/auth/totp/confirm
Confirm TOTP enrollment.
Headers: Authorization: Bearer <token>
Request: { code }
Response: 200 { ok, backupCodes: [...] }
POST /api/projects/:id/auth/totp/disable
Disable TOTP.
Headers: Authorization: Bearer <token>
Request: { code }
Response: 200 { ok: true }
Sessions
GET /api/projects/:id/auth/sessions
List active sessions.
Headers: Authorization: Bearer <token>
Response: 200 { sessions: [...] }
DELETE /api/projects/:id/auth/sessions/:sessionId
Revoke a specific session.
Headers: Authorization: Bearer <token>
Response: 200 { ok: true }
Custom Fields
GET /api/projects/:id/auth/fields
Get custom field definitions.
Response: 200 { fields: [...] }
Update Metadata
PATCH /api/projects/:id/auth/me/metadata
Update the authenticated user's metadata.
Headers: Authorization: Bearer <token>
Request: { metadata: { ... } }
Response: 200 { user }
ID Token (OIDC)
POST /api/projects/:id/auth/token
Issue an RS256-signed OIDC ID token for the authenticated user.
Headers: Authorization: Bearer <token>
Response: 200 { idToken, tokenType: "Bearer", expiresIn }
Event Logs
GET /api/projects/:id/auth/logs
List auth event logs for the authenticated user.
Headers: Authorization: Bearer <token>
Query: ?limit=N&offset=N&event=type
Response: 200 { logs: [...], total: N }
Email Tracking
GET /api/projects/:id/email/track/open/:token
1×1 transparent GIF tracking pixel. Logs email open events.
Response: 200 (image/gif)
POST /api/projects/:id/email/bounce
Receive bounce notifications from SMTP.
Request: { email, reason?, type? }
Response: 200 { ok: true }
Passkeys (WebAuthn)
GET /api/projects/:id/auth/passkey/register/options
Get WebAuthn registration options (authenticated).
Headers: Authorization: Bearer <token>
Response: 200 { challenge, rp, user, pubKeyCredParams, authenticatorSelection }
POST /api/projects/:id/auth/passkey/register/verify
Verify and store a new passkey credential (authenticated).
Headers: Authorization: Bearer <token>
Request: { credential, name? }
Response: 201 { credential }
GET /api/projects/:id/auth/passkey/authenticate/options
Get WebAuthn authentication options (public, no auth required).
Query: ?userId=...
Response: 200 { challenge, allowCredentials?, rpId, userVerification }
POST /api/projects/:id/auth/passkey/authenticate/verify
Verify WebAuthn assertion and issue session.
Request: { assertion }
Response: 200 { user, session }
GET /api/projects/:id/auth/passkeys
List passkey credentials (authenticated).
Headers: Authorization: Bearer <token>
Response: 200 { passkeys: [...] }
DELETE /api/projects/:id/auth/passkeys/:credentialId
Delete a passkey credential (authenticated).
Headers: Authorization: Bearer <token>
Response: 200 { ok: true }
OAuth (Social Login)
GET /api/projects/:id/auth/oauth/:provider/authorize
Initiate OAuth authorization redirect.
Query: ?redirectUrl=...
Response: 302 redirect to provider's OAuth consent screen
GET /api/projects/:id/auth/oauth/:provider/callback
Handle OAuth callback from provider.
Query: ?code=...&state=...
Response: 302 redirect with session (or error query param)
OIDC / JWKS
GET /api/projects/:id/.well-known/openid-configuration
OpenID Connect Discovery document.
Response: 200 { issuer, authorization_endpoint, token_endpoint, jwks_uri, ... }
GET /api/projects/:id/.well-known/jwks.json
JSON Web Key Set for RS256 ID token verification.
Response: 200 { keys: [...] }
Server Admin Routes
These endpoints are called from your application server using the project's secret key (x-kyqu-secret-key header).
User Management
DELETE /api/projects/:id/admin/users/:userId
Delete a project user (server-to-server).
Headers: x-kyqu-secret-key: <project-secret>
Response: 200 { ok: true }
PATCH /api/projects/:id/admin/users/:userId/status
Update a user's status (server-to-server).
Headers: x-kyqu-secret-key: <project-secret>
Request: { status: "active" | "suspended", reason?: string }
Response: 200 { ok: true }
System
GET /api/health
Basic health check.
Response: 200 { ok: true }
GET /api/ready
Readiness check with subsystem status.
Response: 200 { ok: true, database: "ok", email: "...", rateLimitStore: "..." }