Skip to main content

Resources & Instances

Reservations draw a deliberate line between what can be booked and the physical thing that gets used. A "Deluxe King Suite" is a type with a nightly rate and an occupancy rule; "Room 204" and "Room 205" are the units that actually get assigned, checked in, and cleaned. Keeping these separate lets one resource definition back many interchangeable units, and lets you take a single unit out of service without touching the catalog.

The catalog has three layers:

  • ResourceCategory groups resources for browsing, display order, channel mapping, and resource-type filtering.
  • Resource defines a bookable type — a dining table type, a room type, or a rental product — with its capacity, pricing, booking behavior, and checklist templates.
  • ResourceInstance is a physical unit under a resource that can be assigned, reserved, occupied, blocked for maintenance, cleaned, or retired.
Resource catalog structure and instance lifecycleA category groups resources. Each resource carries capacity, pricing, and checklist configuration and has physical instances. An instance cycles through available, reserved, occupied, and cleaning, and can be blocked for maintenance or taken out of service.groupshas unitsCategorygroupingResourcebookable typeInstancephysical unitcapacitypricingchecklistINSTANCE STATUSavailablereservedoccupiedcleaning↺ back to availablemaintenanceout_of_serviceblocked — not assignable until restored

Why it matters

  • One type, many units — define a room or table type once, then add as many interchangeable instances as you own. Bookings match the type; the platform assigns a free unit.
  • Operational truth — take a single instance into maintenance or cleaning without making the whole resource unbookable.
  • Right model per business — capacity and pricing strategies adapt the same structure to tables (party-size ranges), rooms (occupancy + nightly rates), and rentals (single-unit limits + tiered pricing).

ResourceCategory

Groups resources by business use, location scope, resource type, and external channel mapping.

FieldTypeRequiredDescription
idstringYesUnique category identifier
namestringYesCategory display name
descriptionstring | nullNoPublic or administrative description
locationIdstring | nullNoLocation scope; null applies across locations
resourceTypeenum | nullNotable, room, rental, or resource scope
displayOrdernumber | nullNoStable ordering for catalog displays
channelMappingsarray | nullNoExternal channel category IDs (channelId, externalCategoryId)
isActivebooleanYesWhether the category is usable (default: true)
metadataobject | nullNoIntegration-specific or rendering metadata
resourceRevisionIdstring | nullNoVersion revision this category belongs to

Resource

Defines a reservable type, including capacity, pricing, booking behavior, checklist templates, and display metadata.

FieldTypeRequiredDescription
idstringYesUnique identifier
resourceTypeenumYestable, room, rental, or resource
namestringYesResource name
categoryIdstring | nullNoCategory this resource belongs to
locationIdstring | nullNoLocation scope
descriptionstring | nullNoDescription
imageUrlsstring[] | nullNoImage URLs
capacityinteger | nullNoSimple capacity
capacityConfigobject | nullNoStrategy-based capacity (see below)
isAvailablebooleanYesCatalog availability (default: true)
amenitiesstring[]NoAmenity labels (default: [])
pricingobject | nullNoPricing strategy (see below)
turnoverMinutesinteger | nullNoReset time between bookings
reservationDurationinteger | nullNoDefault duration
reservationDurationUnitenum | nullNominutes, hours, or nights
checklistTemplatearrayNoPickup/return checklist items (default: [])
applicableTierIdsstring[]NoPricing tier IDs (default: [])
attributesarray | nullNoStructured key/value attributes
instancesarray | nullConditionalInstance IDs (read) / embedded definitions (create)

Capacity strategies

capacityConfig is discriminated by kind and pairs with a resource type.

Strategy (kind)Resource typeFieldsPurpose
rangetablemin, maxParty-size matching
occupancyroomstandard, max, extraFeeLodging occupancy pricing
singlerentalvalue, weightLimit, skillLevelSingle-unit rental constraints

Pricing strategies

pricing is discriminated by kind.

Strategy (kind)Resource typeFieldsPurpose
nonetableholdPolicyNo price quote needed for a slot
dayOfWeekroomrates.monrates.sunNightly rate generation
tieredrentaltiers[] (from, to, price)Duration- or quantity-based pricing

Checklist templates

For rentals especially, a resource can carry a checklist that staff complete at handover. Each item has an id, a label, a required flag (default true), and a phasepickup, return, or both (default both).

Capacity & pricing in context

The configuration is identical across SDKs and channels — here is a room type with occupancy capacity, day-of-week rates, and two embedded instances:

{
"resourceType": "room",
"name": "King Suite",
"capacityConfig": { "kind": "occupancy", "standard": 2, "max": 4, "extraFee": 25 },
"pricing": {
"kind": "dayOfWeek",
"rates": { "mon": 220, "tue": 220, "wed": 240, "thu": 260, "fri": 320, "sat": 340, "sun": 250 }
},
"amenities": ["wifi", "kitchenette", "city-view"],
"instances": [
{ "name": "Room 204", "code": "204", "status": "available" },
{ "name": "Room 205", "code": "205", "status": "available" }
],
"isAvailable": true
}
Instance requirement on create

