| Input | How to get it |
|---|---|
| Visitor token | STEP 1 |
| Business timezone | GetBusinessDetails → timeZone |
reservationLocationId, partySize.min/max, businessSchedule.periods, approval.mode | STEP 2 |
| Requested date + time converted to UTC in the business zone; party size within bounds | Visitor + date rules |
Guest firstName and phone (required), optional last name/email | Ask the visitor — do not fabricate |
Experience id, per-guest price, weekly schedule (experiences) | STEP 5 |
experienceId).428 MUST_BE_PREMIUM at any write: stop, explain online reservations aren't enabled on this site, give phone/email from GetBusinessDetails.date/startDate (2026-09-17T19:30:00+03:00 → 2026-09-17T16:30:00Z). Sending the local clock time with a Z suffix asks for the wrong hour (a 19 request became 22 local and returned NON_WORKING_HOURS).timeSlotInterval (15 min here); ask for slotsBefore/slotsAfter to offer neighbours.status: "AVAILABLE" slots are bookable; NON_WORKING_HOURS and UNAVAILABLE are not.GenerateVisitorToken once; reuse it.
GET https://www.wixapis.com/table-reservations/reservation-locations/v1/reservation-locations (visitor-readable).
POST https://www.wixapis.com/table-reservations/reservations/v1/time-slots
→ { "timeSlots": [{ "startDate": "2026-09-17T16:30:00Z", "duration": 90, "status": "AVAILABLE", "manualApproval": false }, …] }. Offer the AVAILABLE ones in local time. check-time-slot (same base, /check-time-slot) additionally requires duration — prefer time-slots.
Single-shot alternative (also used for experiences): POST https://www.wixapis.com/table-reservations/reservations/v1/reservations
On this (free-plan) site both hold and reservations return 428 { "message": "site must be premium", "details": { "applicationError": { "code": "MUST_BE_PREMIUM" } } }. That is the expected gate — reading slots works, writing does not.
POST https://www.wixapis.com/table-reservations/experiences/v1/experiences/query with { "query": {} } (visitor-readable).
There is no experience-scoped availability endpoint: compute the next occurrences yourself from weeklyOptions.startDaysAndTimes (+ startDate/endDate, oneTimeOptions) in the business timezone, honouring minimumReservationNotice. Price is per guest in the site currency. Booking uses STEP 4b with details.experienceId; it is premium-gated like tables.
428 MUST_BE_PREMIUM ("site must be premium") on hold / reserve / createOnline reservations need a premium plan even though the location reads onlineReservationsEnabled: true. Don't retry; give the visitor the phone and email.
NON_WORKING_HOURSYou sent local time with a Z. Convert to UTC from the business timezone first.
400 duration must not be empty from check-time-slotUse time-slots (no duration needed) or pass duration in minutes.
404 on /table-reservations/v1/reservations/held or /table-reservations/v1/reservationsThe base is /table-reservations/reservations/v1/…; hold is /reservations/hold, confirm is /reservations/{id}/reserve, create is /reservations.
firstName and phone are required for every online reservation; use a real E.164 number from the visitor.
None exists; project the schedule (STEP 5).
| Constant | Value |
|---|---|
| Table Reservations app id | f9c07de2-5341-40c6-b096-8eb39de391fb |
| Reservations base | https://www.wixapis.com/table-reservations/reservations/v1/ |
| Held reservation lifetime | 10 minutes |
Last updated: 17 September 2026