openapi: 3.0.3 info: title: Phorest Third-Party API description: >- The Phorest API exposes a partner-gated business's salon/spa data - clients, appointments, bookings, staff, services, products, purchases, vouchers, loyalty, and reporting - for approved integrators. Access is granted by Phorest support on request (quoting a Phorest Account Number), not through self-service signup. Requests use HTTP Basic authentication with a `global/{email}` username and a Phorest-issued API password, and are scoped in the URL path to a `businessId` and, for most resources, a `branchId`. Endpoints, methods, and parameters in this document are transcribed from Phorest's public API reference at developer.phorest.com/reference; a small number of item-level paths (marked in their description) are modeled by convention from the confirmed collection-level siblings because Phorest's public reference does not expose every single-resource path in plain text. version: '1.0' contact: name: Phorest API Support email: api-requests@phorest.com url: https://developer.phorest.com/docs/getting-started license: name: Proprietary - partner access only url: https://developer.phorest.com/docs/requesting-assistance-with-the-phorest-api servers: - url: https://api-gateway-eu.phorest.com/third-party-api-server/api/business description: EU production gateway - url: https://api-gateway-us.phorest.com/third-party-api-server/api/business description: US/AUS production gateway - url: https://platform.phorest.com/third-party-api-server/api/business description: EU production alias documented in Phorest support articles security: - basicAuth: [] tags: - name: Clients description: Client (customer) records and client categories. - name: Appointments description: Appointment lifecycle - list, retrieve, update, cancel, confirm, check in. - name: Bookings description: Booking creation and lifecycle, plus real-time availability checks. - name: Staff description: Staff records, rota/work-time tables, and staff breaks. - name: Services description: Services, service categories, packages, and special offers. - name: Branches description: Branches (locations), rooms, machines, and tax rates. - name: Products description: Retail products and inventory. - name: Purchases description: Point-of-sale purchases, stock adjustments, and till balances. - name: Vouchers description: Gift voucher creation, lookup, and balance updates. - name: Loyalty description: Client loyalty point adjustments. - name: Courses description: Course templates and a client's purchased course sessions. - name: Reporting description: Asynchronous CSV export jobs for sale-level reporting. - name: Reviews description: Client reviews for syndication to external review platforms. - name: Leads description: Marketing leads and lead statistics. paths: /{businessId}/client: parameters: - $ref: '#/components/parameters/BusinessId' get: operationId: getClients tags: [Clients] summary: List clients description: >- Lists clients for a business, filterable by email, phone, name, or update time. Confirmed: developer.phorest.com/reference/getclients. parameters: - name: email in: query schema: { type: string } - name: phone in: query schema: { type: string } - name: firstName in: query schema: { type: string } - name: lastName in: query schema: { type: string } - name: externalId in: query schema: { type: string } - name: updatedAfter in: query schema: { type: string, format: date-time } - name: updatedBefore in: query schema: { type: string, format: date-time } - name: includeArchived in: query schema: { type: boolean } - name: includeDeleted in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Clients listed successfully. content: application/json: schema: type: object properties: _embedded: type: object properties: clients: type: array items: { $ref: '#/components/schemas/Client' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } post: operationId: createClient tags: [Clients] summary: Create a client description: >- Creates a client - for example from a website newsletter signup. Confirmed: developer.phorest.com/docs/using-the-client-endpoint. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ClientInput' } responses: '201': description: Client created successfully. content: application/json: schema: { $ref: '#/components/schemas/Client' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/client/{clientId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/ClientId' get: operationId: getClient tags: [Clients] summary: Retrieve a client description: >- Retrieves a single client by ID. Modeled by convention from the confirmed getClients/updateClient siblings - not shown as its own text page in the public reference. responses: '200': description: The requested client. content: application/json: schema: { $ref: '#/components/schemas/Client' } '404': { $ref: '#/components/responses/NotFound' } put: operationId: updateClient tags: [Clients] summary: Update a client description: >- Updates an existing client. The request body must include the client's current `version`; Phorest increments it on success. Confirmed: developer.phorest.com/docs/using-the-client-endpoint. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ClientInput' } responses: '200': description: Client updated successfully. content: application/json: schema: { $ref: '#/components/schemas/Client' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } /{businessId}/client/walkin: parameters: - $ref: '#/components/parameters/BusinessId' get: operationId: getWalkInClient tags: [Clients] summary: Retrieve the walk-in client description: >- Retrieves the business's placeholder "walk-in" client record, used for bookings/purchases with no named client. Modeled from the reference page name getwalkinclient by convention with the client resource root. responses: '200': description: The walk-in client record. content: application/json: schema: { $ref: '#/components/schemas/Client' } /{businessId}/category/client: parameters: - $ref: '#/components/parameters/BusinessId' get: operationId: getClientCategories tags: [Clients] summary: List client categories description: >- Lists client categories used for marketing/newsletter segmentation. Confirmed: developer.phorest.com/reference/getclientcategories. parameters: - name: name in: query schema: { type: string } - name: includeArchived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Client categories listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/ClientCategory' } /{businessId}/category/client/{categoryId}: parameters: - $ref: '#/components/parameters/BusinessId' - name: categoryId in: path required: true schema: { type: string } get: operationId: getClientCategory tags: [Clients] summary: Retrieve a client category description: >- Retrieves a single client category by ID. Modeled by convention from the confirmed getClientCategories sibling. responses: '200': description: The requested client category. content: application/json: schema: { $ref: '#/components/schemas/ClientCategory' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/appointment: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getAppointments tags: [Appointments] summary: List appointments description: >- Lists appointments for a business/branch over at most a one-month range, filterable by date, update time, staff, room, machine, client, or group booking. Confirmed: developer.phorest.com/reference/getappointments. parameters: - name: from_date in: query schema: { type: string, format: date } - name: to_date in: query schema: { type: string, format: date } - name: staff_id in: query schema: { type: string } - name: room_id in: query schema: { type: string } - name: machine_id in: query schema: { type: string } - name: client_id in: query schema: { type: string } - name: group_booking_id in: query schema: { type: string } - name: fetch_canceled in: query schema: { type: boolean } - name: fetch_deleted in: query schema: { type: boolean } - name: fetch_archived in: query schema: { type: boolean } - name: fetch_notes in: query schema: { type: boolean } - name: updated_from in: query schema: { type: string, format: date-time } - name: updated_to in: query schema: { type: string, format: date-time } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Appointments listed successfully. content: application/json: schema: type: object properties: _embedded: type: object properties: appointments: type: array items: { $ref: '#/components/schemas/Appointment' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/appointment/{appointmentId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/AppointmentId' get: operationId: getAppointment tags: [Appointments] summary: Retrieve an appointment description: >- Retrieves a single appointment by ID. Modeled by convention from the confirmed getAppointments/updateAppointment siblings. responses: '200': description: The requested appointment. content: application/json: schema: { $ref: '#/components/schemas/Appointment' } '404': { $ref: '#/components/responses/NotFound' } put: operationId: updateAppointment tags: [Appointments] summary: Update an appointment description: >- Updates an appointment (for example rescheduling or reassigning staff/room). Confirmed to exist: developer.phorest.com/reference/updateappointment; sub-path modeled by convention with the confirmed collection path. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/AppointmentInput' } responses: '200': description: Appointment updated successfully. content: application/json: schema: { $ref: '#/components/schemas/Appointment' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } /{businessId}/branch/{branchId}/appointment/{appointmentId}/cancel: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/AppointmentId' post: operationId: cancelAppointment tags: [Appointments] summary: Cancel an appointment description: >- Cancels an appointment. Confirmed to exist: developer.phorest.com/reference/cancelappointments; sub-path modeled by convention with the confirmed action-suffix pattern used by cancelBooking/confirmAppointment. responses: '200': description: Appointment canceled successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/appointment/{appointmentId}/confirm: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/AppointmentId' post: operationId: confirmAppointment tags: [Appointments] summary: Confirm an appointment description: >- Marks an appointment as confirmed. Confirmed to exist: developer.phorest.com/reference/confirmappointments; sub-path modeled by convention. responses: '200': description: Appointment confirmed successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/appointment/{appointmentId}/checkin: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/AppointmentId' post: operationId: checkInAppointment tags: [Appointments] summary: Check in an appointment description: >- Checks a client in for an appointment. Confirmed to exist: developer.phorest.com/reference/checkin_1; sub-path modeled by convention. responses: '200': description: Appointment checked in successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/appointments/availability: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: checkAppointmentAvailability tags: [Bookings] summary: Check appointment availability description: >- Returns available appointment slots for a set of requested services within a time window; optionally scoped to a client or an existing booking being rescheduled. Confirmed: developer.phorest.com/reference/checkappointmentavailability. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/AvailabilityRequest' } responses: '200': description: Appointment availabilities listed. content: application/json: schema: type: object properties: availableSlots: type: array items: { $ref: '#/components/schemas/AvailabilitySlot' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/booking: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: createBooking tags: [Bookings] summary: Create a booking description: >- Creates a booking (one or more scheduled services) for a client. Confirmed: developer.phorest.com/reference/createbooking. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/BookingInput' } responses: '201': description: Booking created successfully. content: application/json: schema: { $ref: '#/components/schemas/Booking' } '400': description: Booking data is invalid, unable to create a booking. '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/booking/{bookingId}/cancel: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: bookingId in: path required: true schema: { type: string } post: operationId: cancelBooking tags: [Bookings] summary: Cancel a booking description: >- Cancels a booking. Confirmed to exist: developer.phorest.com/reference/cancelbooking; sub-path modeled by convention. responses: '200': description: Booking canceled successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/booking/{bookingId}/activate: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: bookingId in: path required: true schema: { type: string } post: operationId: activateBooking tags: [Bookings] summary: Activate a reserved booking description: >- Activates a RESERVED booking, turning a temporary hold into an ACTIVE booking. Confirmed to exist: developer.phorest.com/reference/activatebooking; sub-path modeled by convention. responses: '200': description: Booking activated successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/booking/{bookingId}/note: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: bookingId in: path required: true schema: { type: string } post: operationId: appendNoteToBooking tags: [Bookings] summary: Append a note to a booking description: >- Appends a service/colour note to an existing booking. Confirmed to exist: developer.phorest.com/reference/appendnotetobooking; sub-path modeled by convention. requestBody: required: true content: application/json: schema: type: object properties: note: type: string maxLength: 50000 responses: '200': description: Note appended successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/deposit-payment-link: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: createDepositPaymentLink tags: [Bookings] summary: Create a deposit payment link description: >- Creates a hosted payment link so a client can pay a booking deposit online. Confirmed to exist: developer.phorest.com/reference/createdepositpaymentlink; sub-path modeled by convention. requestBody: required: true content: application/json: schema: type: object properties: bookingId: { type: string } amount: { type: number } responses: '201': description: Deposit payment link created successfully. content: application/json: schema: type: object properties: paymentLinkUrl: { type: string, format: uri } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/staff: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getStaffList tags: [Staff] summary: List staff description: >- Lists staff for a branch, filterable by update time and archived status. Confirmed: developer.phorest.com/reference/getstafflist. parameters: - name: updatedAfter in: query schema: { type: string } - name: updatedBefore in: query schema: { type: string } - name: fetch_archived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Staff listed successfully. content: application/json: schema: type: object properties: _embedded: type: object properties: staffs: type: array items: { $ref: '#/components/schemas/Staff' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/staff/{staffId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: staffId in: path required: true schema: { type: string } get: operationId: getStaff tags: [Staff] summary: Retrieve a staff member description: >- Retrieves a single staff member by ID. Confirmed to exist: developer.phorest.com/reference/getstaff; sub-path modeled by convention with the confirmed collection path. responses: '200': description: The requested staff member. content: application/json: schema: { $ref: '#/components/schemas/Staff' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/staff-work-time-table: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getStaffWorkTimeTables tags: [Staff] summary: List staff work time tables (rota) description: >- Returns staff work-time entries (rota) for a date range. This endpoint does not support pagination and always returns all records for the given range. Confirmed: developer.phorest.com/reference/getstaffworktimetables. parameters: - name: from_date in: query required: true schema: { type: string, format: date } - name: to_date in: query required: true schema: { type: string, format: date } responses: '200': description: Staff work time tables listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/StaffWorkTimeEntry' } /{businessId}/branch/{branchId}/staff/{staffId}/break: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: staffId in: path required: true schema: { type: string } get: operationId: getBreaks tags: [Staff] summary: List a staff member's breaks description: >- Lists breaks scheduled for a staff member. Confirmed to exist: developer.phorest.com/reference/getbreaks; sub-path modeled by convention. responses: '200': description: Breaks listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/StaffBreak' } post: operationId: createBreak tags: [Staff] summary: Create a staff break description: >- Creates a break on a staff member's rota. Confirmed to exist: developer.phorest.com/reference/createbreak; sub-path modeled by convention. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StaffBreakInput' } responses: '201': description: Break created successfully. content: application/json: schema: { $ref: '#/components/schemas/StaffBreak' } /{businessId}/branch/{branchId}/staff/{staffId}/break/{breakId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: staffId in: path required: true schema: { type: string } - name: breakId in: path required: true schema: { type: string } get: operationId: getStaffBreak tags: [Staff] summary: Retrieve a staff break description: >- Retrieves a single break by ID. Confirmed to exist: developer.phorest.com/reference/getstaffbreak; sub-path modeled by convention. responses: '200': description: The requested break. content: application/json: schema: { $ref: '#/components/schemas/StaffBreak' } '404': { $ref: '#/components/responses/NotFound' } put: operationId: updateBreak tags: [Staff] summary: Update a staff break description: >- Updates an existing break. Confirmed to exist: developer.phorest.com/reference/updatebreak; sub-path modeled by convention. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StaffBreakInput' } responses: '200': description: Break updated successfully. content: application/json: schema: { $ref: '#/components/schemas/StaffBreak' } '404': { $ref: '#/components/responses/NotFound' } delete: operationId: deleteBreak tags: [Staff] summary: Delete a staff break description: >- Deletes a break. Confirmed to exist: developer.phorest.com/reference/deletebreak; sub-path modeled by convention. responses: '200': description: Break deleted successfully. '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/service: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getServices tags: [Services] summary: List branch services description: >- Lists services offered at a branch, with price and duration data. Modeled by convention: the item path GET /{businessId}/branch/{branchId}/service/{serviceId} is confirmed at developer.phorest.com/reference/getservice ("Retrieve a branch service"); the bare collection path follows the same list/item pattern confirmed across every other resource in this API. parameters: - name: category_id in: query schema: { type: string } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Services listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Service' } /{businessId}/branch/{branchId}/service/{serviceId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: serviceId in: path required: true schema: { type: string } get: operationId: getService tags: [Services] summary: Retrieve a branch service description: >- Retrieves a single branch service by ID, with an optional flag to include its online category. Confirmed: developer.phorest.com/reference/getservice. parameters: - name: fetch_online_category in: query schema: { type: boolean } responses: '200': description: The requested service. content: application/json: schema: { $ref: '#/components/schemas/Service' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/service-category: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getServiceCategories tags: [Services] summary: List service categories description: >- Lists service categories for a branch. Confirmed: developer.phorest.com/reference/getservicecategories. parameters: - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Service categories listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/ServiceCategory' } /{businessId}/branch/{branchId}/package: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getServicePackages tags: [Services] summary: List service packages description: >- Lists bundled service packages for a branch, filterable by service category. Confirmed: developer.phorest.com/reference/getservicepackages. parameters: - name: category_id in: query schema: { type: string } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Service packages listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/ServicePackage' } /{businessId}/branch/{branchId}/service-special-offer: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getServiceSpecialOffers tags: [Services] summary: List service special offers description: >- Lists discounted service special offers for a branch, filterable by service category. Confirmed: developer.phorest.com/reference/getservices_1. parameters: - name: category_id in: query schema: { type: string } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Service special offers listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/ServiceSpecialOffer' } /{businessId}/branch/{branchId}/course: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getCourses tags: [Courses] summary: List course templates description: >- Lists prepaid-session course templates (e.g. "10-session laser hair removal") offered at a branch. Confirmed: developer.phorest.com/reference/getcourses. parameters: - name: includeArchived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Courses listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Course' } /{businessId}/branch/{branchId}/client/{clientId}/course: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/ClientId' get: operationId: getClientCourses tags: [Courses] summary: List a client's purchased courses description: >- Lists the course instances a client has purchased, with remaining session counts. Confirmed to exist: developer.phorest.com/reference/getclientcourses; sub-path modeled by convention. responses: '200': description: Client courses listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/ClientCourse' } /{businessId}/branch/{branchId}/client/{clientId}/course/{courseId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - $ref: '#/components/parameters/ClientId' - name: courseId in: path required: true schema: { type: string } get: operationId: getClientCourse tags: [Courses] summary: Retrieve a client's course description: >- Retrieves a single client course instance by ID. Confirmed to exist: developer.phorest.com/reference/getclientcourse; sub-path modeled by convention. responses: '200': description: The requested client course. content: application/json: schema: { $ref: '#/components/schemas/ClientCourse' } '404': { $ref: '#/components/responses/NotFound' } put: operationId: updateClientCourse tags: [Courses] summary: Update a client's course description: >- Updates a client course instance (for example, adjusting remaining sessions). Confirmed to exist: developer.phorest.com/reference/updateclientcourse; sub-path modeled by convention. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ClientCourse' } responses: '200': description: Client course updated successfully. content: application/json: schema: { $ref: '#/components/schemas/ClientCourse' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch: parameters: - $ref: '#/components/parameters/BusinessId' get: operationId: getBranches tags: [Branches] summary: List branches description: >- Lists a business's branches (locations). Confirmed: developer.phorest.com/reference/getbranches. parameters: - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Branches listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Branch' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/worktimetable: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getBranchWorkTimeTable tags: [Branches] summary: Retrieve a branch's work time table description: >- Returns the branch's opening hours / work-time table. Confirmed to exist: developer.phorest.com/reference/getbranchworktimetable; sub-path modeled by convention. responses: '200': description: Branch work time table. content: application/json: schema: { $ref: '#/components/schemas/BranchWorkTimeTable' } /{businessId}/branch/{branchId}/room: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getRooms tags: [Branches] summary: List treatment rooms description: >- Lists treatment rooms for a branch, filterable by update date and archived status. Confirmed: developer.phorest.com/reference/getrooms. parameters: - name: updated_from in: query schema: { type: string, format: date-time } - name: includeArchived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Rooms listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Room' } /{businessId}/branch/{branchId}/room/{roomId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: roomId in: path required: true schema: { type: string } get: operationId: getRoom tags: [Branches] summary: Retrieve a treatment room description: >- Retrieves a single room by ID. Confirmed to exist: developer.phorest.com/reference/getroom; sub-path modeled by convention. responses: '200': description: The requested room. content: application/json: schema: { $ref: '#/components/schemas/Room' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/machine: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getMachines tags: [Branches] summary: List machines description: >- Lists equipment/machines for a branch, filterable by update date and archived status. Confirmed: developer.phorest.com/reference/getmachines. parameters: - name: updated_from in: query schema: { type: string, format: date-time } - name: includeArchived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Machines listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Machine' } /{businessId}/branch/{branchId}/machine/{machineId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: machineId in: path required: true schema: { type: string } get: operationId: getMachine tags: [Branches] summary: Retrieve a machine description: >- Retrieves a single machine by ID. Confirmed to exist: developer.phorest.com/reference/getmachine; sub-path modeled by convention. responses: '200': description: The requested machine. content: application/json: schema: { $ref: '#/components/schemas/Machine' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/taxrate: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getTaxRates tags: [Branches] summary: List tax rates description: >- Lists tax rates configured for a branch. Confirmed: developer.phorest.com/reference/gettaxrates. parameters: - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Tax rates listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/TaxRate' } /{businessId}/branch/{branchId}/taxrate/{taxRateId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: taxRateId in: path required: true schema: { type: string } get: operationId: getTaxRate tags: [Branches] summary: Retrieve a tax rate description: >- Retrieves a single tax rate by ID. Confirmed to exist: developer.phorest.com/reference/gettaxrate; sub-path modeled by convention. responses: '200': description: The requested tax rate. content: application/json: schema: { $ref: '#/components/schemas/TaxRate' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/product: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getProducts tags: [Products] summary: List retail products description: >- Lists retail products for a branch with stock level, pricing, and barcode data. Confirmed: developer.phorest.com/reference/getproducts. parameters: - name: productType in: query schema: { type: string } - name: searchQuery in: query schema: { type: string } - name: archivedOnly in: query schema: { type: boolean } - name: outOfStock in: query schema: { type: boolean } - name: lowStock in: query schema: { type: boolean } - name: includeArchived in: query schema: { type: boolean } - name: updated_from in: query schema: { type: string, format: date-time } - name: updated_to in: query schema: { type: string, format: date-time } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Products listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Product' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/inventorytransaction: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getInventoryTransactions tags: [Purchases] summary: List inventory transactions description: >- Lists inventory transactions (stock movements) for a branch. Confirmed: developer.phorest.com/reference/getinventorytransactions. parameters: - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Inventory transactions listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/InventoryTransaction' } /{businessId}/branch/{branchId}/stock/adjustment: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: performStockAdjustment tags: [Purchases] summary: Perform a stock adjustment description: >- Manually adjusts stock quantities for one or more products by barcode. Confirmed: developer.phorest.com/reference/performstockadjustment. requestBody: required: true content: application/json: schema: type: object required: [stocks] properties: stocks: type: array minItems: 1 items: type: object properties: barcodes: type: array items: { type: string } quantity: { type: number } reason: { type: string } responses: '204': description: Stock adjustment applied successfully. '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/purchase: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: createPurchase tags: [Purchases] summary: Create a purchase description: >- Records a point-of-sale purchase (appointments, products, courses, and/or vouchers) against a client, automatically updating stock. Also emits a purchase event onto a partner-provisioned AWS SQS queue per Phorest's public sqs-sample reference project. Confirmed: developer.phorest.com/reference/createpurchase. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/PurchaseInput' } responses: '201': description: Purchase created successfully. content: application/json: schema: { $ref: '#/components/schemas/Purchase' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/till/{tillId}/balance: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: tillId in: path required: true schema: { type: string } get: operationId: getTillBalance tags: [Purchases] summary: Retrieve a till balance description: >- Retrieves the till balance for a branch till, optionally including integrated-payment balances. Confirmed: developer.phorest.com/reference/gettillbalance. parameters: - name: includeIntegratedPayments in: query schema: { type: boolean } responses: '200': description: Till balance retrieved successfully. content: application/json: schema: { $ref: '#/components/schemas/TillBalance' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/salefee: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getSaleFeeList tags: [Purchases] summary: List sale fees description: >- Lists configured sale fees (e.g. card-processing or service fees) for a branch. Confirmed: developer.phorest.com/reference/getsalefeelist. parameters: - name: includeArchived in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Sale fees listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/SaleFee' } /{businessId}/voucher: parameters: - $ref: '#/components/parameters/BusinessId' get: operationId: getVouchers tags: [Vouchers] summary: List vouchers description: >- Lists gift vouchers for a business, filterable by client, serial number, and update time. Confirmed: developer.phorest.com/reference/getvouchers. parameters: - name: clientId in: query schema: { type: string } - name: serialNumber in: query schema: { type: string } - name: includeUsed in: query schema: { type: boolean } - name: updated_from in: query schema: { type: string, format: date-time } - name: updated_to in: query schema: { type: string, format: date-time } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Vouchers listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Voucher' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } post: operationId: createVoucher tags: [Vouchers] summary: Create a voucher description: >- Creates a gift voucher for a business. Confirmed: developer.phorest.com/reference/createvoucher. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/VoucherInput' } responses: '201': description: Voucher created successfully. content: application/json: schema: { $ref: '#/components/schemas/Voucher' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '412': description: A voucher with the specified serial number already exists. '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/voucher/{voucherId}: parameters: - $ref: '#/components/parameters/BusinessId' - name: voucherId in: path required: true schema: { type: string } get: operationId: getVoucher tags: [Vouchers] summary: Retrieve a voucher description: >- Retrieves a single voucher by ID. Confirmed: developer.phorest.com/reference/getvoucher. responses: '200': description: The requested voucher. content: application/json: schema: { $ref: '#/components/schemas/Voucher' } '404': { $ref: '#/components/responses/NotFound' } put: operationId: updateVoucherBalance tags: [Vouchers] summary: Update a voucher's balance description: >- Updates a voucher's remaining balance. Confirmed: developer.phorest.com/reference/updatevoucherbalance. requestBody: required: true content: application/json: schema: type: object required: [remainingBalance] properties: remainingBalance: { type: number } responses: '200': description: Voucher balance updated successfully. content: application/json: schema: { $ref: '#/components/schemas/Voucher' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/loyaltypoints: parameters: - $ref: '#/components/parameters/BusinessId' post: operationId: changeLoyaltyPoints tags: [Loyalty] summary: Add or deduct a client's loyalty points description: >- Adds or deducts loyalty points for a client at a branch. Confirmed: developer.phorest.com/reference/changeloyaltypoints. requestBody: required: true content: application/json: schema: type: object required: [clientId, branchId, description, pointsChange, operationType] properties: clientId: { type: string } branchId: { type: string } description: { type: string } pointsChange: { type: integer } operationType: type: string enum: [ADD, DEDUCT] responses: '200': description: Loyalty points changed successfully. '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } /{businessId}/branch/{branchId}/csvexportjob: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' post: operationId: createCsvExportJob tags: [Reporting] summary: Create a CSV export job description: >- Creates an asynchronous CSV export job (transactions, sundries, DATEV, client courses, client-course transactions, or clients) over a date range. Confirmed: developer.phorest.com/reference/createcsvexportjob. requestBody: required: true content: application/json: schema: type: object required: [jobType] properties: jobType: type: string enum: - TRANSACTIONS_CSV - SUNDRIES_CSV - DATEV_CSV - CLIENT_COURSES_CSV - CLIENT_COURSE_TRANSACTIONS_CSV - CLIENT_CSV startFilter: { type: string, format: date } finishFilter: { type: string, format: date } filterExpression: { type: string } responses: '201': description: CSV export job created successfully. content: application/json: schema: { $ref: '#/components/schemas/CsvExportJob' } '400': { $ref: '#/components/responses/BadRequest' } '404': { $ref: '#/components/responses/NotFound' } '429': { $ref: '#/components/responses/RateLimited' } '500': { $ref: '#/components/responses/ServerError' } /{businessId}/branch/{branchId}/csvexportjob/{jobId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: jobId in: path required: true schema: { type: string } get: operationId: getCsvExportJob tags: [Reporting] summary: Retrieve a CSV export job description: >- Polls a CSV export job for status and, once complete, a download URL. Confirmed: developer.phorest.com/reference/getcsvexportjob. responses: '200': description: The requested CSV export job. content: application/json: schema: { $ref: '#/components/schemas/CsvExportJob' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/review: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getReviewList tags: [Reviews] summary: List reviews description: >- Lists client reviews for a branch, filterable by client, client name, staff name, or review date - used to syndicate reviews to external platforms. Confirmed: developer.phorest.com/reference/getreviewlist. parameters: - name: clientId in: query schema: { type: string } - name: clientName in: query schema: { type: string } - name: staffName in: query schema: { type: string } - name: reviewDate in: query schema: { type: string, format: date } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Reviews listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Review' } /{businessId}/branch/{branchId}/review/{reviewId}: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' - name: reviewId in: path required: true schema: { type: string } get: operationId: getReview tags: [Reviews] summary: Retrieve a review description: >- Retrieves a single review by ID. Confirmed to exist: developer.phorest.com/reference/getreview; sub-path modeled by convention. responses: '200': description: The requested review. content: application/json: schema: { $ref: '#/components/schemas/Review' } '404': { $ref: '#/components/responses/NotFound' } /{businessId}/branch/{branchId}/leads: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getLeads tags: [Leads] summary: List marketing leads description: >- Lists marketing leads for a branch, filterable by name, status, and contactability. Confirmed: developer.phorest.com/reference/getleads. parameters: - name: name in: query schema: { type: string } - name: status in: query schema: type: array items: { type: string } - name: contactableByEmail in: query schema: { type: boolean } - name: contactableByMobile in: query schema: { type: boolean } - name: fetchMessageHistory in: query schema: { type: boolean } - $ref: '#/components/parameters/Size' - $ref: '#/components/parameters/Page' responses: '200': description: Leads listed successfully. content: application/json: schema: type: array items: { $ref: '#/components/schemas/Lead' } /{businessId}/branch/{branchId}/leads/stats: parameters: - $ref: '#/components/parameters/BusinessId' - $ref: '#/components/parameters/BranchId' get: operationId: getLeadsStats tags: [Leads] summary: Retrieve lead statistics description: >- Retrieves aggregate lead statistics for a branch. Confirmed to exist: developer.phorest.com/reference/getleadsstats; sub-path modeled by convention. responses: '200': description: Lead statistics. content: application/json: schema: type: object additionalProperties: true /{businessId}/lead: parameters: - $ref: '#/components/parameters/BusinessId' post: operationId: createLead tags: [Leads] summary: Create a lead description: >- Creates a marketing lead (e.g. from a website contact form). Confirmed to exist: developer.phorest.com/reference/createlead; sub-path modeled by convention. requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/Lead' } responses: '201': description: Lead created successfully. content: application/json: schema: { $ref: '#/components/schemas/Lead' } components: securitySchemes: basicAuth: type: http scheme: basic description: >- Username is `global/{email}`, using the email address Phorest associated with the granted API access. Password is the API password issued by Phorest support. parameters: BusinessId: name: businessId in: path required: true description: The Phorest business (salon group) identifier. schema: { type: string } BranchId: name: branchId in: path required: true description: The Phorest branch (location) identifier. schema: { type: string } ClientId: name: clientId in: path required: true schema: { type: string } AppointmentId: name: appointmentId in: path required: true schema: { type: string } Size: name: size in: query description: Records per page. Max 100, defaults to 20. schema: { type: integer, default: 20, maximum: 100 } Page: name: page in: query description: Zero-indexed page number. Defaults to 0. schema: { type: integer, default: 0, minimum: 0 } responses: BadRequest: description: The request was invalid. NotFound: description: The specified business, branch, or resource does not exist. RateLimited: description: Request rate limit exceeded. Current limit set to 100 requests per second. ServerError: description: Internal server error. schemas: Client: allOf: - $ref: '#/components/schemas/ClientInput' - type: object properties: clientId: { type: string } version: { type: integer } creatingBranchId: { type: string, readOnly: true } createdAt: { type: string, format: date-time } updatedAt: { type: string, format: date-time } ClientInput: type: object required: [firstName, lastName] properties: firstName: { type: string } lastName: { type: string } email: { type: string, format: email } mobile: { type: string } address: { type: string } birthDate: { type: string, format: date } version: { type: integer, description: Required on update; omit on create. } ClientCategory: type: object properties: categoryId: { type: string } name: { type: string } archived: { type: boolean } Appointment: allOf: - $ref: '#/components/schemas/AppointmentInput' - type: object properties: appointmentId: { type: string } state: type: string enum: [ACTIVE, RESERVED, CANCELED, ARCHIVED] AppointmentInput: type: object properties: clientId: { type: string } staffId: { type: string } roomId: { type: string } machineId: { type: string } startTime: { type: string, format: date-time } endTime: { type: string, format: date-time } serviceId: { type: string } note: { type: string, maxLength: 50000 } AvailabilityRequest: type: object required: [startTime, endTime, clientServiceSelections] properties: clientId: { type: string } startTime: { type: string, format: date-time } endTime: { type: string, format: date-time } clientServiceSelections: type: array items: type: object properties: serviceId: { type: string } staffId: { type: string } rescheduleBookingId: { type: string } isOnlineAvailability: { type: boolean } AvailabilitySlot: type: object properties: startTime: { type: string, format: date-time } endTime: { type: string, format: date-time } staffId: { type: string } Booking: allOf: - $ref: '#/components/schemas/BookingInput' - type: object properties: bookingId: { type: string } BookingInput: type: object required: [clientId] properties: bookingStatus: type: string enum: [ACTIVE, RESERVED, CANCELED] clientId: { type: string } note: { type: string, maxLength: 50000 } clientAppointmentSchedules: type: array items: type: object properties: serviceId: { type: string } staffId: { type: string } startTime: { type: string, format: date-time } Staff: type: object properties: staffId: { type: string } firstName: { type: string } lastName: { type: string } email: { type: string, format: email } archived: { type: boolean } roles: type: array items: { type: string } StaffWorkTimeEntry: type: object properties: staffId: { type: string } date: { type: string, format: date } startTime: { type: string, format: date-time } endTime: { type: string, format: date-time } StaffBreak: allOf: - $ref: '#/components/schemas/StaffBreakInput' - type: object properties: breakId: { type: string } StaffBreakInput: type: object properties: startTime: { type: string, format: date-time } endTime: { type: string, format: date-time } description: { type: string } Service: type: object properties: serviceId: { type: string } name: { type: string } categoryId: { type: string } price: { type: number } durationMinutes: { type: integer } archived: { type: boolean } ServiceCategory: type: object properties: categoryId: { type: string } name: { type: string } ServicePackage: type: object properties: packageId: { type: string } name: { type: string } categoryId: { type: string } price: { type: number } serviceIds: type: array items: { type: string } ServiceSpecialOffer: type: object properties: offerId: { type: string } serviceId: { type: string } discountedPrice: { type: number } startDate: { type: string, format: date } endDate: { type: string, format: date } Course: type: object properties: courseId: { type: string } name: { type: string } totalSessions: { type: integer } archived: { type: boolean } ClientCourse: type: object properties: clientCourseId: { type: string } courseId: { type: string } clientId: { type: string } remainingSessions: { type: integer } Branch: type: object properties: branchId: { type: string } name: { type: string } address: { type: string } phone: { type: string } timezone: { type: string } BranchWorkTimeTable: type: object properties: branchId: { type: string } openingHours: type: array items: type: object properties: dayOfWeek: { type: string } startTime: { type: string } endTime: { type: string } Room: type: object properties: roomId: { type: string } name: { type: string } archived: { type: boolean } Machine: type: object properties: machineId: { type: string } name: { type: string } archived: { type: boolean } TaxRate: type: object properties: taxRateId: { type: string } name: { type: string } rate: { type: number } Product: type: object properties: productId: { type: string } name: { type: string } barcode: { type: string } productType: { type: string } price: { type: number } stockLevel: { type: integer } archived: { type: boolean } InventoryTransaction: type: object properties: transactionId: { type: string } productId: { type: string } quantityChange: { type: number } reason: { type: string } createdAt: { type: string, format: date-time } PurchaseInput: type: object required: [number, clientId, items] properties: number: type: string description: Must be unique across all purchases for the branch. clientId: { type: string } payments: type: array items: type: object properties: type: { type: string } amount: { type: number } items: type: array minItems: 1 items: type: object properties: itemType: type: string enum: [APPOINTMENT, PRODUCT, COURSE, VOUCHER] itemId: { type: string } quantity: { type: integer } price: { type: number } Purchase: allOf: - $ref: '#/components/schemas/PurchaseInput' - type: object properties: purchaseId: { type: string } transactionId: type: string description: Unique per branch only; combine with branchId to disambiguate across branches. Not present in the SQS purchase event. branchId: { type: string } TillBalance: type: object properties: tillId: { type: string } expectedCash: { type: number } countedCash: { type: number } integratedPaymentBalances: type: array items: type: object additionalProperties: true SaleFee: type: object properties: saleFeeId: { type: string } name: { type: string } amount: { type: number } archived: { type: boolean } Voucher: allOf: - $ref: '#/components/schemas/VoucherInput' - type: object properties: voucherId: { type: string } remainingBalance: { type: number } VoucherInput: type: object required: [issueDate, expiryDate, creatingBranchId, originalBalance] properties: serialNumber: { type: string } issueDate: { type: string, format: date-time } expiryDate: { type: string, format: date-time } clientId: { type: string } creatingBranchId: { type: string } originalBalance: { type: number } notes: { type: string } CsvExportJob: type: object properties: jobId: { type: string } jobType: type: string enum: - TRANSACTIONS_CSV - SUNDRIES_CSV - DATEV_CSV - CLIENT_COURSES_CSV - CLIENT_COURSE_TRANSACTIONS_CSV - CLIENT_CSV status: type: string enum: [PENDING, IN_PROGRESS, COMPLETE, FAILED] downloadUrl: { type: string, format: uri } Review: type: object properties: reviewId: { type: string } clientId: { type: string } staffId: { type: string } rating: { type: integer } comment: { type: string } reviewDate: { type: string, format: date } Lead: type: object properties: leadId: { type: string } name: { type: string } status: { type: string } contactableByEmail: { type: boolean } contactableByMobile: { type: boolean } email: { type: string, format: email } mobile: { type: string }