When you create a room or rental resource here, it must include at least one instance. On create, the embedded instance definitions omit resourceId; the server assigns it once the parent resource exists. (table resources are exempt because you don't create them here at all — see below.)

Table resources come from floor plans

table resources are not created directly. The platform creates a table Resource and its ResourceInstance automatically when you author a Floor Plan — that is why tables are exempt from the instance-requirement rule above. Create rooms and rentals here; create tables by defining a floor plan.

ResourceInstance

A physical table, room, rental unit, or other concrete unit under a resource.

FieldTypeRequiredDescription
idstringYesUnique identifier
resourceIdstringYesParent resource
namestring | nullNoInstance name (e.g. "Room 204")
codestring | nullNoShort code (e.g. "204")
statusenumYesLifecycle status (default: available)
isAvailablebooleanYesPhysical availability (default: true)
attributesarray | nullNoStructured key/value attributes (floor, view, …)
locationIdstring | nullNoLocation scope

Status lifecycle

ValueMeaning
availableCan be assigned
reservedReserved for a future booking
occupiedCurrently in use
maintenanceTemporarily blocked for maintenance
cleaningTemporarily blocked for reset or cleaning
out_of_serviceNot usable until restored
note

Keep physical availability on the ResourceInstance (status, isAvailable) and catalog availability on the Resource (isAvailable).

Resource versioning

Versioning separates a stable catalog definition from its mutable revisions, so you can edit a catalog without disturbing existing reservations. A ResourceDefinition (id, name, description, isActive) owns one or more ResourceRevision records, each with a status of draft, active, or archived, an optional derivedFromRevisionId, and a publishedAt timestamp. Draft a revision for editing, publish it before exposing it to booking channels, and keep historical reservations tied to the resource and instance IDs that existed when they were booked. Catalog records can carry a resourceRevisionId when a revision-specific view is needed.

Query options

Each resource supports paginated filtering and sorting:

ResourceFiltersSort fields
ResourceCategorysearch, locationId, resourceType[], isActivename, displayOrder, createdAt
Resourcesearch, locationId, resourceType[], categoryId, isAvailable, capacityRange, location, amenities[], priceRangename, capacity, createdAt
ResourceInstanceresourceId, locationId, status[], isAvailablename, status, createdAt

All sorts take a direction of asc or desc.

Create a resource

A resource is created with its type, configuration, and (for non-table types) its instances.

import { ResourceType, ResourceInstanceStatus } from 'wiil-core-js';

const roomResource = await client.reservationResources.create({
name: 'Deluxe Ocean Suite',
resourceType: ResourceType.ROOM,
capacity: 4,
isAvailable: true,
amenities: ['WiFi', 'Air Conditioning', 'Mini Bar', 'Ocean View'],
checklistTemplate: [],
applicableTierIds: [],
instances: [
{ name: 'Room 101', code: 'R101', status: ResourceInstanceStatus.AVAILABLE, isAvailable: true },
{ name: 'Room 102', code: 'R102', status: ResourceInstanceStatus.AVAILABLE, isAvailable: true },
],
});

console.log(`Room Resource Created: ${roomResource.id}`);

Read, update, and batch

import { ResourceType } from 'wiil-core-js';

const loaded = await client.resourceCategories.get('category_123');
const roomCategories = await client.resourceCategories.getByResourceType(ResourceType.ROOM);
const allInstances = await client.resourceInstances.getByResource(roomResource.id);
SDK models differ for reservations

The TypeScript SDK manages categories and instances as dedicated resources (client.resourceCategories, client.resourceInstances), shown below. The Python SDK manages physical inventory through the unified client.reservation_resources model — creating resources (optionally with embedded instances), filtering by type, updating availability, and batch-creating — rather than as separate category/instance clients.

Resource categories

Organize resources into categories. (TypeScript SDK)

import { ResourceType } from 'wiil-core-js';

const category = await client.resourceCategories.create({
name: 'Conference Rooms',
description: 'Meeting and conference spaces',
resourceType: ResourceType.ROOM,
isActive: true,
displayOrder: 1,
});

const roomCategories = await client.resourceCategories.getByResourceType(ResourceType.ROOM);
const activeCategories = await client.resourceCategories.getActive();
const allCategories = await client.resourceCategories.list();

const updated = await client.resourceCategories.update(category.id, {
id: category.id,
description: 'Premium meeting spaces',
displayOrder: 2,
});

const batch = await client.resourceCategories.createBatch([
{ name: 'Executive Suites', resourceType: ResourceType.ROOM, isActive: true, displayOrder: 10 },
{ name: 'Equipment Rentals', resourceType: ResourceType.RENTAL, isActive: true, displayOrder: 11 },
]);

await client.resourceCategories.delete(category.id);

Resource instances

Manage individual bookable units within a resource. (TypeScript SDK)

import { ResourceInstanceStatus } from 'wiil-core-js';

const instance = await client.resourceInstances.create({
resourceId: roomResource.id,
name: 'Room 201',
code: 'R201',
status: ResourceInstanceStatus.AVAILABLE,
isAvailable: true,
attributes: [
{ key: 'floor', value: '2' },
{ key: 'view', value: 'garden' },
],
});

const resourceInstances = await client.resourceInstances.getByResource(roomResource.id);
const availableInstances = await client.resourceInstances.getByStatus(ResourceInstanceStatus.AVAILABLE);

const updatedInstance = await client.resourceInstances.update(instance.id, {
id: instance.id,
code: 'R201-PREMIUM',
attributes: [
{ key: 'floor', value: '2' },
{ key: 'view', value: 'ocean' },
],
});

await client.resourceInstances.delete(instance.id);