@wix/agent-skills 1.31.0 → 1.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +7 -8
  3. package/skills/wix-app/references/DASHBOARD_PAGE.md +1 -1
  4. package/skills/wix-app/references/STORES_VERSIONING.md +1 -1
  5. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +11 -50
  6. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +14 -10
  7. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +5 -8
  8. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +5 -4
  9. package/skills/wix-headless-kit/SKILL.md +31 -14
  10. package/skills/wix-headless-kit/guides/api-run.md +116 -31
  11. package/skills/wix-headless-kit/guides/existing-site.md +9 -2
  12. package/skills/wix-headless-kit/guides/reference-mode.md +9 -1
  13. package/skills/wix-headless-kit/install/AGENTS.md +10 -7
  14. package/skills/wix-headless-kit/install/attach.mjs +35 -30
  15. package/skills/wix-headless-kit/install/background.mjs +32 -0
  16. package/skills/wix-headless-kit/install/bootstrap.mjs +28 -11
  17. package/skills/wix-headless-kit/install/check.mjs +2 -2
  18. package/skills/wix-headless-kit/install/context.mjs +62 -8
  19. package/skills/wix-headless-kit/install/deploy.mjs +36 -11
  20. package/skills/wix-headless-kit/install/env-ignore.mjs +16 -0
  21. package/skills/wix-headless-kit/install/install.mjs +95 -0
  22. package/skills/wix-headless-kit/install/pins.json +1 -1
  23. package/skills/wix-headless-kit/install/proc.mjs +46 -0
  24. package/skills/wix-headless-kit/install/setup.mjs +18 -27
  25. package/skills/wix-headless-kit/install/templates.mjs +4 -3
  26. package/skills/wix-headless-templates/blog/app/components/blog/RichContent.tsx +3 -2
  27. package/skills/wix-headless-templates/blog/project/package-lock.json +1287 -1299
  28. package/skills/wix-headless-templates/blog/project/package.json +1 -1
  29. package/skills/wix-headless-templates/blog/project/src/components/blog/RichContent.tsx +3 -2
  30. package/skills/wix-headless-templates/blog/rest/authors.ts +5 -5
  31. package/skills/wix-headless-templates/blog/rest/comments.ts +4 -4
  32. package/skills/wix-headless-templates/blog/rest/post-likes.ts +3 -3
  33. package/skills/wix-headless-templates/blog/rest/posts.ts +4 -4
  34. package/skills/wix-headless-templates/blog/rest/taxonomy.ts +5 -5
  35. package/skills/wix-headless-templates/blog/seed/SEED.md +1 -1
  36. package/skills/wix-headless-templates/blog/seed/seed-blog.mjs +4 -3
  37. package/skills/wix-headless-templates/bookings/rest/booking.ts +4 -4
  38. package/skills/wix-headless-templates/bookings/rest/services.ts +4 -4
  39. package/skills/wix-headless-templates/bookings/seed/SEED.md +1 -1
  40. package/skills/wix-headless-templates/bookings/seed/seed-bookings.mjs +4 -2
  41. package/skills/wix-headless-templates/cms/rest/collections.ts +3 -3
  42. package/skills/wix-headless-templates/cms/rest/items.ts +4 -4
  43. package/skills/wix-headless-templates/cms/seed/seed-cms.mjs +2 -1
  44. package/skills/wix-headless-templates/donations/rest/campaigns.ts +4 -4
  45. package/skills/wix-headless-templates/donations/rest/donate.ts +3 -3
  46. package/skills/wix-headless-templates/donations/seed/SEED.md +1 -1
  47. package/skills/wix-headless-templates/donations/seed/seed-donations.mjs +5 -3
  48. package/skills/wix-headless-templates/events/rest/events.ts +4 -4
  49. package/skills/wix-headless-templates/events/rest/orders.ts +4 -4
  50. package/skills/wix-headless-templates/events/rest/registration.ts +4 -4
  51. package/skills/wix-headless-templates/events/seed/SEED.md +1 -1
  52. package/skills/wix-headless-templates/events/seed/seed-events.mjs +5 -3
  53. package/skills/wix-headless-templates/faq/rest/faq.ts +4 -4
  54. package/skills/wix-headless-templates/faq/seed/seed-faq.mjs +2 -1
  55. package/skills/wix-headless-templates/forms/rest/forms.ts +4 -4
  56. package/skills/wix-headless-templates/forms/rest/submissions.ts +4 -4
  57. package/skills/wix-headless-templates/forms/seed/seed-forms.mjs +2 -1
  58. package/skills/wix-headless-templates/members/rest/auth.ts +3 -3
  59. package/skills/wix-headless-templates/members/rest/members.ts +4 -4
  60. package/skills/wix-headless-templates/members/seed/seed-members.mjs +2 -1
  61. package/skills/wix-headless-templates/portfolio/rest/portfolio.ts +4 -4
  62. package/skills/wix-headless-templates/portfolio/seed/SEED.md +4 -2
  63. package/skills/wix-headless-templates/portfolio/seed/seed-portfolio.mjs +8 -7
  64. package/skills/wix-headless-templates/pricing-plans/rest/plan-access.ts +3 -3
  65. package/skills/wix-headless-templates/pricing-plans/rest/plans.ts +4 -4
  66. package/skills/wix-headless-templates/pricing-plans/rest/purchase.ts +3 -3
  67. package/skills/wix-headless-templates/pricing-plans/seed/seed-pricing-plans.mjs +2 -1
  68. package/skills/wix-headless-templates/rentals/rest/rentals.ts +4 -4
  69. package/skills/wix-headless-templates/rentals/seed/SEED.md +1 -1
  70. package/skills/wix-headless-templates/rentals/seed/seed-rentals.mjs +4 -2
  71. package/skills/wix-headless-templates/restaurants/rest/menu.ts +4 -4
  72. package/skills/wix-headless-templates/restaurants/rest/ordering.ts +5 -5
  73. package/skills/wix-headless-templates/restaurants/rest/reservations.ts +4 -4
  74. package/skills/wix-headless-templates/restaurants/seed/SEED.md +1 -1
  75. package/skills/wix-headless-templates/restaurants/seed/seed-restaurants.mjs +6 -4
  76. package/skills/wix-headless-templates/shared/capabilities/site-search/rest/search.ts +4 -4
  77. package/skills/wix-headless-templates/shared/capabilities/site-search/seed/install.mjs +6 -4
  78. package/skills/wix-headless-templates/shared/seed/images.mjs +41 -5
  79. package/skills/wix-headless-templates/shared/seed/main.mjs +15 -0
  80. package/skills/wix-headless-templates/shared/seed/wix-cli.mjs +43 -11
  81. package/skills/wix-headless-templates/storefront/INSTRUCTIONS.md +1 -1
  82. package/skills/wix-headless-templates/storefront/rest/cart.ts +5 -5
  83. package/skills/wix-headless-templates/storefront/rest/catalog.ts +5 -5
  84. package/skills/wix-headless-templates/storefront/seed/SEED.md +44 -14
  85. package/skills/wix-headless-templates/storefront/seed/seed-store.mjs +23 -15
  86. package/skills/wix-manage/SKILL.md +28 -18
  87. package/skills/wix-manage/references/app-installation/install-wix-apps.md +5 -1
  88. package/skills/wix-manage/references/app-installation/list-installed-apps.md +19 -9
  89. package/skills/wix-manage/references/automations/activation-status.md +52 -0
  90. package/skills/wix-manage/references/automations/api-catalog.md +81 -0
  91. package/skills/wix-manage/references/automations/build-and-manage-automations.md +34 -0
  92. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +3 -0
  93. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +277 -363
  94. package/skills/wix-manage/references/bookings/external-calendar-integration.md +3 -0
  95. package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +3 -0
  96. package/skills/wix-manage/references/cms/cms-data-items-crud.md +11 -2
  97. package/skills/wix-manage/references/cms/cms-publishing-flow.md +63 -16
  98. package/skills/wix-manage/references/custom-apps/use-app-skills-and-app-tools.md +3 -1
  99. package/skills/wix-manage/references/forms/update-form.md +3 -0
  100. package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +3 -0
  101. package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +3 -0
  102. package/skills/wix-manage/references/sites/create-headless-site.md +7 -50
  103. package/skills/wix-manage/references/sites/manage-oauth-apps.md +4 -4
  104. package/skills/wix-manage/references/sites/read-site-context.md +4 -0
  105. package/skills/wix-manage/references/sites/send-feedback-to-wix.md +92 -0
  106. package/skills/wix-manage/references/sites/upload-static-site.md +298 -283
  107. package/skills/wix-manage/references/stores/add-store-pages-to-site.md +3 -0
  108. package/skills/wix-manage/references/stores/change-store-currency.md +3 -0
  109. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +3 -0
  110. package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +3 -0
  111. package/skills/wix-manage/references/stores/update-product-with-options.md +192 -22
  112. package/skills/wix-manage/references/bookings/create-appointment-service.md +0 -243
  113. package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +0 -31
  114. package/skills/wix-manage/references/bookings/create-class-service.md +0 -222
  115. package/skills/wix-manage/references/bookings/create-course-service.md +0 -251
