Register a new user account with email, password, and name. Public access without authentication. Automatically creates a personal Tenant for the new user.
- MVP: email verification is skipped — the account is immediately active after registration.
- A personal Tenant is auto-created on sign-up; its slug is derived from the email local part (everything before
@). - Email must be unique across all users.
- Password must be at least 8 characters long.
- The response includes JWT access token (15 min) and refresh token (14 days).
sequenceDiagram
actor User
User->>+FE: fills sign up form
FE->>FE: validate form
alt form is invalid
FE-->>User: show error messages <br> disable submit button
end
User->>+FE: submits sign up form
FE->>+BE: POST /api/v1/auth/signup <br> SignUpRequest
BE->>BE: validate request
alt request is invalid
BE-->>FE: 400 Bad Request <br> ErrorResponse
end
BE->>DB: check if email already exists
alt email already exists
BE-->>FE: 409 Conflict <br> ErrorResponse
end
BE->>DB: create user
BE->>DB: create personal tenant (slug from email local part)
BE->>BE: generate access token
BE->>BE: generate refresh token
BE->>DB: store refresh token
BE->>-FE: 201 Created <br> AuthResponse
FE->>FE: store tokens in localStorage
FE->>-User: redirect to homepage
POST /api/v1/auth/signup SignUpRequest:
{
"email": "jane.doe@example.com",
"password": "secret123",
"name": "Jane Doe"
}
201 Created AuthResponse:
{
"data": {
"accessToken": "*****",
"refreshToken": "*****"
}
}
400 Bad Request (validation) ErrorResponse:
{
"status": 400,
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"errors": [
{ "field": "email", "message": "must be a valid email address" }
]
}
409 Conflict (email already registered) ErrorResponse:
{
"status": 409,
"code": "CONFLICT_USER",
"message": "Email is already registered"
}
Frontend
Validations
| Field | Constraints | Size | Pattern | Note |
|---|---|---|---|---|
| not_blank | ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ | |||
| password | not_blank | 8 - 72 | ||
| name | not_blank | 1 - 100 |
Backend
Validations
| Field | Constraints | Size | Pattern | Note |
|---|---|---|---|---|
| not_blank, email | ||||
| password | not_blank | 8 - 72 | ||
| name | not_blank | 1 - 100 |
Test Cases
| GIVEN | WHEN | THEN |
|---|---|---|
| email not yet registered | sign up is called | user created, personal tenant created, tokens returned |
| email already registered | sign up is called | 409 CONFLICT_USER error response is returned |
| password shorter than 8 chars | sign up is called | 400 VALIDATION_ERROR error response is returned |
| invalid email format | sign up is called | 400 VALIDATION_ERROR error response is returned |
| name is blank | sign up is called | 400 VALIDATION_ERROR error response is returned |
| invalid request (empty body) | sign up is called | 400 VALIDATION_ERROR error response is returned |
Was this page helpful?
Thanks for the feedback.