Creating a new booking

Creating a new booking via the Appointedd API.

Creating a new booking in Appointedd is a three step process which has been designed to prevent the possibility of double bookings being made. This process involves:

  1. Finding a date and time that one of your resources would be available for a new booking.
  2. Creating a new availability slot, which reserves the date and time for your new booking for a preset number of minutes.
  3. Converting the availability slot you created in the previous step into your new booking.

πŸ“˜

Adding a customer booking on a group booking

From our API's perspective, booking a customer onto a group booking is no different from creating a "new" booking. The only difference is that you might be able to skip the Finding an available date and time step if you already have the service ID, resource ID, and start time of the group booking you want to use. If you do not care if the result is a new booking or a booking on an available existing group booking, or if you service schedule is set up to restrict bookings to only open, available existing group bookings then you can simply follow this guide with no changes.

Preparing your requests

Let's setup the basic options we'll use for all of our HTTP requests to the Appointedd API, as well as set the ID of the resource and service we'll be making a booking for in this tutorial so we can easily reference them later.

const axios = require("axios").default;

// ID of a resource in your organisation.
const RESOURCE_ID = "<YOUR_RESOURCE_ID>";
// ID of a service in your organisation.
const SERVICE_ID = "<YOUR_SERVICE_ID>";

const request = axios.create({
  baseURL: "https://api.appointedd.com/v1/",
  headers: {
    "X-API-KEY": "<YOUR_API_KEY>",
  },
});

Finding an available date and time

To find a date and time that one of your resources would be available for your new booking you'll want to send a request to the POST https://api.appointedd.com/v1/availability/intervals/search endpoint.

πŸ“˜

Increments

By default your organisation's calendar in Appointedd is set to a certain "increment". This means that available times will be shown rounded to the a number that is divisible by your organisation's increment.

For example if your organisation's increment is set to 15 minutes then your availability will be rounded to:

  • 2022-01-01T15:00:00.000Z
  • 2022-01-01T15:15:00.000Z
  • 2022-01-01T15:30:00.000Z
  • 2022-01-01T15:45:00.000Z
  • 2022-01-01T16:00:00.000Z

You can pass a custom increment in using the increment property in your request but we do not recommend this as if you create a booking at, for example, 2022-01-01T15:01:00.000Z by passing an increment value of 1 it will not display on your organisation unless the increment setting is also set to 1 minute.

You can manage your organisation's increment setting on this page using the Calendar interval increments setting: https://app.appointedd.com/management/settings

const findAvailableStartDateTime = async () => {
  // Find and available date and time to create a booking for a specific
  // service with a resource in your organisation.
  const availabilityResponse = await request.post(
    "/availability/intervals/search",
    {
      ranges: [
        {
          start: "2021-01-01T00:00:00.000Z",
          end: "2021-02-01T00:00:00.000Z",
        },
      ],
      resource_ids: [RESOURCE_ID],
      service_id: SERVICE_ID,
    }
  );

  return availabilityResponse.data.data[0].start;
};

Creating a new availability slot

To create a new availability slot you'll want to send a request to the POST /availability/slots endpoint. You should use a start date and time that you received from the availability request that you made in the previous section. If you don't, this will result in an error as there will not be any availability to reserve your new booking!

const createAvailabilitySlot = async (start) => {
  const availabilitySlotResponse = await request.post("/availability/slots", {
    data: {
      resource_id: RESOURCE_ID,
      service_id: SERVICE_ID,
      start,
    },
  });

  return { id: availabilitySlotResponse.data.data.id };
};

This will reserve date and time for your new booking for a preset number of minutes which can be configured in your organisation's Time for which a booking time is reserved setting, which you can find in your organisation's online booking settings.

By default the duration of the booking will be your service's default duration (if you have more than one, otherwise it'll simply be the service's duration). You can optionally pass a duration property in the data property of your request to specify a specific duration in minutes on your service to use.

πŸ“˜

Why availability slots?

In most booking flows there is a delay between a customer selecting the date and time that they want to book and completing their booking details. This delay increases the more complex your booking flow is, for example if you have multiple booking questions in your flow. This delay could mean that another customer that selects the same date and time and completes the booking flow first could steal that date and time and prevent the first customer from finishing their booking flow.

If you do not require any delay to fill in you booking details, for example in an internal tool, you can simply consume the availability slot instantly by making POST /bookings call after you receive your new availability slot.

Creating a new booking

Finally in order to convert that availability slot into a booking you'll want to send a request to the POST /bookings endpoint. In this step you'll also add the details of the customer that is creating this booking.

const createBooking = async (slotId) => {
  const bookingResponse = await request.post("/bookings", {
    slot_id: slotId,
    data: {
      customer: {
        profile: {
          firstname: "Ada",
          lastname: "Lovelace",
          email: "[email protected]",
        },
      },
    },
  });

  return { id: bookingResponse.data.data.id };
};

πŸ“˜

Availability slots are single use

You can only use an availability slot once. To create another booking you'll need to create another availability slot for that booking.

Putting it all together

Let's tie everything in the previous sections into something you can run.

// README:
// 1. Save this to a file called `index.js`.
// 2. Fill out details in square brackets (<>).
// 3. Run `npm install axios` in the same directory.
// 4. Run `node index.js` in the same directory.

const axios = require("axios").default;

// ID of a resource in your organisation.
const RESOURCE_ID = "<YOUR_RESOURCE_ID>";
// ID of a service in your organisation.
const SERVICE_ID = "<YOUR_SERVICE_ID>";

const request = axios.create({
  baseURL: "https://api.appointedd.com/v1/",
  headers: {
    "X-API-KEY": "<YOUR_API_KEY>",
  },
});

const findAvailableStartDateTime = async () => {
  // Find and available date and time to create a booking for a specific
  // service with a resource in your organisation.
  const availabilityResponse = await request.post(
    "/availability/intervals/search",
    {
      data: {
        ranges: [
          {
            start: "2021-01-01T00:00:00.000Z",
            end: "2021-02-01T00:00:00.000Z",
          },
        ],
        resource_ids: [RESOURCE_ID],
        service_id: SERVICE_ID,
      },
    }
  );

  return availabilityResponse.data.data[0].start;
};

const createAvailabilitySlot = async (start) => {
  const availabilitySlotResponse = await request.post("/availability/slots", {
    data: {
      data: {
        resource_id: RESOURCE_ID,
        service_id: SERVICE_ID,
        start,
      },
    },
  });

  return { id: availabilitySlotResponse.data.data.id };
};

const createBooking = async (slotId) => {
  const bookingResponse = await request.post("/bookings", {
    data: {
      slot_id: slotId,
      data: {
        customer: {
          profile: {
            firstname: "Ada",
            lastname: "Lovelace",
            email: "[email protected]",
          },
        },
      },
    },
  });

  return { id: bookingResponse.data.data.id };
};

const main = async () => {
  const start = await findAvailableStartDateTime();

  console.log(`Found available start date & time at: ${start}`);

  const slot = await createAvailabilitySlot(start);

  console.log(`Created availability slot with ID: ${slot.id}`);

  const booking = await createBooking(slot.id);

  console.log(`Created booking with ID: ${booking.id}`);
};

main()
  .then(() => process.exit(0))
  .catch((err) => {
    console.error(err);
    process.exit(-1);
  });