@@ -1,465 +1,379 @@
1
1
  ---
2
2
  name: "Create and Update Booking Services"
3
- description: Full CRUD operations for Wix Bookings services using Services API. Covers service types (APPOINTMENT, CLASS, COURSE), pricing configuration, location setup, and schedule management.
3
+ description: "Creates and updates Wix Bookings services of every type — appointments, classes and courses — from a plain request such as 'a 60-minute consultation for $75', 'a yoga class for 12 people every Tuesday' or 'a 6-week photography course'. Covers choosing the service type, defaults for what the request leaves out, pricing (free, fixed, free-to-paid), staff, capacity, duration, categories, visibility, images, scheduling class and course sessions on the calendar, and changing existing services."
4
4
  ---
5
5
 
6
- # Technical Step-by-Step Instructions: Creating or Updating a Wix Bookings Service (Real-World, API-First)
6
+ # Create and Update Booking Services
7
7
 
8
- ## Description
8
+ One recipe for every Bookings service: pick the type, fill in what the user didn't say, create it, schedule its sessions when it's a class or a course, and report back. The second half covers changing a service that already exists.
9
9
 
10
- 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.
10
+ All service types are created with the same call (`POST https://www.wixapis.com/bookings/v2/bulk/services/create`); the type decides which fields the body carries and what has to happen after it.
11
+
12
+ Related recipes:
13
+ - A service booked by room or equipment instead of (or as well as) staff — "a massage in whichever treatment room is free" → [Multi-Resource Service Creation](multi-resource-service-creation.md). It creates the resource types and resources and gives the service body (`serviceResources`, and `primaryResourceType` for an appointment with no staff); this recipe's staff rules don't apply to such a service.
14
+ - Memberships, class packs or session bundles for a service → [Pricing Plans Bookings Integration](../pricing-plans/pricing-plans-bookings-integration.md).
15
+ - Adding staff, or giving a staff member custom working hours → [Bookings Staff Setup](bookings-staff-setup.md).
16
+ - Cancellation, booking-window or waitlist rules → [Booking Service Policy Setup](booking-service-policy-setup.md).
17
+
18
+ If a Bookings call fails because the Wix Bookings app isn't installed on the site, install it with [Install Wix Apps](../app-installation/install-wix-apps.md) (app ID `13d21c63-b5ec-5912-8397-c3a5ddb27a97`) and retry. Don't check for the app before the first call — the error says so when it's missing.
11
19
 
12
20
  ---
13
21
 
14
- ## Prerequisites
22
+ ## Part 1 — Create a service
15
23
 
16
- - **Wix Bookings app installed** (App ID: `13d21c63-b5ec-5912-8397-c3a5ddb27a97`)
24
+ ### Step 1: Pick the service type
17
25
 
18
- > **Note:** If you receive errors from Bookings APIs, the Wix Bookings app may not be installed on the site. Use [List Installed Apps](../app-installation/list-installed-apps.md) to verify, and [Install Wix Apps](../app-installation/install-wix-apps.md) to install it if missing.
26
+ | The user describes | Type | How customers book it |
27
+ |---|---|---|
28
+ | a consultation, appointment, meeting, 1-on-1, treatment, haircut, lesson at a time the customer picks | `APPOINTMENT` | The customer picks a free slot during the staff member's working hours. One customer per booking. |
29
+ | a class, group session, drop-in, "yoga every Tuesday", bootcamp class | `CLASS` | The business sets the session times; many customers book each session, and a customer can book one, some or all sessions. |
30
+ | a course, workshop series, program, "6-week course", "8 sessions", teacher training | `COURSE` | The business sets a fixed series with a start and an end; customers book the whole course, never a single session. |
19
31
 
20
- ## Overview
32
+ When the wording fits none of these, create an `APPOINTMENT`. When it's ambiguous between a class and a course, the deciding question is whether customers can join a single session (class) or must sign up for the whole series (course). See [About Service Types](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types) for the full comparison.
21
33
 
22
- A Bookings service defines a time based offering and includes the following considerations:
34
+ ### Step 2: Fill in what the user didn't say
23
35
 
