Auth - Owner Registration
Base path: /api/v1/auth
The owner registration flow requires 3 steps: (1) Request OTP → (2) Verify OTP → (3) Create account.
Used by: cms-booki-web-app · Role: guest (unauthenticated)
organizationId: Not applicable at registration time — the organization is created as part of step 3.
POST /api/v1/auth/register/owner/otp — Send OTP
Auth: Public
Description: Send a 6-digit OTP to the provided email for owner registration verification.
Request
{
"email": "jane@example.com"
}
Fields:
email(string, required): Valid email address where OTP will be sent
Response (200 OK)
{
"message": "Owner email OTP sent successfully. Kindly check your email for the OTP."
}
Error Responses
400 Bad Request — Invalid email or email already registered:
{
"statusCode": 400,
"message": "Email already registered as an owner account"
}
cURL Example
curl -X POST http://localhost:4001/api/v1/auth/register/owner/otp \
-H "Content-Type: application/json" \
-d '{"email": "jane@example.com"}'
POST /api/v1/auth/register/owner/otp/verify — Verify OTP
Auth: Public
Description: Verify the OTP code sent to email. OTP valid for 1 hour.
Request
{
"otp": "123456"
}
Fields:
otp(string, required): 6-digit code from email
Response (200 OK)
{
"message": "OTP verified successfully.",
"valid": true
}
Error Responses
400 Bad Request — Invalid or expired OTP:
{
"statusCode": 400,
"message": "Invalid or expired OTP"
}
404 Not Found — OTP not found for email:
{
"statusCode": 404,
"message": "No OTP found for this email"
}
cURL Example
curl -X POST http://localhost:4001/api/v1/auth/register/owner/otp/verify \
-H "Content-Type: application/json" \
-d '{"otp": "123456"}'
POST /api/v1/auth/register/owner — Create Owner Account
Auth: Public
Description: Complete owner registration with OTP, business details, and password.
Request
{
"otp": "123456",
"password": "SecureP@ss123",
"ownerDetails": {
"firstName": "Jane",
"middleName": "Marie", // (optional)
"lastName": "Doe",
"phone": "09171234567"
},
"businessDetails": {
"service": "69dcbe3f1a79a4eac35bc717",
"name": "Jane's Beauty Salon",
"businessPermit": "BP-2024-001",
"businessRegistration": "BR-2024-001",
"branch": 1,
"slug": "janes-salon",
"businessAddress": {
"region": "NCR",
"province": "Metro Manila",
"municipalOrCity": "Quezon City",
"barangay": "Doña Julia",
"zip": "1100",
"street": "Main Avenue", // (optional)
"address": "123 Business Complex" // (optional)
}
}
}
Fields:
otp(string, required): OTP from previous verification steppassword(string, required): Min 8 chars, must include uppercase, lowercase, number, special characterownerDetails(object, required):firstName(string, required): First name (max 255 chars)middleName(string, optional): Middle namelastName(string, required): Last name (max 255 chars)phone(string, required): Phone number (10-20 chars)
businessDetails(object, required):service(string, required): Booking service category ID (24-hex)name(string, required): Business name (max 255 chars)businessPermit(string, required): Permit documentation referencebusinessRegistration(string, required): Registration numberbranch(number, required): Number of branches (min 1)slug(string, required): Business slug (max 255 chars)businessAddress(object, required):region: Region name (required, max 255)province: Province name (required, max 255)municipalOrCity: Municipality/City (required, max 255)barangay: Barangay (required, max 255)zip: ZIP code (required, max 20)street: Street name (optional, max 255)address: Full address (optional, max 255)
Response (201 Created)
{
"message": "Business owner added successfully."
}
Error Responses
400 Bad Request — Invalid password or missing fields:
{
"statusCode": 400,
"message": "Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character"
}
409 Conflict — Business slug already in use:
{
"statusCode": 409,
"message": "Business slug 'janes-salon' is already taken"
}
cURL Example
curl -X POST http://localhost:4001/api/v1/auth/register/owner \
-H "Content-Type: application/json" \
-d '{
"otp": "123456",
"password": "SecureP@ss123",
"ownerDetails": {
"firstName": "Jane",
"middleName": "Marie",
"lastName": "Doe",
"phone": "09171234567"
},
"businessDetails": {
"service": "69dcbe3f1a79a4eac35bc717",
"name": "Jane'\''s Beauty Salon",
"businessPermit": "BP-2024-001",
"businessRegistration": "BR-2024-001",
"branch": 1,
"slug": "janes-salon",
"businessAddress": {
"region": "NCR",
"province": "Metro Manila",
"municipalOrCity": "Quezon City",
"barangay": "Doña Julia",
"zip": "1100",
"street": "Main Avenue",
"address": "123 Business Complex"
}
}
}'
Notes
- OTP codes expire after 1 hour.
- Business slug must be unique; recommended format: lowercase name with hyphens (e.g.,
janes-salon,acme-services). - Password complexity is strictly enforced; all 4 character types required.
- Owner account is created with
ACTIVEstatus and default branch automatically created. - See
booki-api/src/validations/user.validation.tsfor exact field requirements.
