API

Organizations - Packages

Create, list, update, and delete service packages (owner endpoints).

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 name
  • sort (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 (deletedAt timestamp) but remain in DB.
  • Pagination defaults to 10 items per page (max 100).
  • See booki-api/src/validations/package.validation.ts for exact constraints.