24
- - type - for detailed information about service type - refer to the [article](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types)
25
- - `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 it
26
- - `CLASS` - 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.
27
- - `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.
28
- - Staff Member - a resource required in order to provide a service. [REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/create-staff-member) A staff member availability is defined by the schedule associated with the staff member, by default it is the main business schedule and cannot be modified by schedule APIs, but a staff member can have its own schedule by calling `assignWorkingHoursSchedule` which allows the staff member to have its own availability. The property `staffMember.usesDefaultWorkingHours` defines whether the default hours (business hours) are used.
29
- - Schedule (availability) - availability is defined by `Events` ([REST](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/introduction)) defined on a schedule.
30
- - The schedule which defines the service availability is based on the service type.
31
- - For appointment service, it is based on the schedule of staff members which provides it (`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 process
32
- - For classes and courses it is based on the schedule of the service itself (`service.schedule`)
33
- - When creating an APPOINTMENT service and specifying `staffMemberIds`, ensure you are using the staff member's resourceId, not their primary staff member id.
34
- - Service Images - the service may have several images - `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.
35
- - In order to add a media (image) to a service, it should first be defined in Wix Media Manager - search existing ([REST](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/search-files)) or new ([REST](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/bulk-import-file))
36
- - Set only the image **id**, but nest it inside the media item's `image` object: `service.media.mainMedia.image.id` (likewise `service.media.coverMedia.image.id` and `service.media.items[].image.id`). The `id` is the binding field; `url` and dimensions are descriptive and need not be set. ⚠️ Setting the id directly on the media item (`service.media.mainMedia.id`, without the `image` wrapper) returns HTTP 200 but **silently drops** it — the image reads back empty (`image.id: ""`). Because it's a silent 200, a success status is not proof: always nest under `.image` and confirm with a re-query.
36
+ Use the user's values wherever they gave one. For the rest:
37
37
 
38
- ### Service Type Selection Guide
38
+ | Field | APPOINTMENT | CLASS | COURSE |
39
+ |---|---|---|---|
40
+ | `name` | the user's wording | the user's wording | the user's wording |
41
+ | `description` | 1–2 sentences you write | 1–2 sentences, say it's a group class | 1–2 sentences, say it's a multi-session course (mention the session count if given) |
42
+ | `defaultCapacity` | `1` (required, must be 1) | `10` (participants per session) | `10` (participants for the whole course) |
43
+ | Duration | 60 minutes, via `schedule.availabilityConstraints.sessionDurations` | each session's start and end — only from the user (Step 5), never a default | each session's start and end — only from the user (Step 5), never a default |
44
+ | Staff | one staff member, via `staffMemberIds` (required unless the service is booked by a resource — see Related recipes) | the instructor goes on the session events, not the service | the instructor goes on the session events, not the service |
45
+ | `onlineBooking` | `{ "enabled": true }` | `{ "enabled": true }` | `{ "enabled": true }` |
46
+ | `category` | an existing category that fits, or a new one (Step 3) | an existing category that fits, or a new one (Step 3) | an existing category that fits, or a new one (Step 3) |
39
47
 
40
- Choose based on these documented behaviors:
48
+ **Price.** Never invent one.
49
+ - The user gave a price → `rateType: "FIXED"` with that amount in `fixed.price.value`. For a class it's the price of one session; for a course it's the price of the whole course — don't divide it per session.
50
+ - The user said "free" → `rateType: "NO_FEE"`.
51
+ - The user gave no price → create the service free (`NO_FEE`), say so in the summary, and offer to set a price.
41
52
 
42
- - **APPOINTMENT**: Customer picks available time slot. Availability based on staff schedules. One customer (or dedicated group) per booking.
43
- - **CLASS**: Business sets recurring times. Multiple customers book same session. Customers can book 1, some, or all sessions in series.
44
- - **COURSE**: Business sets fixed series. Multiple customers book. Customers must book entire course (all sessions).
53
+ **Session schedule** (CLASS / COURSE). Never invent one — no default days, times or start date. A schedule is the user's to give: "Tuesdays 6–7pm" or "Wednesdays at 19:00 starting the 14th" is one; "a 6-week course", "8 sessions" or "a weekly class" gives only the length or the count, not the days and times. Without days and times, create the service, create no sessions, and ask for them (Step 5, Step 7). This holds when you're working on your own and can't wait for an answer, too: an instruction to proceed on reasonable assumptions covers the service's other fields, never its schedule — sessions you pick are a timetable the owner didn't choose, published to customers.
45
54
 
46
- When unsure, refer to [About Service Types](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types).
55
+ **Currency.** Send only `fixed.price.value`; leave `price.currency` out. The service always takes the site's payment currency — a currency you send is replaced with it (a `"JPY"` price on a USD site is stored as USD). Don't look up the site currency first; read it from the create response when you report the price.
47
56
 
48
- ### CRITICAL: Staff Assignment Behavior by Service Type
57
+ **Visibility.** Services are visible by default. When the user asks for a hidden service ("a hidden test course"), add `"hidden": true` to the create body.
49
58
 
50
- **APPOINTMENT Services:**
59
+ ### Step 3: Read what the site already has
51
60
 
52
- - **Staff assignment WORKS**: Can specify `staffMemberIds` array with staff member `resourceId` values
53
- - **Behavior**: Service availability based on assigned staff schedules
54
- - **Example**: Personal training session assigned to specific trainer
61
+ Run these reads before creating anything; they're independent, so run them together.
55
62
 
56
- **CLASS and COURSE Services:**
63
+ **Staff members** — required for an APPOINTMENT, and the instructor for CLASS or COURSE sessions. For a CLASS or COURSE whose schedule the user didn't give, skip this read: no sessions are created yet, so no instructor is needed.
57
64
 
58
- - **Staff assignment IGNORED**: Setting `staffMemberIds` has no effect on service creation
59
- - **Behavior**: Service uses its own schedule (`service.schedule`), not staff schedules
60
- - **Workaround**: Staff association must be handled separately through calendar events or other mechanisms
61
- - **Example**: Yoga class where any qualified instructor can teach
65
+ `POST https://www.wixapis.com/bookings/v1/staff-members/query`
62
66
 
63
- This is a critical API limitation that affects service planning and staff resource management.
67
+ ```json
68
+ { "query": {} }
69
+ ```
64
70
 
65
- ### IMPORTANT NOTES
71
+ Use each staff member's `resourceId` — not its `id` — everywhere this recipe asks for a staff ID. Pick the staff member the user named; otherwise the one with `default: true`; otherwise the first one. If the site has no staff members, create one with [Bookings Staff Setup](bookings-staff-setup.md) first.
66
72
 
67
- - I MUST read the full articles about [service types](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types), [service payments](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-payments), [service location](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-locations) in order to fully understand how to set the service properties
68
- - If the service type is `CLASS` or `COURSE` I MUST read the full articles service's _schedule_ and _events_ mentioned before
69
- - If the service type is `APPOINTMENT` I MUST read the relevant full article about staff members ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/introduction)) in order to determine whether I should create a new staff member (or members)
70
- - For free service I MUST set `service.payment.rateType` as `"NO_FEE"` and `service.payment.options.inPerson` as `true` (at least one payment option must be true)
71
- - For paid service I MUST set the `service.payment.fixed.price.value` (must be above 0) as well as `service.payment.fixed.price.currency`
72
- - When changing a free service to a paid service, I MUST update `service.payment.rateType` from `"NO_FEE"` to `"FIXED"` in the same request where I set `service.payment.fixed.price`; patching only `fixed.price` on a `NO_FEE` service fails validation.
73
+ **Categories:**
73
74
 
74
- ### Payment Options Validation Rules
75
+ `POST https://www.wixapis.com/bookings/v2/categories/query`
75
76
 
76
- | rateType | `options.online` | `options.inPerson` | Valid? |
77
- | -------- | ---------------- | ------------------ | --------------------------------- |
78
- | FIXED | true | false | ✓ |
79
- | FIXED | false | true | ✓ |
80
- | FIXED | true | true | ✓ |
81
- | VARIED | true | false | ✓ |
82
- | VARIED | false | true | ✓ |
83
- | NO_FEE | false | true | ✓ |
84
- | NO_FEE | true | false | ✗ (online not allowed for NO_FEE) |
85
- | Any | false | false | ✗ (at least one must be true) |
77
+ ```json
78
+ { "query": {} }
79
+ ```
86
80
 
