Below are the recommended steps to successfully create or update a Wix Bookings service (or several at once) on Wix, with real-world troubleshooting and fixes for common API issues.
13d21c63-b5ec-5912-8397-c3a5ddb27a97)Note: If you receive errors from Bookings APIs, the Wix Bookings app may not be installed on the site. Use List Installed Apps to verify, and Install Wix Apps to install it if missing.
A Bookings service defines a time based offering and includes the following considerations:
APPOINTMENT - Appointments allow customers to book services at their preferred time during the business hours. For example, a hair salon might offer different appointment-based hair cutting and styling services. Appointments appear in the booking calendar once they're booked by a customer. Not-yet-booked times during the business hours are displayed as available slots to potential customers while booking. The availability of the service is based on the availability of the staff member providing itCLASS - A class is a single event or a series of recurring events that multiple customers can book. For example, a yoga studio might offer a twice-weekly vinyasa flow class. Classes may have a set end date or continue indefinitely. If a class includes more than a single event, customers can sign up for 1, several, or all of the events. Upon creation, classes are listed immediately in the booking calendar.COURSE - A course starts and ends on pre-defined dates with a limited number of events that multiple customers can book. For example, a yoga studio might offer a teacher training course with 5 events. In contrast to classes, customers must book the entire course. Upon creation, courses are displayed immediately in the booking calendar.assignWorkingHoursSchedule which allows the staff member to have its own availability. The property staffMember.usesDefaultWorkingHours defines whether the default hours (business hours) are used.Events (REST) defined on a schedule.service.staffMemberIds which is mapped to staffMember.resourceId). In order to fetch the staff schedule you should retrieve the staff member with RESOURCE_DETAILS fieldmask and read the schedule id from the staffMember.resource.eventsSchedule.id - This is needed if you wish to define the staff member's availability as part of the processservice.schedule)staffMemberIds, ensure you are using the staff member's resourceId, not their primary staff member id.service.media.mainMedia - presented in the services list, service.media.coverMedia - presented in the service page and service.media.items - array of images presented as a gallery in the service page for site visitors.item.id -> service.media.mainMedia.id) there is no need to set the entire object.Choose based on these documented behaviors:
When unsure, refer to About Service Types.
APPOINTMENT Services:
staffMemberIds array with staff member resourceId valuesCLASS and COURSE Services:
staffMemberIds has no effect on service creationservice.schedule), not staff schedulesThis is a critical API limitation that affects service planning and staff resource management.
CLASS or COURSE I MUST read the full articles service's schedule and events mentioned beforeAPPOINTMENT I MUST read the relevant full article about staff members (REST) in order to determine whether I should create a new staff member (or members)service.payment.rateType as "NO_FEE" and service.payment.options.inPerson as true (at least one payment option must be true)service.payment.fixed.price.value (must be above 0) as well as service.payment.fixed.price.currency| rateType | options.online | options.inPerson | Valid? |
|---|---|---|---|
| FIXED | true | false | ✓ |
| FIXED | false | true | ✓ |
| FIXED | true | true | ✓ |
| VARIED | true | false | ✓ |
| VARIED | false | true | ✓ |
| NO_FEE | false | true | ✓ |
| NO_FEE | true | false | ✗ (online not allowed for NO_FEE) |
| Any | false | false | ✗ (at least one must be true) |
IMPORTANT: Services without categories may not appear in category-based UI filters, which are commonly used in booking interfaces.
Service Category Considerations:
category.id, hiding uncategorized servicesCategory Management Steps:
category.id in the service objectCommon Category Filter Patterns:
This filter will only show services with assigned categories, making uncategorized services invisible to users.
You can retrieve a list of existing booking services using the Query Services endpoint. This allows you to filter, sort, and page through up to 100 services at a time, making it easy to find and manage your current offerings.
queryCategories API (REST) to identify available categoriescreateCategory API (REST) if no suitable category existsQuery Categories:
Create Category (if none exist):
IMPORTANT: For APPOINTMENT services, staffMemberIds is required. The API will return a 400 error without it. You must query staff members first to obtain a valid resourceId.
resourceId valuescreateStaffMember API (REST) and keep the response staffMember.id and resourceIdgetStaffMember API (REST) to get resource.eventsSchedule.idQuery Staff Members (to get resourceId):
Use the resourceId from the response (not id) in staffMemberIds when creating APPOINTMENT services.
Staff Selection Strategy:
default: true → use itService Type Requirements:
staffMemberIds is required - API will fail without itstaffMemberIds is ignored; use service.schedule insteadBased on the information gathered above, use the relevant API based on the desired outcome.
bulkCreateServices endpoint (REST)updateService endpoint (REST)bulkUpdateServices (REST)bulkUpdateServicesByFilter (REST)getService endpoint (REST)Create Service Example (paid APPOINTMENT, 60 minutes):
Note: Currency may default to the site's business currency regardless of what you specify. Verify the response if currency is critical.
Create Service Example (free APPOINTMENT, 60 minutes):
Create Service Example (CLASS with capacity):
Note: CLASS services do not use staffMemberIds or sessionDurations. After creation, you must create events via bulkCreateEvents using the returned service.schedule.id to define when the class occurs.
After creation, use the service.schedule.id from the response to create class events with bulkCreateEvents (see Step 3).
Required Fields:
name - Service nametype - APPOINTMENT, CLASS, or COURSEonlineBooking: { enabled: true } - Required for all servicesstaffMemberIds - Required for APPOINTMENT only (use resourceId values); ignored for CLASS/COURSEschedule.availabilityConstraints.sessionDurations - Duration in minutes (APPOINTMENT only)defaultCapacity - Required for CLASS/COURSE (max participants per session)payment.options - At least one of online or inPerson must be true (required for all services, including free; see validation table above)Service Type Specific Considerations:
staffMemberIds with staff resourceId valuesstaffMemberIds; configure service.schedule insteadUpdate Service Example (PATCH):
Note: Updates require the current revision value (from a GET response) placed inside the service object, not at the top level.
Once the service and staff member are available, you can define when the service is available:
3a. Determine the schedule to use based on the service type:
assignWorkingHoursSchedule (POST https://www.wixapis.com/bookings/v1/staff-members/<STAFF_MEMBER_ID>/assign-working-hours-schedule) (REST). Use the resource.eventsSchedule.id as the scheduleId.service.schedule.id from the service created/updated in Step 2.3b. Create events using bulkCreateEvents (POST https://www.wixapis.com/calendar/v3/bulk/events/create) (REST) or update existing ones with bulkUpdateEvents (POST https://www.wixapis.com/calendar/v3/bulk/events/update) (REST).
Event requirements:
event.resources array must include at least one resource (a staff member/room/etc.) using the resourceId. CLASS and COURSE events will fail with a 400 error if no resources are provided.event.scheduleId — use the staff member's events schedule ID for APPOINTMENT availability, or service.schedule.id for CLASS/COURSE.event.type — set to WORKING_HOURS for staff availability, CLASS for class sessions, or COURSE for course sessions.APPOINTMENT Service Creation Fails (staffMemberIds required):
"service of type appointment requires at least one staff member id"resourceId, then include it in staffMemberIdsService Creation Fails (payment.options required):
INVALID_PAYMENT_OPTIONS - "It is mandatory to specify either payment.options.online or payment.options.inPerson as true"true"options": { "online": true, "inPerson": false } (or inPerson: true for free services) to the payment objectFree Service Fails with online=true:
INVALID_PAYMENT_OPTIONS - "Specifying payment.paymentOptions.online as true is applicable only to payments of types FIXED or VARIED"payment.options.online: true is only valid for paid services (FIXED or VARIED)"options": { "online": false, "inPerson": true }Services Not Appearing in UI Filters:
category.id existence or specific category valuesStaff Assignment Not Working for CLASS/COURSE Services:
staffMemberIds in CLASS or COURSE services appears to be ignoredApp Not Installed Errors:
Resource ID vs Staff ID Confusion:
staffMemberIds arraystaffMember.resourceId, not staffMember.idRESOURCE_DETAILS fieldMask to get correct IDsService Schedule vs Staff Schedule Confusion:
staffMember.resource.eventsSchedule.id)service.schedule.id)Update Service Fails with revision error:
revision must not be empty or service.revision is requiredrevision placed at top level of request body instead of inside service object{ "service": { "revision": "...", ...fields } } - get revision value from GET response firstonlineBooking Field: The onlineBooking object (e.g., {"enabled": true}) is a required field when creating services, even if not explicitly highlighted as mandatory in the high-level overview. This is a schema-level requirement.event.type as WORKING_HOURS (APPOINTMENT) I MUST call assignWorkingHoursSchedule BEFORE CREATING THE EVENTS so that the staff member is no longer linked to the business working hoursevent.type as CLASS or COURSE I MUST use the service schedule id, so the service has to exist (created/updated) before setting the availability of it