ResytechResytech Docs

Activities, Calendar & Timeslots

Browse activities, check availability calendars, retrieve time slots, and discover eligible add-ons using the ResytechApi client.

This page covers the read-side of the booking flow: fetching activity details, checking calendar availability, loading time slots for a given date, and discovering eligible add-ons.

All examples assume you have already initialized the API client:

const api = new ResytechApi({ debug: true });
const init = await api.initialization.initialize({ identifier: 'session-1' });

All response types on this page extend ApiResponseBase, which adds message, statusCode, action, and isNetworkError on top of the fields shown below. Always check success before reading the payload.

Activities

getActivity

Retrieve full details for a single activity, including equipment, durations, media, custom fields, agreements, and trip protection settings.

const result = await api.activity.getActivity('activity-uuid');

if (result.success) {
  const activity = result.activity;
  console.log(activity.name, '- Base price:', activity.basePrice);
}

Parameters

ParameterTypeRequiredDescription
uuidstringYesActivity unique identifier

ActivityResponse

FieldTypeDescription
successbooleanWhether the request succeeded
activityActivityFull activity details (see below)

Activity Type

FieldTypeDescription
uuidstringUnique identifier
namestringDisplay name
basePricenumberBase price in dollars (decimal)
descriptionstringFull description
cancellationPolicystringCancellation policy text
detailsstringAdditional details
mediaMedia[]Images and videos
durationsDuration[]Available booking durations
equipmentEquipment[]Available equipment (boats, kayaks, etc.)
manifestManifestGuest limits, age restrictions, demographics
firstAvailableDateDateEarliest bookable date
allowEquipmentMixingbooleanWhether customers can book multiple equipment types
maxEquipmentPerBookingnumberMax equipment items per booking
customFieldsCustomField[]Custom form fields for checkout
agreementsActivityAgreement[]Agreements the customer must accept
typenumberActivity type identifier
allowPrivateToursbooleanWhether private tours are available
dynamicDurationSettingsActivityDynamicDurationSettingDynamic duration config
schedulingActivitySchedulingDate range and cutoff settings
tripProtectionTripProtectionTrip protection configuration

Supporting Types

Duration

FieldTypeDescription
uuidstringDuration identifier (pass to cart/calendar requests)
minutesnumberDuration length in minutes
pricenumberBase price for this duration

Equipment

FieldTypeDescription
uuidstringEquipment identifier
namestringDisplay name
descriptionstringShort description
detailsstringDetailed info
quantitynumberTotal inventory
capacitynumberSeats per unit
mediaMedia[]Images
addonsAddon[]Equipment-specific add-ons
amenitiesAmenity[]Equipment amenities
propertiesEquipmentProperty[]Custom properties (e.g., length, weight)

Manifest

FieldTypeDescription
guestLimitnumberMaximum guests per booking
ageRestrictionnumberMinimum age
guestMinimumnumberMinimum guests per booking
demographicsDemographic[]Guest demographics (adults, children, etc.)

Media

FieldTypeDescription
uuidstringMedia identifier
ordernumberDisplay order
typenumberMedia type (image, video, etc.)
uristringFull-size URL
thumbnailUristringThumbnail URL

Addon

FieldTypeDescription
uuidstringAdd-on identifier
namestringDisplay name
descriptionstringDescription
pricenumberPrice per unit

Amenity

FieldTypeDescription
idstringAmenity identifier
namestringDisplay name
descriptionstringDescription
iconTypenumberIcon type indicator
iconstringIcon name or URI
assignmentCountnumberNumber of equipment items this amenity is assigned to

EquipmentProperty

FieldTypeDescription
idstringProperty identifier
namestringProperty name (e.g., "Length")
valuestringProperty value (e.g., "12 ft")
descriptionstringOptional description
iconTypenumberIcon type indicator
iconstringIcon name or URI
featuredbooleanWhether to highlight this property

Demographic

FieldTypeDescription
uuidstringDemographic identifier
titlestringDisplay name (e.g., "Adult", "Child")
descriptionstringDescription

CustomField

FieldTypeDescription
uuidstringField identifier
typenumberField type indicator
labelstringField label shown to the customer
requiredbooleanWhether the customer must answer

ActivityAgreement

FieldTypeDescription
uuidstringAgreement identifier
titlestringAgreement title
bodystringAgreement body text
requiredbooleanWhether the customer must accept
enabledbooleanWhether this agreement is active

ActivityDynamicDurationSetting

FieldTypeDescription
enabledbooleanWhether dynamic durations are enabled
minimumHoursnumberMinimum bookable duration in hours
maximumHoursnumberMaximum bookable duration in hours
incrementMinutesnumberAllowed increment (in minutes) between min and max
baseHourlyRatenumberHourly rate used for pricing
createdAtDateCreated timestamp
updatedAtDateLast updated timestamp

