# Activities, Calendar & Timeslots (/developers/activities)



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](/developers/resytech-api):

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

Activities [#activities]

getActivity [#getactivity]

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

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

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

**Parameters**

| Parameter | Type     | Required | Description                |
| --------- | -------- | -------- | -------------------------- |
| `uuid`    | `string` | Yes      | Activity unique identifier |

**ActivityResponse**

| Field      | Type       | Description                       |
| ---------- | ---------- | --------------------------------- |
| `success`  | `boolean`  | Whether the request succeeded     |
| `activity` | `Activity` | Full activity details (see below) |

Activity Type [#activity-type]

| Field                     | Type                             | Description                                         |
| ------------------------- | -------------------------------- | --------------------------------------------------- |
| `uuid`                    | `string`                         | Unique identifier                                   |
| `name`                    | `string`                         | Display name                                        |
| `basePrice`               | `number`                         | Base price in cents                                 |
| `description`             | `string`                         | Full description                                    |
| `cancellationPolicy`      | `string`                         | Cancellation policy text                            |
| `details`                 | `string`                         | Additional details                                  |
| `media`                   | `Media[]`                        | Images and videos                                   |
| `durations`               | `Duration[]`                     | Available booking durations                         |
| `equipment`               | `Equipment[]`                    | Available equipment (boats, kayaks, etc.)           |
| `manifest`                | `Manifest`                       | Guest limits, age restrictions, demographics        |
| `firstAvailableDate`      | `Date`                           | Earliest bookable date                              |
| `allowEquipmentMixing`    | `boolean`                        | Whether customers can book multiple equipment types |
| `maxEquipmentPerBooking`  | `number`                         | Max equipment items per booking                     |
| `customFields`            | `CustomField[]`                  | Custom form fields for checkout                     |
| `agreements`              | `ActivityAgreement[]`            | Agreements the customer must accept                 |
| `type`                    | `number`                         | Activity type identifier                            |
| `allowPrivateTours`       | `boolean`                        | Whether private tours are available                 |
| `dynamicDurationSettings` | `ActivityDynamicDurationSetting` | Dynamic duration config                             |
| `scheduling`              | `ActivityScheduling`             | Date range and cutoff settings                      |
| `tripProtection`          | `TripProtection`                 | Trip protection configuration                       |

Supporting Types [#supporting-types]

**Duration**

| Field     | Type     | Description                                          |
| --------- | -------- | ---------------------------------------------------- |
| `uuid`    | `string` | Duration identifier (pass to cart/calendar requests) |
| `minutes` | `number` | Duration length in minutes                           |

**Equipment**

| Field         | Type                  | Description                              |
| ------------- | --------------------- | ---------------------------------------- |
| `uuid`        | `string`              | Equipment identifier                     |
| `name`        | `string`              | Display name                             |
| `description` | `string`              | Short description                        |
| `details`     | `string`              | Detailed info                            |
| `quantity`    | `number`              | Total inventory                          |
| `capacity`    | `number`              | Seats per unit                           |
| `media`       | `Media[]`             | Images                                   |
| `addons`      | `Addon[]`             | Equipment-specific add-ons               |
| `amenities`   | `Amenity[]`           | Equipment amenities                      |
| `properties`  | `EquipmentProperty[]` | Custom properties (e.g., length, weight) |

**Manifest**

| Field            | Type            | Description                                 |
| ---------------- | --------------- | ------------------------------------------- |
| `guestLimit`     | `number`        | Maximum guests per booking                  |
| `ageRestriction` | `number`        | Minimum age                                 |
| `guestMinimum`   | `number`        | Minimum guests per booking                  |
| `demographics`   | `Demographic[]` | Guest demographics (adults, children, etc.) |

**Media**

| Field          | Type     | Description                     |
| -------------- | -------- | ------------------------------- |
| `uuid`         | `string` | Media identifier                |
| `order`        | `number` | Display order                   |
| `type`         | `number` | Media type (image, video, etc.) |
| `uri`          | `string` | Full-size URL                   |
| `thumbnailUri` | `string` | Thumbnail URL                   |

***

Calendar [#calendar]

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

getActivityCalendar [#getactivitycalendar]

Get availability for a specific activity in a given month.

```javascript
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 [#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.

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

ActivityCalendarRequest [#activitycalendarrequest]

| Field           | Type                            | Required | Description                                 |
| --------------- | ------------------------------- | -------- | ------------------------------------------- |
| `activity`      | `string`                        | Yes      | Activity UUID                               |
| `month`         | `number`                        | Yes      | Month (1-12)                                |
| `year`          | `number`                        | Yes      | Year (e.g. 2025)                            |
| `includePrices` | `boolean`                       | No       | Include per-day pricing                     |
| `duration`      | `string`                        | No       | Duration UUID to filter by                  |
| `startTime`     | `string`                        | No       | Filter by start time                        |
| `equipment`     | `ClientShoppingCartEquipment[]` | No       | Equipment selection to check against        |
| `durationMins`  | `number`                        | No       | Duration in minutes (for dynamic durations) |
| `cartId`        | `string`                        | No       | Cart ID (used by `getCartCalendar`)         |

CalendarResponse [#calendarresponse]

| Field      | Type            | Description                        |
| ---------- | --------------- | ---------------------------------- |
| `success`  | `boolean`       | Whether the request succeeded      |
| `calendar` | `CalendarMonth` | Month data with daily availability |

CalendarMonth [#calendarmonth]

| Field   | Type                    | Description          |
| ------- | ----------------------- | -------------------- |
| `month` | `number`                | Month number (1-12)  |
| `year`  | `number`                | Year                 |
| `days`  | `ActivityCalendarDay[]` | Array of day objects |

ActivityCalendarDay [#activitycalendarday]

| Field              | Type      | Description                                                 |
| ------------------ | --------- | ----------------------------------------------------------- |
| `date`             | `string`  | Date string (YYYY-MM-DD)                                    |
| `isAvailable`      | `boolean` | Whether there is availability on this day                   |
| `price`            | `number`  | Starting price for this day (if `includePrices` was `true`) |
| `isEstimatedPrice` | `boolean` | Whether the price is an estimate                            |
| `blackoutMessage`  | `string`  | Reason the day is blacked out (if applicable)               |

***

Time Slots [#time-slots]

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

getActivityTimeSlots [#getactivitytimeslots]

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

```javascript
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 [#getlocationtimeslots]

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

```javascript
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 [#getcarttimeslots]

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

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

TimeSlotRequest [#timeslotrequest]

| Field               | Type                            | Required | Description                                               |
| ------------------- | ------------------------------- | -------- | --------------------------------------------------------- |
| `date`              | `string`                        | Yes      | Date in YYYY-MM-DD format                                 |
| `activity`          | `string`                        | No       | Activity UUID (recommended for activity-specific queries) |
| `duration`          | `string`                        | No       | Duration UUID                                             |
| `durationMins`      | `number`                        | No       | Duration in minutes (for dynamic durations)               |
| `equipment`         | `ClientShoppingCartEquipment[]` | No       | Equipment selection to check availability against         |
| `isPrivateTour`     | `boolean`                       | No       | Filter for private tour availability                      |
| `ignoreEarlyCutoff` | `boolean`                       | No       | Ignore early booking cutoff rules                         |

ActivityTimeSlotsResponse [#activitytimeslotsresponse]

Returned by `getActivityTimeSlots` and `getCartTimeSlots`.

| Field       | Type                 | Description                   |
| ----------- | -------------------- | ----------------------------- |
| `success`   | `boolean`            | Whether the request succeeded |
| `timeSlots` | `ActivityTimeSlot[]` | Available time slots          |

LocationTimeSlotsResponse [#locationtimeslotsresponse]

Returned by `getLocationTimeSlots`.

| Field     | Type                             | Description                   |
| --------- | -------------------------------- | ----------------------------- |
| `success` | `boolean`                        | Whether the request succeeded |
| `results` | `LocationAllActivityTimeSlots[]` | Slots grouped by activity     |

ActivityTimeSlot [#activitytimeslot]

| Field                | Type      | Description                                       |
| -------------------- | --------- | ------------------------------------------------- |
| `price`              | `number`  | Price for this time slot                          |
| `remainingSeats`     | `number`  | Number of seats still available                   |
| `canBookPrivateTour` | `boolean` | Whether a private tour can be booked at this time |

LocationAllActivityTimeSlots [#locationallactivitytimeslots]

| Field               | Type                 | Description                                                 |
| ------------------- | -------------------- | ----------------------------------------------------------- |
| `uuid`              | `string`             | Activity UUID                                               |
| `slots`             | `ActivityTimeSlot[]` | Available slots for this activity                           |
| `nextAvailableDate` | `string`             | Next date with availability (if no slots on requested date) |

***

Add-ons [#add-ons]

getEligibleAddons [#geteligibleaddons]

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

```javascript
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 [#geteligibleaddonsrequest]

| Field                    | Type                            | Required | Description                                 |
| ------------------------ | ------------------------------- | -------- | ------------------------------------------- |
| `activity`               | `string`                        | Yes      | Activity UUID                               |
| `date`                   | `string`                        | Yes      | Date in YYYY-MM-DD format                   |
| `time`                   | `string`                        | Yes      | Time in HH:mm format                        |
| `duration`               | `string`                        | No       | Duration UUID                               |
| `dynamicDurationMinutes` | `number`                        | No       | Duration in minutes (for dynamic durations) |
| `equipment`              | `ClientShoppingCartEquipment[]` | No       | Equipment selection for context             |

GetEligibleAddonsResponse [#geteligibleaddonsresponse]

| Field     | Type              | Description                   |
| --------- | ----------------- | ----------------------------- |
| `success` | `boolean`         | Whether the request succeeded |
| `addons`  | `EligibleAddon[]` | List of eligible add-ons      |

EligibleAddon [#eligibleaddon]

| Field         | Type     | Description        |
| ------------- | -------- | ------------------ |
| `uuid`        | `string` | Add-on identifier  |
| `name`        | `string` | Display name       |
| `description` | `string` | Description        |
| `price`       | `number` | Price per unit     |
| `quantity`    | `number` | Available quantity |
| `mediaUri`    | `string` | Image URL          |

***

Full Example: Browse to Book [#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.

```javascript
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.
```