87
- - Always Prioritize Reading Full API Method Documentation: this overview article provides a general workflow. However, it repeatedly stresses the importance of reading the full documentation for each specific REST method you intend to use. This is critical for understanding detailed requirements.
88
- - I should pay close attention to all required fields, data types, enum values, and specific ID types (e.g., resourceId vs. id) as defined in the detailed schema of each API endpoint. The overview article serves as a guide but doesn't replace the need to consult these specifics.
81
+ A service without a category isn't shown on the live site, and services aren't assigned one automatically, so every create body carries a `category.id`. Use the category the user named; otherwise an existing one that fits the service. A general one such as "Our Services" (a fresh Bookings install has it) fits anything, but a category meant for something else doesn't — a yoga class doesn't go under a template's "Styling". If no category fits, or the user named one that doesn't exist, create it — `POST https://www.wixapis.com/bookings/v2/categories` with `{ "category": { "name": "Yoga" } }` (the user's name for it, or a short name for the kind of service) — use the returned `category.id`, and mention the new category in the summary.
89
82
 
90
- ### Service Categories - CRITICAL for UI Visibility
83
+ **Existing services** (duplicate check):
91
84
 
92
- **IMPORTANT**: Services without categories may not appear in category-based UI filters, which are commonly used in booking interfaces.
85
+ `POST https://www.wixapis.com/bookings/v2/services/query`
93
86
 
94
- **Service Category Considerations:**
87
+ ```json
88
+ { "query": { "paging": { "limit": 100 } } }
89
+ ```
95
90
 
96
- - **Default Behavior**: Services created without explicit category assignment may not be visible in filtered views
97
- - **UI Impact**: Many booking interfaces filter services by `category.id`, hiding uncategorized services
98
- - **Best Practice**: Always assign services to appropriate categories during creation
91
+ A site with more than 100 services needs more pages: repeat with `"offset": 100`, `200`… inside `paging` until a page returns fewer than 100. If a service with the same or a very similar name exists, tell the user before creating another one.
99
92
 
100
- **Category Management Steps:**
93
+ ### Step 4: Create the service
101
94
 
102
- 1. **Query existing categories** using [Query Categories](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/query-categories) to see available options
103
- 2. **Create new category if needed** using [Create Category](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/create-category)
104
- 3. **Assign category during service creation** by including `category.id` in the service object
105
- 4. **Update existing services** using [Update Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/update-service) to add missing categories
95
+ `POST https://www.wixapis.com/bookings/v2/bulk/services/create` — one call creates up to 100 services. Always send `"returnEntity": true`: without it the response carries only `results[i].itemMetadata.id`, with no `schedule.id` to schedule sessions on.
106
96
 
107
- **Common Category Filter Patterns:**
97
+ **APPOINTMENT** (60-minute paid consultation):
108
98
 
109
99
  ```json
110
100
  {
111
- "filter": {
112
- "category.id": {
113
- "$exists": true
114
- }
115
- }
101
+ "returnEntity": true,
102
+ "services": [{
103
+ "name": "Strategy Consultation",
104
+ "description": "A one-on-one session to map out your next quarter.",
105
+ "type": "APPOINTMENT",
106
+ "defaultCapacity": 1,
107
+ "onlineBooking": { "enabled": true },
108
+ "staffMemberIds": ["<STAFF_RESOURCE_ID>"],
109
+ "schedule": { "availabilityConstraints": { "sessionDurations": [60] } },
110
+ "payment": {
111
+ "rateType": "FIXED",
112
+ "options": { "online": true, "inPerson": false },
113
+ "fixed": { "price": { "value": "75" } }
114
+ },
115
+ "category": { "id": "<CATEGORY_ID>" }
116
+ }]
116
117
  }
117
118
  ```
118
119
 
119
- This filter will only show services with assigned categories, making uncategorized services invisible to users.
120
-
121
- ### Querying Existing Services
120
+ **CLASS or COURSE** (paid yoga class for 12 — for a course, change `type` to `"COURSE"`):
122
121
 
123
- You can retrieve a list of existing booking services using the [Query Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/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.
122
+ ```json
123
+ {
124
+ "returnEntity": true,
125
+ "services": [{
126
+ "name": "Vinyasa Yoga",
127
+ "description": "A flowing group yoga class for all levels.",
128
+ "type": "CLASS",
129
+ "defaultCapacity": 12,
130
+ "onlineBooking": { "enabled": true },
131
+ "payment": {
132
+ "rateType": "FIXED",
133
+ "options": { "online": true, "inPerson": false },
134
+ "fixed": { "price": { "value": "25" } }
135
+ },
136
+ "category": { "id": "<CATEGORY_ID>" }
137
+ }]
138
+ }
139
+ ```
124
140
 
125
- ---
141
+ For a CLASS or COURSE, don't send `staffMemberIds` (it's read-only for these types — the API fills it from the staff on the service's recurring sessions, so staff on single, non-recurring sessions don't appear there; query the calendar events for the full list) or `sessionDurations`, and don't put sessions anywhere in this body (`course.sessions`, `CourseSession` and the like do not create sessions).
126
142
 
127
- ## Steps
143
+ **Free service** — replace `payment` with:
128
144
 
129
- ### 0. Query and Setup Categories (CRITICAL FIRST STEP)
145
+ ```json
146
+ "payment": { "rateType": "NO_FEE", "options": { "online": false, "inPerson": true } }
147
+ ```
130
148
 
131
- 1. **Query existing categories** using `queryCategories` API ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/query-categories)) to identify available categories
132
- 2. **Create category if needed** using `createCategory` API ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/create-category)) if no suitable category exists
133
- 3. **Record category ID** for use in service creation - this prevents services from being hidden in UI filters
149
+ **Payment options** — at least one of `options.online` / `options.inPerson` must be `true`, even for a free service, and `online` is allowed only for paid rate types:
134
150
 
135
- **Query Categories:**
151
+ | `rateType` | `online` | `inPerson` | Valid? |
152
+ |---|---|---|---|
153
+ | `FIXED` | true | false | ✓ |
154
+ | `FIXED` | false | true | ✓ |
155
+ | `FIXED` | true | true | ✓ |
156
+ | `NO_FEE` | false | true | ✓ |
157
+ | `NO_FEE` | true | false | ✗ online needs FIXED or VARIED |
158
+ | any | false | false | ✗ one must be true |
136
159
 
137
- ```bash
138
- curl -X POST 'https://www.wixapis.com/bookings/v2/categories/query' \
139
- -H 'Authorization: <AUTH>' \
140
- -H 'Content-Type: application/json' \
141
- -d '{ "query": {} }'
142
- ```
160
+ Price-by-variant (`VARIED`), custom-text (`CUSTOM`), deposits and pricing plans are described in [About Service Payments](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-payments).
143
161
 
144
- **Create Category (if none exist):**
162
+ **Read the response.** A `200` can still carry a failed item, so check before reporting success:
145
163
 