ActivityScheduling

FieldTypeDescription
dateTypenumberDate selection mode (range vs specific dates)
dateRangeDateOnlyRangeBookable date range (when dateType is range)
specificDatesstring[]Bookable dates (when dateType is specific dates)
earlyCutoffTypenumberCutoff unit (hours, days, etc.)
earlyCutoffValuenumberHow far in advance bookings must be made
futureCutoffDaysnumberHow far into the future bookings can be made

TripProtection

FieldTypeDescription
enabledbooleanWhether trip protection is offered
pricingTypenumberPricing mode (flat amount vs percent)
flatAmountnumberFlat fee when pricingType is flat
percentAmountnumberPercentage when pricingType is percent
coverageTypenumberCoverage mode
coverageAmountnumberAmount of coverage provided
customTitlestringCustom display title
customDescriptionstringCustom description shown to the customer

Calendar

Calendar endpoints return monthly availability data. Use them to build date pickers that show which days have open slots.

getActivityCalendar

Get availability for a specific activity in a given month.

const calendar = await api.calendar.getActivityCalendar({
  activity: 'activity-uuid',
  month: 7,
  year: 2025,
  includePrices: true
});

if (calendar.success) {
  calendar.calendar.days.forEach(day => {
    console.log(day.date, day.isAvailable ? `$${day.price}` : 'unavailable');
  });
}

getCartCalendar

Same as getActivityCalendar, but returns availability that accounts for items already in the cart. Use this when the customer is adding a second activity to an existing booking.

const calendar = await api.calendar.getCartCalendar({
  activity: 'activity-uuid',
  month: 7,
  year: 2025,
  cartId: 'existing-cart-id'
});

ActivityCalendarRequest

FieldTypeRequiredDescription
activitystringYesActivity UUID
monthnumberYesMonth (1-12)
yearnumberYesYear (e.g. 2025)
includePricesbooleanNoInclude per-day pricing
durationstringNoDuration UUID to filter by
startTimestringNoFilter by start time
equipmentClientShoppingCartEquipment[]NoEquipment selection to check against
durationMinsnumberNoDuration in minutes (for dynamic durations)
cartIdstringNoCart ID (used by getCartCalendar)

CalendarResponse

FieldTypeDescription
successbooleanWhether the request succeeded
calendarCalendarMonthMonth data with daily availability

CalendarMonth

FieldTypeDescription
monthnumberMonth number (1-12)
yearnumberYear
daysActivityCalendarDay[]Array of day objects

ActivityCalendarDay

FieldTypeDescription
datestringDate string (YYYY-MM-DD)
isAvailablebooleanWhether there is availability on this day
pricenumberStarting price for this day (if includePrices was true)
isEstimatedPricebooleanWhether the price is an estimate
blackoutMessagestringReason the day is blacked out (if applicable)

Time Slots

Once the customer selects a date, load the available time slots for that day.

getActivityTimeSlots

Get time slots for a specific activity on a given date.

const slots = await api.timeslots.getActivityTimeSlots({
  activity: 'activity-uuid',
  date: '2025-07-15',
  durationMins: 60
});

if (slots.success) {
  slots.timeSlots.forEach(slot => {
    console.log(`Price: $${slot.price}, Seats left: ${slot.remainingSeats}`);
  });
}

getLocationTimeSlots

Get time slots for all activities at the location. Useful for location-wide availability views.

const locationSlots = await api.timeslots.getLocationTimeSlots({
  date: '2025-07-15',
  durationMins: 60
});

if (locationSlots.success) {
  locationSlots.results.forEach(activitySlots => {
    console.log('Activity:', activitySlots.uuid);
    console.log('Slots:', activitySlots.slots?.length);
    console.log('Next available:', activitySlots.nextAvailableDate);
  });
}

getCartTimeSlots

Get time slots that account for items already in the active cart.

const cartSlots = await api.timeslots.getCartTimeSlots({
  date: '2025-07-15',
  durationMins: 60
});

TimeSlotRequest

FieldTypeRequiredDescription
datestringYesDate in YYYY-MM-DD format
activitystringNoActivity UUID (recommended for activity-specific queries)
durationstringNoDuration UUID
durationMinsnumberNoDuration in minutes (for dynamic durations)
equipmentClientShoppingCartEquipment[]NoEquipment selection to check availability against
isPrivateTourbooleanNoFilter for private tour availability
ignoreEarlyCutoffbooleanNoIgnore early booking cutoff rules

ActivityTimeSlotsResponse

Returned by getActivityTimeSlots and getCartTimeSlots.

FieldTypeDescription
successbooleanWhether the request succeeded
timeSlotsActivityTimeSlot[]Available time slots

