Below are the recommended steps to successfully create Wix Bookings services that require multiple resource types (e.g., Room + Equipment + Instructor). This recipe covers the gaps in individual API documentation: resource architecture planning, entity relationship patterns, availability dependencies, and real-world coordination challenges that aren't clear from reading individual API references.
Before creating multi-resource services, ensure the following requirements are met:
Resource type, resource, and resource-bound service creation succeed via the API without any premium-related error. If a plan-gating error does occur, it surfaces explicitly (e.g. a 403) — don't preemptively block on plan checks.
If you encounter resource-related errors, install the required apps using the Apps Installer API.
For detailed app installation procedures, refer to:
Multi-resource services allow businesses to create bookings that require multiple types of resources simultaneously. Common examples:
The system involves three independent entity types that can be connected:
Key Architecture Principle: Resources and Services are separate, independent entities. Resources exist independently but their availability depends on business location hours (for non-staff resources) or working hour schedules (for staff resources). Services can optionally connect to resource types (not individual resources) to require resource allocation during booking, but this connection is loose and flexible.
❌ COMMON ARCHITECTURE MISTAKES (Not Clear in Individual Docs):
✅ CORRECT RESOURCE ARCHITECTURE:
resourceType.id, not individual resource IDsResource Availability Behavior:
eventsSchedule for tracking bookingsworkingHoursSchedules is configured, it takes precedence over location hoursSchedule Sharing Patterns:
shared: false = Dedicated schedule per resource (recommended for most cases)shared: true = Multiple resources use same working hours scheduleshared: true among staffService Configuration Pattern:
Critical: Services specify resource types, not individual resources. This creates a loose coupling where:
availableInAllLocations: true is simplest; specific location configuration is complex and often unnecessaryBefore creating anything, plan your resource type structure. Each type should represent a category of resources that can be substituted for each other in bookings.
Common Resource Type Patterns:
Design Principle: If resources are interchangeable for a service, they belong to the same type.
Create resource types using createResourceType API (POST https://www.wixapis.com/bookings/v2/resources/resource-types) (REST):
The response returns resourceType.id — save it for resource creation and the service's serviceResources.
Key Requirements:
name must be unique across the sitename descriptive but concise (appears in booking interface)resourceType.id for resource creationImportant: Cannot change name after creation if conflicts occur - plan carefully.
Create the resource instances of each type. For more than one (the usual case — e.g. Room A and Room B), use bulkCreateResources (POST https://www.wixapis.com/bookings/v2/bulk/resources/create) (REST); for a single one, createResource (POST https://www.wixapis.com/bookings/v2/resources) takes { "resource": { "name": ..., "typeId": ... } }.
Read each created resource's ID from results[i].item.id (with returnEntity: true) or results[i].itemMetadata.id (without it). The resource is directly under item — there is no item.resource.id (reading it throws Cannot read properties of undefined). Match items to your request by itemMetadata.originalIndex, and check bulkActionMetadata.totalFailures before proceeding.
⚠️ Payload shape: the type reference is the flat typeId field (same on single and bulk). Sending a nested object ("type": {"id": ...}) fails with 400 Unexpected value for StringValue. A resource without typeId is created but is not bookable.
If you omit locationOptions, the resource defaults to availableInAllLocations: true — the simplest and usually correct configuration; specific location setup is complex and often unnecessary.
Advanced Configuration (Gap):
specificLocationOptions (complex - avoid unless required)Critical: Each resource automatically gets its own eventsSchedule for booking management (this is documented but the implications for multi-resource coordination aren't clear).
Create the service that optionally connects to multiple resource types using bulkCreateServices API (POST https://www.wixapis.com/bookings/v2/bulk/services/create) (REST). Note the endpoint path is /bulk/services/create (not /services/bulk/create, which 404s).
Pick the service type, and mind the resource-specific required fields:
APPOINTMENT. When such a service is driven by a resource instead of a staff member, primaryResourceType (a flat resource-type GUID) is required — omitting it fails with 400 primary_resource_type is required for appointment services without staff members. APPOINTMENT also needs schedule.availabilityConstraints.sessionDurations.CLASS (drop-in) or COURSE (whole series); these use defaultCapacity and do not require primaryResourceType.Appointment example (one room per booking, no staff):
For a group service, use "type": "CLASS" with "defaultCapacity": <n> instead of primaryResourceType/sessionDurations. Both types take payment.options (at least one of online/inPerson true) — required even for the resource-bound case.
Save the service ID from the response: results[0].item.id (with returnEntity: true), or results[0].itemMetadata.id (without it). There is no results[0].item.service.id — reading that path throws Cannot read properties of undefined.
⚠️ Verify from the response, not from assumptions: without returnEntity: true the bulk response contains only results[0].itemMetadata (id + success flag) — there is no item. With the flag, the created service is at results[0].item (e.g. item.id, item.serviceResources). Check bulkActionMetadata.totalFailures and each itemMetadata.success before reporting the service as created.
Key Principle: This creates a loose connection where the service requests resource allocation during booking, but resources remain independent entities with their own lifecycle and management.
Pricing Strategy: Multi-resource services typically command premium pricing due to coordination complexity.
The docs don't explain how multi-resource allocation actually works during booking. Key behaviors to understand:
Architecture Implication: Plan resource quantities based on expected concurrent demand across all services.
"Resource type not found" Error:
typeId exactly matches the resource type idname when id is required400 "Unexpected value for StringValue" on createResource or on service primaryResourceType:
createResource uses "typeId": "<guid>"; the service field is "primaryResourceType": "<guid>" (both flat, not {"id": ...}). Note this differs from serviceResources[].resourceType.id, which is nested.400 "primary_resource_type is required for appointment services without staff members":
APPOINTMENT service bound to a resource (no staffMemberIds) needs primaryResourceType set to the driving resource-type GUID. Either add it, or model the service as a CLASS/COURSE if a group service fits.404 on bulk creation:
bulk/<entity>/create: POST /bookings/v2/bulk/services/create, POST /bookings/v2/bulk/resources/create. /bookings/v2/services/bulk/create (and the resources equivalent) do not exist.Cannot read properties of undefined after a bulk create (resources or services):
results[i].item — use item.id, never item.resource.id or item.service.id. Without returnEntity: true there is no item at all, only itemMetadata.id."Resource type name already exists" Error (409):
Service doesn't show resource requirements:
serviceResources array includes all required resource typesResources showing as unavailable:
workingHoursSchedules is too restrictivelocationOptions matches your business location setupavailableInAllLocations: true to eliminate location issuesResource updates failing:
Complex location availability issues:
availableInAllLocations: true for all resourcesResource deletion concerns:
Resource Type Design:
Resource Naming:
Availability Strategy:
workingHoursSchedules to non-staff resources unless business rules require it — without them the resource simply follows business location hours, which is usually what you wantService Design:
Last updated: 10 September 2026