146
- ```bash
147
- curl -X POST 'https://www.wixapis.com/bookings/v2/categories' \
148
- -H 'Authorization: <AUTH>' \
149
- -H 'Content-Type: application/json' \
150
- -d '{ "category": { "name": "General" } }'
164
+ ```json
165
+ {
166
+ "results": [{
167
+ "itemMetadata": { "id": "<SERVICE_ID>", "originalIndex": 0, "success": true },
168
+ "item": {
169
+ "id": "<SERVICE_ID>",
170
+ "type": "CLASS",
171
+ "payment": { "rateType": "FIXED", "fixed": { "price": { "value": "25", "currency": "USD" } } },
172
+ "schedule": { "id": "<SERVICE_SCHEDULE_ID>" },
173
+ "revision": "1"
174
+ }
175
+ }],
176
+ "bulkActionMetadata": { "totalSuccesses": 1, "totalFailures": 0, "undetailedFailures": 0 }
177
+ }
151
178
  ```
152
179
 
153
- ### 1. Define staff member to use (REQUIRED for APPOINTMENT)
180
+ - The service is directly under `results[i].item` — there is no `item.service`. Match items to your request by `itemMetadata.originalIndex`.
181
+ - `itemMetadata.success: false` comes with `itemMetadata.error` (code and description). Fix and resend only the failed services.
182
+ - Keep `item.id` (the service ID) and, for a CLASS or COURSE, `item.schedule.id` for Step 5.
154
183
 
155
- > **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`.
184
+ **Optional fields:**
185
+ - **Images** — the file must already be in the Wix Media Manager ([Search Files](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/search-files), or [Bulk Import File](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/bulk-import-file) for a URL). Set only its id, nested under `image`: `"media": { "mainMedia": { "image": { "id": "<FILE_ID>" } } }` (`mainMedia` shows in the services list, `coverMedia` on the service page, `items[]` is the page gallery). An id set directly on the media item (`mainMedia.id`) returns `200` but is silently dropped — read the service back to confirm the image stuck.
186
+ - **Locations** — `"locations": [{ "type": "BUSINESS", "business": { "id": "<LOCATION_ID>" } }]` for a business location, `[{ "type": "CUSTOMER" }]` for an appointment at the customer's place (appointments only), or `[{ "type": "CUSTOM", "custom": { "address": { … } } }]`. All of a course's sessions take place at the same location. To change the locations of an existing service, use [Set Service Locations](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/set-service-locations), not Update Service. Details: [About Service Locations](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-locations).
156
187
 
157
- 1. **Query existing staff members** to get their `resourceId` values
158
- 2. For new staff, create using `createStaffMember` API ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/create-staff-member)) and keep the response `staffMember.id` and `resourceId`
159
- 3. If you wish to update working hours, call `getStaffMember` API ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/get-staff-member)) to get `resource.eventsSchedule.id`
188
+ ### Step 5: Schedule the sessions (CLASS and COURSE)
160
189
 
161
- **Query Staff Members (to get resourceId):**
190
+ A CLASS or COURSE has no sessions when it's created, so customers can't book it, and a course with no future sessions shows as ended on its service page. Sessions are Calendar events on the service's own schedule (`item.schedule.id` from Step 4).
162
191
 
163
- ```bash
164
- curl -X POST 'https://www.wixapis.com/bookings/v1/staff-members/query' \
165
- -H 'Authorization: <AUTH>' \
166
- -H 'Content-Type: application/json' \
167
- -d '{
168
- "query": {},
169
- "fields": ["RESOURCE_DETAILS"]
170
- }'
171
- ```
192
+ - **The user gave days and times** ("Tuesdays at 6pm", "8 Wednesday evenings from the 14th") → create the sessions now.
193
+ - **They didn't** → create only the service, ask for the session days and times, and tell the user plainly that the service can't be booked until sessions exist. Don't make up a schedule — not even when you're told to proceed without asking; in that case finish with the service alone and name exactly what's missing.
172
194
 
173
- Use the `resourceId` from the response (not `id`) in `staffMemberIds` when creating APPOINTMENT services.
174
-
175
- **Staff Selection Strategy:**
176
-
177
- - If a staff member has `default: true` → use it
178
- - If only one staff member exists → use it
179
- - If multiple exist → pick the first or most appropriate
180
- - If none exist → create one using the [Staff Setup recipe](bookings-staff-setup.md)
181
-
182
- **Service Type Requirements:**
183
-
184
- - **APPOINTMENT**: `staffMemberIds` is **required** - API will fail without it
185
- - **CLASS/COURSE**: `staffMemberIds` is ignored; use `service.schedule` instead
186
-
187
- ### 2. Creating or Updating a service
188
-
189
- Based on the information gathered above, use the relevant API based on the desired outcome.
190
-
191
- - **Create services**: `bulkCreateServices` endpoint ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-create-services))
192
- - **Update single service**: `updateService` endpoint ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/update-service))
193
- - **Update services (bulk)**: `bulkUpdateServices` ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services))
194
- - **Update by filter**: `bulkUpdateServicesByFilter` ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services-by-filter))
195
- - **Get single service**: `getService` endpoint ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/get-service))
196
-
197
- **Create Service Example (paid APPOINTMENT, 60 minutes):**
198
-
199
- ```bash
200
- curl -X POST 'https://www.wixapis.com/bookings/v2/bulk/services/create' \
201
- -H 'Authorization: <AUTH>' \
202
- -H 'Content-Type: application/json' \
203
- -d '{
204
- "returnEntity": true,
205
- "services": [{
206
- "name": "Consultation",
207
- "type": "APPOINTMENT",
208
- "onlineBooking": { "enabled": true },
209
- "staffMemberIds": ["<RESOURCE_ID_FROM_STEP_1>"],
210
- "schedule": {
211
- "availabilityConstraints": {
212
- "sessionDurations": [60]
213
- }
214
- },
215
- "payment": {
216
- "rateType": "FIXED",
217
- "options": { "online": true, "inPerson": false },
218
- "fixed": {
219
- "price": { "value": "50", "currency": "USD" }
220
- }
221
- },
222
- "category": {
223
- "id": "<CATEGORY_ID_FROM_STEP_0>"
224
- }
225
- }]
226
- }'
227
- ```
195
+ Create the sessions with `POST https://www.wixapis.com/calendar/v3/bulk/events/create` (up to 50 events per call). The instructor in each event's `resources` is a staff `resourceId` from Step 3 — if you skipped that read because the schedule came later, run it now.
228
196
 
229
- > **Note:** Currency may default to the site's business currency regardless of what you specify. Verify the response if currency is critical.
230
-
231
- **Create Service Example (free APPOINTMENT, 60 minutes):**
232
-
233
- ```bash
234
- curl -X POST 'https://www.wixapis.com/bookings/v2/bulk/services/create' \
235
- -H 'Authorization: <AUTH>' \
236
- -H 'Content-Type: application/json' \
237
- -d '{
238
- "returnEntity": true,
239
- "services": [{
240
- "name": "Free Consultation",
241
- "type": "APPOINTMENT",
242
- "onlineBooking": { "enabled": true },
243
- "staffMemberIds": ["<RESOURCE_ID_FROM_STEP_1>"],
244
- "schedule": {
245
- "availabilityConstraints": {
246
- "sessionDurations": [60]
247
- }
248
- },
249
- "payment": {
250
- "rateType": "NO_FEE",
251
- "options": { "online": false, "inPerson": true }
252
- },
253
- "category": {
254
- "id": "<CATEGORY_ID_FROM_STEP_0>"
255
- }
256
- }]
257
- }'
258
- ```
259
-
260
- **Create Service Example (CLASS with capacity):**
197
+ **Weekly CLASS** — every Tuesday 18:00–19:00 from the first Tuesday the user gave, no end date:
261
198
 