LocationTimeSlotsResponse

Returned by getLocationTimeSlots.

FieldTypeDescription
successbooleanWhether the request succeeded
resultsLocationAllActivityTimeSlots[]Slots grouped by activity

ActivityTimeSlot

FieldTypeDescription
startDateDateSlot start (full datetime)
endDateDateSlot end (full datetime)
durationMinutesnumberSlot length in minutes
pricenumberPrice for this time slot
isAvailablebooleanWhether this slot can be booked
remainingSeatsnumberNumber of seats still available (tour activities)
canBookPrivateTourbooleanWhether a private tour can be booked at this time
blackoutMessagestringOperator-supplied reason the slot is unavailable, populated only when a location blackout blocks the slot. Activity-level blackouts do not surface a message.

LocationAllActivityTimeSlots

FieldTypeDescription
uuidstringActivity UUID
slotsActivityTimeSlot[]Available slots for this activity
nextAvailableDatestringNext date with availability (if no slots on requested date)

Add-ons

getEligibleAddons

Retrieve add-ons that are available for a given activity, date, and time combination.

const addons = await api.addon.getEligibleAddons({
  activity: 'activity-uuid',
  date: '2025-07-15',
  time: '10:00'
});

if (addons.success) {
  addons.addons.forEach(addon => {
    console.log(`${addon.name} - $${addon.price} (${addon.quantity} available)`);
  });
}

GetEligibleAddonsRequest

FieldTypeRequiredDescription
activitystringYesActivity UUID
datestringYesDate in YYYY-MM-DD format
timestringYesTime in HH:mm format
durationstringNoDuration UUID
dynamicDurationMinutesnumberNoDuration in minutes (for dynamic durations)
equipmentClientShoppingCartEquipment[]NoEquipment selection for context

GetEligibleAddonsResponse

FieldTypeDescription
successbooleanWhether the request succeeded
addonsEligibleAddon[]List of eligible add-ons

EligibleAddon

FieldTypeDescription
uuidstringAdd-on identifier
namestringDisplay name
descriptionstringDescription
pricenumberPrice per unit
quantitynumberAvailable quantity
mediaUristringImage URL

Full Example: Browse to Book

This example walks through the complete read-side flow: list activities, check the calendar, get time slots, and discover add-ons.

const api = new ResytechApi({ debug: true });

// 1. Initialize and get available activities
const init = await api.initialization.initialize({
  identifier: 'booking-session'
});

if (!init.success) {
  console.error('Init failed:', init.message);
  return;
}

const activities = init.activities;
console.log(`Found ${activities.length} activities`);

// 2. Get full details for the first activity
const activityUuid = activities[0].uuid;
const activityResult = await api.activity.getActivity(activityUuid);
const activity = activityResult.activity;

console.log(`${activity.name} - ${activity.durations.length} durations available`);
console.log(`Equipment: ${activity.equipment.map(e => e.name).join(', ')}`);

// 3. Check calendar for next month
const now = new Date();
const nextMonth = now.getMonth() + 2; // getMonth() is 0-indexed, API is 1-indexed
const year = nextMonth > 12 ? now.getFullYear() + 1 : now.getFullYear();
const month = nextMonth > 12 ? 1 : nextMonth;

const calendar = await api.calendar.getActivityCalendar({
  activity: activityUuid,
  month: month,
  year: year,
  includePrices: true,
  duration: activity.durations[0]?.uuid
});

if (!calendar.success) {
  console.error('Calendar failed:', calendar.message);
  return;
}

// Find the first available date
const availableDay = calendar.calendar.days.find(d => d.isAvailable);
if (!availableDay) {
  console.log('No availability this month');
  return;
}

console.log(`First available: ${availableDay.date} at $${availableDay.price}`);

// 4. Get time slots for that date
const slots = await api.timeslots.getActivityTimeSlots({
  activity: activityUuid,
  date: availableDay.date,
  duration: activity.durations[0]?.uuid
});

if (!slots.success || !slots.timeSlots?.length) {
  console.log('No slots available');
  return;
}

console.log(`${slots.timeSlots.length} time slots available`);
const firstSlot = slots.timeSlots[0];
console.log(`First slot: $${firstSlot.price}, ${firstSlot.remainingSeats} seats`);

// 5. Check for eligible add-ons
const addons = await api.addon.getEligibleAddons({
  activity: activityUuid,
  date: availableDay.date,
  time: '10:00',
  duration: activity.durations[0]?.uuid
});

if (addons.success && addons.addons?.length) {
  console.log('Available add-ons:');
  addons.addons.forEach(a => console.log(`  ${a.name}: $${a.price}`));
}

// Ready to build a cart! See the Cart & Checkout guide.

On this page