Registration
The account registration and onboarding flow spans account creation, handle validation, and profile completion. This page documents the live custom registration route in apps/api and the currently mounted Better Auth email sign-up route.
The registration and immediate onboarding workstream maps to KUB-112, KUB-114, and KUB-115.
Create Account
POST /api/v1/auth/registerBody
{
"name": "Jane Doe",
"email": "[email protected]",
"password": "your-password",
"passwordConfirmation": "your-password"
}Response
{
"data": {
"token": "<bearer-token>",
"expiresAt": "<iso8601-expires-at>",
"user": {
"id": "usr_123",
"email": "[email protected]",
"name": "Jane Doe",
"type": "user"
}
}
}The API stores the account in the Better Auth and Prisma-backed app_users table, then returns the existing /api/v1/* JWT response contract for client use. Admin users are not created through this surface and continue to authenticate through the Laravel/Filament admin app.
Error Responses
400 invalid_bodywhen the request body is malformed JSON or a JSON value other than an object409 email_takenwhen the email address is already registered422 validation_errorwhen one or more fields are invalid429 rate_limitedafter too many registration attempts from the same resolved client key; if trusted proxy IP headers are disabled or unavailable, registration throttling falls back to a shared bucket instead of trusting forwarded IP headers
Validation Rules
nameis required and should be a human-readable display name.emailis required and must be unique.passwordis required and must meet the production password policy.passwordConfirmationmust matchpassword.
Better Auth Email Sign-Up
The Better Auth handler also exposes:
POST /api/auth/sign-up/emailThat route is live and follows Better Auth request and response conventions. Use it when integrating a Better Auth client directly. Use POST /api/v1/auth/register when you need the Kubuli-specific JWT response envelope documented on this page.
Check Handle Availability
GET /api/v1/users/handle/check?handle=jane_doeUse this endpoint during onboarding before persisting the final profile.
Response
{
"data": {
"handle": "jane_doe",
"available": true
}
}Errors
422 validation_errorwhen the handle format is invalid
Create or Update the Onboarding Profile
POST /api/v1/users/profile
Authorization: Bearer <token>This route accepts either a valid user bearer token or a Better Auth session cookie. Guest identities cannot create a profile.
Body
{
"handle": "jane_doe",
"name": "Jane Doe"
}Response
{
"data": {
"user": {
"id": "usr_123",
"email": "[email protected]",
"name": "Jane Doe",
"handle": "jane_doe",
"type": "user",
"createdAt": "<iso8601-created-at>"
}
}
}Errors
400 invalid_bodywhen the request body is malformed JSON or a JSON value other than an object401 auth_requiredwhen no valid bearer token or session cookie is present, or the authenticated user no longer exists403 forbiddenwhen the caller is a guest identity409 handle_takenwhen the handle already belongs to another user422 validation_errorwhenhandleornamefails validation
Current Flow
The current onboarding flow is:
- Create the account with
POST /api/v1/auth/register. - Check candidate handles with
GET /api/v1/users/handle/check. - Persist the chosen profile with
POST /api/v1/users/profile. - Read the resulting identity with
GET /api/v1/me. - Update the saved profile later with
PATCH /api/v1/me.
Email verification and additional provider onboarding flows remain separate follow-up work. Current-user profile read and patch semantics are documented in Authentication.