262
- > **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.
263
-
264
- ```bash
265
- curl -X POST 'https://www.wixapis.com/bookings/v2/bulk/services/create' \
266
- -H 'Authorization: <AUTH>' \
267
- -H 'Content-Type: application/json' \
268
- -d '{
269
- "returnEntity": true,
270
- "services": [{
271
- "name": "Yoga Class",
199
+ ```json
200
+ {
201
+ "returnEntity": true,
202
+ "events": [{
203
+ "event": {
204
+ "scheduleId": "<SERVICE_SCHEDULE_ID>",
272
205
  "type": "CLASS",
273
- "onlineBooking": { "enabled": true },
274
- "defaultCapacity": 20,
275
- "payment": {
276
- "rateType": "FIXED",
277
- "options": { "online": true, "inPerson": false },
278
- "fixed": {
279
- "price": { "value": "25", "currency": "USD" }
280
- }
281
- },
282
- "category": {
283
- "id": "<CATEGORY_ID_FROM_STEP_0>"
284
- }
285
- }]
286
- }'
206
+ "start": { "localDate": "<FIRST_TUESDAY>T18:00:00" },
207
+ "end": { "localDate": "<FIRST_TUESDAY>T19:00:00" },
208
+ "resources": [{ "id": "<STAFF_RESOURCE_ID>", "permissionRole": "WRITER" }],
209
+ "recurrenceRule": { "frequency": "WEEKLY", "interval": 1, "days": ["TUESDAY"] }
210
+ }
211
+ }]
212
+ }
287
213
  ```
288
214
 
289
- After creation, use `results[0].item.schedule.id` from the response to create class events with `bulkCreateEvents` (see Step 3). This requires `returnEntity: true` on the request — without it the response carries only `results[0].itemMetadata.id`, which has no `schedule.id`; and the created service is directly under `item` (there is no `item.service`).
290
-
291
- **Required Fields:**
215
+ This creates one `MASTER` event, and the calendar generates a weekly `INSTANCE` for each Tuesday. To stop the series on a date, add `"until": { "localDate": "<LAST_SESSION_DATE>T19:00:00" }` to `recurrenceRule`.
292
216
 
293
- - `name` - Service name
294
- - `type` - `APPOINTMENT`, `CLASS`, or `COURSE`
295
- - `onlineBooking: { enabled: true }` - Required for all services
296
- - `staffMemberIds` - **Required for APPOINTMENT only** (use `resourceId` values); ignored for CLASS/COURSE
297
- - `schedule.availabilityConstraints.sessionDurations` - Duration in minutes (APPOINTMENT only)
298
- - `defaultCapacity` - **Required for CLASS/COURSE** (max participants per session)
299
- - `payment.options` - At least one of `online` or `inPerson` must be `true` (required for all services, including free; see validation table above)
217
+ **COURSE** — one event per session, all in one call (here the first two of a weekly series):
300
218
 
301
- **Service Type Specific Considerations:**
219
+ ```json
220
+ {
221
+ "returnEntity": true,
222
+ "events": [
223
+ { "event": {
224
+ "scheduleId": "<SERVICE_SCHEDULE_ID>",
225
+ "type": "COURSE",
226
+ "start": { "localDate": "<SESSION_1_DATE>T18:00:00" },
227
+ "end": { "localDate": "<SESSION_1_DATE>T20:00:00" },
228
+ "resources": [{ "id": "<STAFF_RESOURCE_ID>", "permissionRole": "WRITER" }]
229
+ } },
230
+ { "event": {
231
+ "scheduleId": "<SERVICE_SCHEDULE_ID>",
232
+ "type": "COURSE",
233
+ "start": { "localDate": "<SESSION_2_DATE>T18:00:00" },
234
+ "end": { "localDate": "<SESSION_2_DATE>T20:00:00" },
235
+ "resources": [{ "id": "<STAFF_RESOURCE_ID>", "permissionRole": "WRITER" }]
236
+ } }
237
+ ]
238
+ }
239
+ ```
302
240
 
303
- - **APPOINTMENT**: Must include `staffMemberIds` with staff `resourceId` values
304
- - **CLASS/COURSE**: Omit `staffMemberIds`; configure `service.schedule` instead
241
+ Rules for every session event:
242
+ - Wrap each one as `{ "event": { … } }`.
243
+ - `scheduleId` is the **service's** `schedule.id` — not a staff member's schedule — and `type` matches the service type (`CLASS` or `COURSE`).
244
+ - `resources` must hold at least one resource; without it the call fails with `400 resources must have at least 1 resource for class events`. Use the instructor's staff `resourceId`.
245
+ - Every resource needs `"permissionRole": "WRITER"`. Without it the whole call fails with `400 resources.permissionRole must not be UNKNOWN_ROLE`.
246
+ - `start.localDate` / `end.localDate` are local times without a `Z`, in the schedule's time zone (the site's, unless you set `event.timeZone`). A recurring event must start today or later — check the current date before you build the dates.
247
+ - A `recurrenceRule` takes exactly one day. For "Tuesdays and Thursdays", send two events, one per day.
248
+ - Leave `totalCapacity` out: sessions inherit the service's `defaultCapacity`, and setting it detaches that session from later capacity changes.
305
249
 
306
- **Update Service Example (PATCH):**
250
+ **Read the response** the same way as Step 4: check `bulkActionMetadata.totalFailures` and each `results[i].itemMetadata.success`, and fix and resend only the failed events. A `400` (no `results` at all) means nothing was created.
307
251
 
308
- > **Note:** Updates require the current `revision` value (from a GET response) placed **inside** the `service` object, not at the top level.
252
+ **Confirm the sessions exist** before you call the service bookable:
309
253
 
310
- ```bash
311
- # First, get current service to obtain revision
312
- curl -X GET 'https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>' \
313
- -H 'Authorization: <AUTH>'
254
+ `POST https://www.wixapis.com/calendar/v3/events/query`
314
255
 
315
- # Then update with revision inside service object
316
- curl -X PATCH 'https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>' \
317
- -H 'Authorization: <AUTH>' \
318
- -H 'Content-Type: application/json' \
319
- -d '{
320
- "service": {
321
- "revision": "<REVISION_FROM_GET>",
322
- "category": {
323
- "id": "<CATEGORY_ID>"
324
- }
325
- }
326
- }'
327
- ```
328
-
329
- **Update free service to fixed price:**
330
-
331
- When an existing service has `payment.rateType: "NO_FEE"` and the user asks to set a price, convert it to `FIXED` and set the price in the same update.
332
-
333
- ```bash
334
- # First, get current service to obtain revision and current payment settings
335
- curl -X GET 'https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>' \
336
- -H 'Authorization: <AUTH>'
337
-
338
- curl -X PATCH 'https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>' \
339
- -H 'Authorization: <AUTH>' \
340
- -H 'Content-Type: application/json' \
341
- -d '{
342
- "service": {
343
- "revision": "<REVISION_FROM_GET>",
344
- "payment": {
345
- "rateType": "FIXED",
346
- "options": { "online": false, "inPerson": true },
347
- "fixed": {
348
- "price": { "value": "200", "currency": "<SITE_CURRENCY>" }
349
- }
350
- }
351
- }
352
- }'
256
+ ```json
257
+ {
258
+ "fromLocalDate": "<TODAY>T00:00:00",
259
+ "toLocalDate": "<AFTER_LAST_SESSION>T00:00:00",
260
+ "query": { "filter": { "scheduleId": "<SERVICE_SCHEDULE_ID>" } }
261
+ }
353
262
  ```
354
263
 
355
- ### 3. Set the availability of the service
264
+ The result lists the generated sessions (`INSTANCE` events for a weekly class, the single events for a course). For a course, the service itself also reports the span: `GET https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>` returns `schedule.firstSessionStart` and `schedule.lastSessionEnd` once sessions exist.
356
265
 
357
- Once the service and staff member are available, you can define when the service is available:
266
+ **Change sessions later** with `POST https://www.wixapis.com/calendar/v3/bulk/events/update`, sending each event's `id`, its current `revision` and only the fields that change:
358
267
 
