Organizations - Packages
Base path: /api/v1/organizations/packages
Used by: owner-booki-web-app · Role: owner, branch-manager
organizationId: From authenticated user's JWT token (no tenant header needed)
Package endpoints allow owners/managers to manage service offerings. All require branch-manager or above authentication.
POST /api/v1/organizations/packages — Create Package
Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Create a new service package for the organization.
Request
{
"name": "Haircut + Wash",
"description": "Professional haircut with complimentary shampoo and conditioner wash. Includes styling.",
"amount": 450.0
}
Fields:
name(string, required): Package name (2-255 chars)description(string, required): Detailed description (10-500 chars)amount(number, required): Price in PHP (≥ 0)
Response (201 Created)
{
"message": "Package created successfully."
}
Error Responses
422 Unprocessable Entity — Missing fields:
{
"statusCode": 422,
"message": "Name is required."
}
422 Unprocessable Entity — Description too short:
{
"statusCode": 422,
"message": "Description must be at least 10 characters long."
}
403 Forbidden — Insufficient role:
{
"statusCode": 403,
"message": "Insufficient permissions to access this resource."
}
cURL Example
curl -X POST http://localhost:4001/api/v1/organizations/packages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGc..." \
-d '{
"name": "Haircut + Wash",
"description": "Professional haircut with complimentary shampoo and conditioner wash. Includes styling.",
"amount": 450.00
}'
GET /api/v1/organizations/packages — List Packages
Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: List all packages for the authenticated user's organization.
Request
Query Parameters (optional):
page(number, default: 1)limit(number, default: 10, max: 100)search(string): Filter by package namesort(string, default:_id)order(string, default:desc)
GET /api/v1/organizations/packages?page=1&limit=20&search=wash
Response (200 OK)
{
"items": [
{
"_id": "69de52154f3e4272e30c7a14",
"name": "Haircut + Wash",
"description": "Professional haircut with complimentary shampoo and conditioner wash. Includes styling.",
"amount": 450,
"createdAt": "2026-04-14T14:41:25.867Z",
"updatedAt": "2026-04-14T14:41:25.867Z"
},
{
"_id": "69de52bc4f3e4272e30c7a15",
"name": "Hair Coloring Package",
"description": "Full hair coloring service using premium dye. Includes consultation, application, and rinse.",
"amount": 1500,
"createdAt": "2026-04-14T14:44:12.229Z",
"updatedAt": "2026-04-14T14:44:12.229Z"
}
],
"pages": 1,
"pageRange": "1-2 of 2"
}
cURL Example
curl -X GET "http://localhost:4001/api/v1/organizations/packages?page=1&limit=20" \
-H "Authorization: Bearer eyJhbGc..."
GET /api/v1/organizations/packages/:id — Get Package
Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Retrieve a specific package by ID.
Request
GET /api/v1/organizations/packages/69de52154f3e4272e30c7a14
Response (200 OK)
{
"_id": "69de52154f3e4272e30c7a14",
"name": "Haircut + Wash",
"description": "Professional haircut with complimentary shampoo and conditioner wash. Includes styling.",
"amount": 450,
"organizationId": "69dcbeec1a79a4eac35bc721",
"createdAt": "2026-04-14T14:41:25.867Z",
"updatedAt": "2026-04-14T14:41:25.867Z",
"deletedAt": null
}
Error Responses
404 Not Found — Package doesn't exist:
{
"statusCode": 404,
"message": "Package not found"
}
cURL Example
curl -X GET http://localhost:4001/api/v1/organizations/packages/69de52154f3e4272e30c7a14 \
-H "Authorization: Bearer eyJhbGc..."
PUT /api/v1/organizations/packages/:id — Update Package
Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Update package details. At least one field must be provided.
Request
{
"name": "Haircut + Premium Wash",
"description": "Professional haircut with premium hair spa wash treatment.",
"amount": 550.0
}
All fields optional; at least one required:
name(string, 2-255 chars)description(string, 10-500 chars)amount(number, ≥ 0)
Response (200 OK)
{
"message": "Package updated successfully."
}
Error Responses
400 Bad Request — No fields provided:
{
"statusCode": 400,
"message": "At least one field must be provided for update"
}
cURL Example
curl -X PUT http://localhost:4001/api/v1/organizations/packages/69de52154f3e4272e30c7a14 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGc..." \
-d '{
"name": "Haircut + Premium Wash",
"amount": 550.00
}'
DELETE /api/v1/organizations/packages/:id — Delete Package
Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Soft-delete a package (marks deletedAt, not removed from DB).
Request
DELETE /api/v1/organizations/packages/69de52154f3e4272e30c7a14
Response (200 OK)
{
"message": "Package deleted successfully."
}
Error Responses
404 Not Found — Package not found:
{
"statusCode": 404,
"message": "Package not found"
}
409 Conflict — Active bookings prevent deletion:
{
"statusCode": 409,
"message": "Cannot delete package with active bookings"
}
cURL Example
curl -X DELETE http://localhost:4001/api/v1/organizations/packages/69de52154f3e4272e30c7a14 \
-H "Authorization: Bearer eyJhbGc..."
Public Packages (Customer View)
Customers and guests see packages without authentication.
Used by: customer-booki-web-app · Role: guest / customer
organizationId: Resolved by tenant middleware from x-tenant-slug header or subdomain.
GET /api/v1/packages (public, tenant required)
GET /api/v1/packages/:id (public, tenant required)
These endpoints return only active, non-deleted packages and don't require authentication. See Services & Contact Form for details.
Notes
- Packages are scoped to the organization; managers can only see their org's packages.
- Prices are in PHP (Philippine Peso).
- Deleted packages are soft-deleted (
deletedAttimestamp) but remain in DB. - Pagination defaults to 10 items per page (max 100).
- See
booki-api/src/validations/package.validation.tsfor exact constraints.
