Booking frame

Use the booking frame to easily integrate Trybe into your existing booking flow.

With the booking frame, you can provide your guests with a smooth experience for booking treatments and packages without having to worry about the frontend.

Summary

The booking frame works in the following way:

  1. Creating a Booking Frame Session

    You make a request to our API to create a booking frame session, providing us with the date range and the number of guests.

    In the response, we'll generate you a URL.

  2. Present an iframe

    You present an iframe with the source as the generated URL.

  3. Guest uses booking frame

    The guest uses the Trybe booking frame to check availability, book treatments, and configure packages for their stay.

  4. Handle when the user is finished

    When the user has finished booking, they'll click a call to action within the booking frame which triggers a postMessage on the parent document.

  5. Submit the basket

    When you're ready, submit the basket to confirm the guest's choices.

  6. Record payment (optional)

    If you've captured a payment, make an additional request to our API to record this.

Authentication

To make requests to the API, you need to authenticate. There are two methods of authentication required for the different endpoints you'll be using:

  • booking-frame endpoints

    Pass a partner_id in the request to create your booking frame session. Get in touch with us to request a partner ID.

  • shop endpoints

    Generate an API key from the Developer settings page in Trybe and pass this as a Bearer token.

Base URL

When using the BookingFrameApi, the base URL of the API is specific to the site. You can see the URL for a site by heading to Shop Settings within Trybe.

Code samples

Use the following code samples for examples on how to integrate the booking frame into your application.

Creating a Booking Frame Session

Here's an example cURL request to create a booking frame session for 2 guests at Palm Tree Spa. The guests will be able to book treatments between 1st April 2023 to 3rd April 2023 inclusive. All treatments that are available for the given dates will be offered to the guest.

curl --request POST \
  --url https://palmtreespa.try.be/booking-frame/create \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2
}'

You can use the reservation_id to store your own reference against this booking frame session.

In the response, we'll send a JSON encoded url back. This is the URL to use to present an iframe to the user.

...
"url": "https:\/\/palmtreespa.try.be\/booking-frame\/6419a5ff5faebc72af0529a3",
...

Theming

The booking frame supports basic theming to create a consistent look and feel with your application.

We support customising the following values:

  • accent_color The accent colour is used as the background colour for some buttons and links.
  • accent_text_color The accent text colour is the text colour used for text placed over the accent colour background.

Send these values as a hex colour code under the theme property when creating a new booking frame session. Here's an example payload:

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "theme": {
      "accent_color": "#9999ff",
      "accent_text_color": "#ffffff"
    }
}

Only show specific treatments

If you want the user to only be able to pick from a specific range of treatments, you can pass the offering IDs when creating the booking frame session using the allowed_offering_ids field.

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "allowed_offering_ids": [
        "5e932c0901d210625e3a8766",
        "5e932c0901d210625e3a8767"
    ]
}

With the given payload, only two offerings will be available to choose from.

Similarly, you can use the disallowed_offering_ids field to exclude specific offerings.

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "disallowed_offering_ids": [
        "5e932c0901d210625e3a8766",
        "5e932c0901d210625e3a8767"
    ]
}

This payload will generate a booking frame session where the guest can choose from any offering except the ones specified.

Hiding prices

In some cases, you may not want the guest to see prices of the treatments; for example if the guest is buying an overnight package where the price includes one spa treatment.

To hide all the prices from the guest, use the hide_prices field.

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "hide_prices": true
}

Hiding prices for specific offerings

Sometimes you might want to offer the guest one or more specific treatments or packages within Trybe where the price is already included in your rate, but also give the guest flexibility to book more treatments at an additional cost.

For example, if the guest is booking a "Stay and Spa" rate in your application which includes a room and a specific treatment, but they are also free to book additional treatments on top of this.

With the included_offering_ids field, you can specify which offerings are "included", and should therefore display their price as zero on the booking frame. We'll display the value in the currency of the site, so if the site has GBP as the default currency, the price of the offering will display as "£0.00".

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "included_offering_ids": [
        "5e932c0901d210625e471af1"
    ]
}

Please note, the Basket response will still show the full price of the item in order for the revenue to be associated in Trybe.

Configure only mode

You can create a booking frame session which only allows the guest to configure an item already in the basket, and it removes the ability for them to pick an offering.

This can be useful if you want the guest to pick a package from your own application, but you don't want to deal with the complexities of configuring the package in your application. Or if you only want to offer a specific package to the guest, and you've already made it clear to the guest in your flow that they're booking a specific offering.

To use this, pass the configure_only field when creating the booking frame session:

{
    "partner_id": "INSERT_YOUR_PARTNER_ID",
    "reservation_id": "12345",
    "date_from": "2023-04-01",
    "date_to": "2023-04-03",
    "num_guests": 2,
    "configure_only": true
}

Then, use the API to programatically add an item to the basket. You can retrieve the basket ID and guest IDs from the response of the previous API request. Here's an example cURL request to add an item to the basket. Make sure you replace the IDs with ones relevant to your use case, and provide a valid Bearer token for authentication.

curl --request POST \
  --url https://api.try.be/shop/basket/5e932c0901d210625e3a8766/items \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer INSERT_YOUR_BEARER_TOKEN' \
  --data '{
    "offering_id": "5e932c0901d210625e471af1",
    "offering_type": "package",
    "date": "2023-04-01",
    "guest_id": "5e932c0901d210625e471af2",
}'

Now, when the booking frame is presented, the guest will only be able to configure the item in the basket. They won't be able to pick a different offering, nor remove the offering.

Present an iframe

Once you've created the booking frame session, you can present the booking frame to the guest by embedding an iframe on your page.

Here's an example of how you could acheive this in plain JavaScript:

const bookingFrameUrl = bookingFrameResponse.data.url
const iframe = document.createElement('iframe')

iframe.src = bookingFrameUrl

document.body.appendChild(iframe)

Sizing

The booking frame is responsive and has been engineered with small screens in mind. For the best mobile experience, we strongly recommend that the iframe is sized to fill the width and height of the viewport.

Handle when the user is finished

When the user has finished configuring their order, they'll click the "Continue" CTA button. This will trigger a postMessage event to be sent to the parent window with the following payload:

{
  "type": "trybeBookingFrameComplete",
  "reservationId": "12345"
}

The reservationId will match what you provided when creating the booking frame session.

You should add an event listener to this event, and use it to close the iframe and continue with your flow.

Here's an example of how you could do this in plain JavaScript:

window.addEventListener('message', function (event) {
  if (event.data.type === 'trybeBookingFrameComplete') {
    // Close the iframe
    // Continue with your flow
  }
})

Submit the basket

Once the guest has finished configuring their order, you'll need to "submit" the basket. This is what confirms the order in Trybe and schedules it with the relevant practitioner/room/area.

To do this, you'll need to make a POST request to the /shop/orders/{basketId}/submit endpoint. Make sure you replace the basket ID with one relevant to your use case, and provide a valid Bearer token for authentication.

curl --request POST \
  --url https://api.try.be/shop/orders/5e932c0901d210625e3a8766/submit \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer INSERT_YOUR_BEARER_TOKEN'

Record payment (optional)

If you've taken payment for the order within your application and want to record this in Trybe, make a POST request to the /shop/orders/{basketId}/payments endpoint.

Pass the amount as an integer of the smallest unit of currency. For example, if you've taken £100.00, pass 10000. No need to pass the currency code - it's derived from the Site's configuration.

curl --request POST \
  --url https://api.try.be/shop/orders/5e932c0901d210625e3a8766/submit \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer INSERT_YOUR_BEARER_TOKEN' \
  --data '{
    "amount": 10000,
    "processor": "partner"
  }'

Analytics

If you've configured your booking frame to connect to your Google Tag Manager container, the following events will be pushed to the data layer for you to track user behaviour:

Event name Description Metadata
date_changed When the date is changed date
guest_changed When the guest is changed guest_number
offering_selected When any offering on the list is clicked offering_name offering_id guest_number
booking_frame_complete When the guest clicks the Finish CTA button
offering_closed When the guest clicks the X after selecting an offering to return to the list guest_number
arrival_time_picked When an arrival time is picked for non-package offerings arrival_time guest_number
item_removed When the guest removes an added item from their basket item_id item_name
package_choice_selected When the guest is configuring a package, this will be fired when a choice is made. If the choice requires a timeslot, this event will be fired after the time has been picked. choice_number option_number guest_number
package_choice_showing_time_picker When the guest is configuring a package, this will be fired when an option is selected that requires a time selection choice_number option_number guest_number
package_configured When the guest is configuring a package, this will be fired once all their choices have been made guest_number
package_choice_changed When the guest is configuring a package, this will be fired if they click "Change" for a choice choice_number guest_number

When an event contains metadata, the following conventions will be used:

  • guest_number, choice_number and option_number start from 1, not 0.
  • Any dates are formatted as a Y-m-d string, ie 2023-08-25
  • Any times are formatted as an H:i string, ie 16:20