359
- **3a. Determine the schedule to use** based on the service type:
360
-
361
- - **APPOINTMENT**: The staff member working hours determine the service availability. If the staff member needs different hours from the business defaults, call `assignWorkingHoursSchedule` (`POST https://www.wixapis.com/bookings/v1/staff-members/<STAFF_MEMBER_ID>/assign-working-hours-schedule`) ([REST](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/assign-working-hours-schedule)). Use the `resource.eventsSchedule.id` as the `scheduleId`.
362
- - **CLASS or COURSE**: Use the `service.schedule.id` from the service created/updated in Step 2.
268
+ ```json
269
+ {
270
+ "events": [{
271
+ "event": {
272
+ "id": "<EVENT_ID>",
273
+ "revision": "<EVENT_REVISION>",
274
+ "start": { "localDate": "<NEW_DATE>T19:00:00" },
275
+ "end": { "localDate": "<NEW_DATE>T20:00:00" }
276
+ }
277
+ }]
278
+ }
279
+ ```
363
280
 
364
- **3b. Create events** using `bulkCreateEvents` (`POST https://www.wixapis.com/calendar/v3/bulk/events/create`) ([REST](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-create-event)) or update existing ones with `bulkUpdateEvents` (`POST https://www.wixapis.com/calendar/v3/bulk/events/update`) ([REST](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-update-event)).
281
+ For a weekly class, update the `MASTER` event (its id is in the create response, or query events with `"recurrenceType": ["MASTER"]`) to move every future session; updating one `INSTANCE` changes only that session. Details: [Bulk Update Event](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-update-event).
365
282
 
366
- **Event requirements**:
283
+ ### Step 6: Appointment availability
367
284
 
368
- - `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.
369
- - `event.scheduleId` — use the staff member's events schedule ID for APPOINTMENT availability, or `service.schedule.id` for CLASS/COURSE.
370
- - `event.type` — set to `WORKING_HOURS` for staff availability, `CLASS` for class sessions, or `COURSE` for course sessions.
285
+ An APPOINTMENT has no events of its own: its free slots come from the working hours of the staff in `staffMemberIds`, which by default follow the business hours. If the user wants different hours for that staff member, follow [Bookings Staff Setup](bookings-staff-setup.md) — it detaches the staff member from the business hours and creates `WORKING_HOURS` events on the staff member's own schedule.
371
286
 
372
- ### Troubleshooting Common Issues
287
+ ### Step 7: Report back
373
288
 
374
- **APPOINTMENT Service Creation Fails (staffMemberIds required):**
289
+ Base the summary on the API responses, not on what you sent:
290
+ 1. **What was created** — name, type, price as stored (amount and currency; "per session" for a class, "for the whole course" for a course; "free" if no price was given, with an offer to set one), capacity, duration or staff for an appointment, category, and hidden if it is.
291
+ 2. **Assumptions** — every default from Step 2 you applied ("I set capacity to 10 since you didn't say").
292
+ 3. **Sessions** (CLASS / COURSE) — the sessions you created and confirmed: list each session's date and time (for a weekly class with no end date, the weekday, time and first date). If none exist yet, say the service can't be booked until it has sessions, and end with a direct question for them: the weekday(s), start and end time, and first date — for a course, the date of each session or the weekly pattern and how many sessions.
293
+ 4. **What you can change** — offer to adjust price, capacity, duration, staff or schedule.
375
294
 
376
- - **Error**: `"service of type appointment requires at least one staff member id"`
377
- - **Cause**: APPOINTMENT services cannot be created without at least one staff member assigned
378
- - **Solution**: Query staff members first (Step 1) to get a valid `resourceId`, then include it in `staffMemberIds`
295
+ ---
379
296
 
380
- **Service Creation Fails (payment.options required):**
297
+ ## Part 2 — Change an existing service
381
298
 
382
- - **Error**: `INVALID_PAYMENT_OPTIONS - "It is mandatory to specify either payment.options.online or payment.options.inPerson as true"`
383
- - **Cause**: All services (including free) require at least one payment option to be `true`
384
- - **Solution**: Add `"options": { "online": true, "inPerson": false }` (or `inPerson: true` for free services) to the `payment` object
299
+ ### Find it and read its revision
385
300
 
386
- **Free Service Fails with online=true:**
301
+ When the user gave a service ID, use it. Otherwise list the services and match the name the user used:
387
302
 
388
- - **Error**: `INVALID_PAYMENT_OPTIONS - "Specifying payment.paymentOptions.online as true is applicable only to payments of types FIXED or VARIED"`
389
- - **Cause**: `payment.options.online: true` is only valid for paid services (FIXED or VARIED)
390
- - **Solution**: For free services (NO_FEE), use `"options": { "online": false, "inPerson": true }`
303
+ `POST https://www.wixapis.com/bookings/v2/services/query`
391
304
 
392
- **Changing a free service price fails:**
305
+ ```json
306
+ { "query": { "paging": { "limit": 100 } } }
307
+ ```
393
308
 
394
- - **Error**: `"Payment of type FREE cannot be used with payment.rate"`
395
- - **Cause**: The service is still `NO_FEE` while the update tries to set `fixed.price`
396
- - **Solution**: Change `payment.rateType` to `"FIXED"` and include `payment.fixed.price` in the same update request
309
+ Page with `offset` as in Step 3 on a site with more than 100 services. If more than one service matches, ask the user which one; if none does, say so rather than creating one. Then read it to get its current `revision` and current values:
397
310
 
398
- **Services Not Appearing in UI Filters:**
311
+ `GET https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>`
399
312
 
400
- - **Problem**: Services created without category assignment are invisible in category-based filters
401
- - **Root Cause**: Many UI implementations filter by `category.id` existence or specific category values
402
- - **Solution**: Query all services, identify those missing categories, and update them using bulk update operations
403
- - **Prevention**: Always assign categories during service creation (Step 0)
313
+ ### Update it
404
314
 
405
- **Staff Assignment Not Working for CLASS/COURSE Services:**
315
+ `PATCH https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>` — send only the fields you're changing, with the current `revision` **inside** the `service` object (a `revision` at the top level fails with `revision must not be empty`):
406
316
 
407
- - **Problem**: Setting `staffMemberIds` in CLASS or COURSE services appears to be ignored
408
- - **Solution**: This is expected behavior; use service schedules instead of staff assignments
409
- - **Alternative**: Manage staff-to-class relationships through calendar events or custom data structures
317
+ ```json
318
+ {
319
+ "service": {
320
+ "revision": "<REVISION_FROM_GET>",
321
+ "category": { "id": "<CATEGORY_ID>" }
322
+ }
323
+ }
324
+ ```
410
325
 
