API

Organizations - Business Hours

Get and update business operating hours, timeslots, and availability.

Base path: /api/v1/organizations/business-hours

Used by: owner-booki-web-app · Role: owner, branch-manager
organizationId: From authenticated user's JWT token (no tenant header needed)

Business hours define when the business operates and automatic timeslot generation. Owner can manage hours; customers view them for booking.


GET /api/v1/organizations/business-hours — Get Business Hours

Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Retrieve business hours and settings for the organization.

Request

GET /api/v1/organizations/business-hours

Response (200 OK)

{
  "businessHours": [
    {
      "day": "monday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "tuesday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "wednesday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "thursday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "friday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "saturday",
      "isOpen": false,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "sunday",
      "isOpen": false,
      "openTime": "08:00",
      "closeTime": "17:00"
    }
  ],
  "timezone": "Asia/Manila",
  "intervalMinutes": 60
}

cURL Example

curl -X GET http://localhost:4001/api/v1/organizations/business-hours \
  -H "Authorization: Bearer eyJhbGc..."

GET /api/v1/organizations/business-hours/open-days — Get Open Days

Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Get list of days the business is open.

Response (200 OK)

["monday", "tuesday", "wednesday", "thursday", "friday"]

cURL Example

curl -X GET http://localhost:4001/api/v1/organizations/business-hours/open-days \
  -H "Authorization: Bearer eyJhbGc..."

GET /api/v1/organizations/business-hours/timeslots — Get Available Timeslots

Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Generate available timeslots for a specific date based on business hours and interval.

Request

Query Parameters:

  • day (string, optional): Target date in YYYY-MM-DD format. Defaults to today.
  • period (string, optional): all (default), am, or pm
GET /api/v1/organizations/business-hours/timeslots?day=2026-04-10&period=all

Response (200 OK)

{
  "timezone": "Asia/Manila",
  "timeslots": [
    {
      "startTime": "08:00",
      "endTime": "09:00"
    },
    {
      "startTime": "09:00",
      "endTime": "10:00"
    },
    {
      "startTime": "10:00",
      "endTime": "11:00"
    },
    {
      "startTime": "11:00",
      "endTime": "12:00"
    },
    {
      "startTime": "12:00",
      "endTime": "13:00"
    },
    {
      "startTime": "13:00",
      "endTime": "14:00"
    },
    {
      "startTime": "14:00",
      "endTime": "15:00"
    },
    {
      "startTime": "15:00",
      "endTime": "16:00"
    },
    {
      "startTime": "16:00",
      "endTime": "17:00"
    }
  ]
}

With period=am:

{
  "timezone": "Asia/Manila",
  "timeslots": [
    {
      "startTime": "08:00",
      "endTime": "09:00"
    },
    {
      "startTime": "09:00",
      "endTime": "10:00"
    },
    {
      "startTime": "10:00",
      "endTime": "11:00"
    },
    {
      "startTime": "11:00",
      "endTime": "12:00"
    }
  ]
}

cURL Example

curl -X GET "http://localhost:4001/api/v1/organizations/business-hours/timeslots?day=2026-04-10&period=all" \
  -H "Authorization: Bearer eyJhbGc..."

PUT /api/v1/organizations/business-hours — Update Business Hours

Auth: Protected (Authorization: Bearer <accessToken>) · branch-manager+
Used by: owner-booki-web-app · Role: owner, branch-manager
Description: Update business hours, timezone, and booking interval.

Request

{
  "businessHours": [
    {
      "day": "monday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "tuesday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "wednesday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "thursday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "friday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "saturday",
      "isOpen": true,
      "openTime": "08:00",
      "closeTime": "17:00"
    },
    {
      "day": "sunday",
      "isOpen": false,
      "openTime": "08:00",
      "closeTime": "17:00"
    }
  ],
  "timezone": "Asia/Manila",
  "intervalMinutes": 60
}

Fields:

  • timezone (string, required): IANA timezone (e.g., Asia/Manila, America/New_York)
  • intervalMinutes (number, optional): Booking interval in minutes (15-60, default: 30)
  • businessHours (array, required): Exactly 7 days (monday-sunday)
    • day (string): Day name
    • isOpen (boolean): Whether open
    • openTime (string, ISO HH:MM): Required if isOpen=true
    • closeTime (string, ISO HH:MM): Required if isOpen=true

Response (200 OK)

{
  "message": "Business hours updated successfully."
}

Error Responses

400 Bad Request — Missing days:

{
  "statusCode": 400,
  "message": "Business hours must contain exactly 7 days"
}

400 Bad Request — Open time missing:

{
  "statusCode": 400,
  "message": "Open time is required when the day is open"
}

cURL Example

curl -X PUT http://localhost:4001/api/v1/organizations/business-hours \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGc..." \
  -d '{
    "timezone": "Asia/Manila",
    "intervalMinutes": 30,
    "businessHours": [
      {"day": "monday", "isOpen": true, "openTime": "09:00", "closeTime": "18:00"},
      {"day": "tuesday", "isOpen": true, "openTime": "09:00", "closeTime": "18:00"},
      {"day": "wednesday", "isOpen": true, "openTime": "09:00", "closeTime": "18:00"},
      {"day": "thursday", "isOpen": true, "openTime": "09:00", "closeTime": "18:00"},
      {"day": "friday", "isOpen": true, "openTime": "09:00", "closeTime": "18:00"},
      {"day": "saturday", "isOpen": true, "openTime": "10:00", "closeTime": "16:00"},
      {"day": "sunday", "isOpen": false, "openTime": null, "closeTime": null}
    ]
  }'

Public Business Hours (Customer View)

Customers and guests see business hours 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/business-hours          (public, tenant required)
GET /api/v1/business-hours/open-days  (public, tenant required)
GET /api/v1/business-hours/timeslots  (public, tenant required)

These endpoints help customers view availability before booking. No authentication needed.


Notes

  • Timezone: Use IANA timezone strings (e.g., Asia/Manila, Europe/London, America/New_York).
  • Interval: Timeslots are generated at this interval (default 30 min). Affects booking availability.
  • Days: Exactly 7 days required (monday-sunday). Closed days have isOpen=false and null times.
  • Times: 24-hour format HH:MM (e.g., 09:00, 18:00).
  • Timeslots are auto-generated; not pre-defined. See booki-api/src/validations/organization.validation.ts.