411
- **App Not Installed Errors:**
326
+ The same shape changes the name, description, capacity, `hidden` (`true` hides the service from the site's booking pages, `false` shows it again) or `onlineBooking`. Update the existing service — don't delete and recreate it, which loses its bookings and sessions.
412
327
 
413
- - **Problem**: 428 "App not installed" errors when creating services
414
- - **Solution**: Install Wix Bookings app using Apps Installer API before creating services
415
- - **Verification**: Query existing services to confirm app installation
328
+ **Free → paid.** A `NO_FEE` service becomes paid only when one update sends the whole payment object — `rateType: "FIXED"`, `options` and `fixed.price` together. Send the `options` the GET returned (a free service usually has `inPerson: true`), so customers keep paying the way they already could; turn on `online` only when the user asks for online payment. Patching just `fixed.price` fails validation (`Payment of type FREE cannot be used with payment.rate`, or `payment.type Payment type must be set to FIXED`):
416
329
 
417
- **Resource ID vs Staff ID Confusion:**
330
+ ```json
331
+ {
332
+ "service": {
333
+ "revision": "<REVISION_FROM_GET>",
334
+ "payment": {
335
+ "rateType": "FIXED",
336
+ "options": { "online": false, "inPerson": true },
337
+ "fixed": { "price": { "value": "35" } }
338
+ }
339
+ }
340
+ }
341
+ ```
418
342
 
419
- - **Problem**: Using wrong ID type for `staffMemberIds` array
420
- - **Solution**: Always use `staffMember.resourceId`, not `staffMember.id`
421
- - **Verification**: Query staff with `RESOURCE_DETAILS` fieldMask to get correct IDs
343
+ The price takes the site's currency, as on create. To change only the amount of a service that is already `FIXED`, send the same payment object with the new value.
422
344
 
423
- **Service Schedule vs Staff Schedule Confusion:**
345
+ **Several services at once.** [Bulk Update Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services) takes a list of services (each with its own `id` and `revision`); [Bulk Update Services By Filter](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services-by-filter) applies one change to every service a filter matches ("make all my services 60 minutes").
424
346
 
425
- - **Problem**: Mixing up schedule IDs between service and staff schedules
426
- - **Solution**:
427
- - APPOINTMENT: Use staff schedule ID (`staffMember.resource.eventsSchedule.id`)
428
- - CLASS/COURSE: Use service schedule ID (`service.schedule.id`)
347
+ **Changing the type** (`"type": "COURSE"` in the same PATCH) deletes the service's schedule and sessions and creates a new schedule. Confirm with the user before doing it, then schedule the sessions again on the new `schedule.id` (Step 5).
348
+ - An APPOINTMENT that already has future bookings can't change type — the update fails with `can't change a service of type appointment after it has been booked`. Tell the user; don't cancel their bookings to get around it.
349
+ - Changing to or from COURSE resets the service's locations to the site's default business location; restore any other location the user needs with [Set Service Locations](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/set-service-locations). Changing an APPOINTMENT to a CLASS or COURSE also clears its `staffMemberIds` and session durations.
429
350
 
430
- **Update Service Fails with revision error:**
351
+ **Deleting a service**: `DELETE https://www.wixapis.com/bookings/v2/services/<SERVICE_ID>` cancels its future sessions. Confirm with the user first.
431
352
 
432
- - **Error**: `revision must not be empty` or `service.revision is required`
433
- - **Cause**: `revision` placed at top level of request body instead of inside `service` object
434
- - **Solution**: Structure as `{ "service": { "revision": "...", ...fields } }` - get revision value from GET response first
353
+ ---
435
354
 
436
- ### IMPORTANT NOTES
355
+ ## Errors
356
+
357
+ | Error | Cause | Fix |
358
+ |---|---|---|
359
+ | `service of type appointment requires at least one staff member id` | APPOINTMENT without `staffMemberIds` | Query staff (Step 3) and send a `resourceId` |
360
+ | `primary_resource_type is required for appointment services without staff members` | An APPOINTMENT booked by a room or equipment | Follow [Multi-Resource Service Creation](multi-resource-service-creation.md) for the body |
361
+ | `INVALID_PAYMENT_OPTIONS` — "mandatory to specify either payment.options.online or payment.options.inPerson as true" | No payment option set | Set `inPerson: true` (free) or `online: true` (paid) |
362
+ | `INVALID_PAYMENT_OPTIONS` — "online as true is applicable only to payments of types FIXED or VARIED" | `online: true` on a `NO_FEE` service | Free services use `online: false, inPerson: true` |
363
+ | `Payment of type FREE cannot be used with payment.rate` | Price set on a `NO_FEE` service without changing `rateType` | Send `rateType: "FIXED"`, `options` and `fixed.price` in one update |
364
+ | `revision must not be empty` / `service.revision is required` | `revision` missing or outside `service` | `{ "service": { "revision": "…", … } }`, revision from a fresh GET |
365
+ | `resources.permissionRole must not be UNKNOWN_ROLE` | Session resource without `permissionRole` | `"resources": [{ "id": "…", "permissionRole": "WRITER" }]` |
366
+ | `resources must have at least 1 resource for class events` | Session event without `resources` | Add the instructor's staff `resourceId` |
367
+ | Course page says "Ended" or "This service is not available" | The course has no future sessions | Create the sessions (Step 5) and confirm them |
368
+ | `428` app not installed | Wix Bookings isn't on the site | Install it with [Install Wix Apps](../app-installation/install-wix-apps.md) and retry |
437
369
 
438
- - I MUST read the full article about the REST method I wish to use
439
- - `onlineBooking` 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.
440
- - Event Creation (BulkCreateEvents): When specifying recurrenceRule.days, I MUST use full day names (e.g., "TUESDAY", "FRIDAY")
441
- - The recurrenceRule.days field within an event object can only accept a single day of the week (e.g., ["TUESDAY"]).
442
- - If I need to set up recurring events for multiple days of the week (e.g., a staff member working every Tuesday and Friday), I MUST define a separate event for each day and send them as separate items for BulkCreateEvents.
443
- - Start Dates for Recurring Events: Recurring events must have a start.localDate that is today or in the future, relative to the server's current time. If I am not sure what the current date and time are I MUST check it.
444
- - When setting `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 hours
445
- - When setting `event.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
370
+ ---
446
371
 
447
- ## Booking REST API Documentation Reference
372
+ ## Reference
448
373
 
449
- - [Query Categories](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/query-categories)
450
- - [Create Category](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/create-category)
451
- - [Get Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/get-service)
452
- - [Update Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/update-service)
453
- - [Create Staff Member](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/create-staff-member)
454
- - [Get Staff Member](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/get-staff-member)
455
- - [Query Staff Members](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/query-staff-members)
456
- - [Bulk Create Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-create-services)
457
- - [Bulk Update Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services)
458
- - [Bulk Update Services By Filter](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services-by-filter)
459
- - [Assign Working Hours Schedule](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/assign-working-hours-schedule)
460
- - [Bulk Create Events](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-create-event)
461
- - [Bulk Update Events](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-update-event)
462
- - [Media Manager: Search Files](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/search-files)
463
- - [Media Manager: Bulk Import File](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/bulk-import-file)
464
- - [Query Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/query-services)
465
- - [Apps Installer API](https://dev.wix.com/docs/api-reference/business-management/app-installation/install-app)
374
+ - Services: [Bulk Create Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-create-services) · [Create Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/create-service) (field rules) · [Get Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/get-service) · [Query Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/query-services) · [Update Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/update-service) · [Bulk Update Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services) · [Bulk Update Services By Filter](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/bulk-update-services-by-filter) · [Delete Service](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/delete-service)
375
+ - Concepts: [About Service Types](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types) · [About Service Payments](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-payments) · [About Service Locations](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-locations)
376
+ - Categories: [Query Categories](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/query-categories) · [Create Category](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/categories-v2/create-category)
377
+ - Staff: [Query Staff Members](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/query-staff-members) · [Create Staff Member](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/staff-members/create-staff-member) · [Assign Working Hours Schedule](https://dev.wix.com/docs/api-reference/business-solutions/bookings/staff-members/assign-working-hours-schedule)
378
+ - Sessions: [Bulk Create Event](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-create-event) · [Bulk Update Event](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/bulk-update-event) · [Query Events](https://dev.wix.com/docs/api-reference/business-management/calendar/events-v3/query-events)
379
+ - Media: [Search Files](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/search-files) · [Bulk Import File](https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/bulk-import-file)