Tutorial: How to Structure Real-Time Updates

Use Cases for Real-Time Updates

Real-Time Updates should always be issued in the following scenarios:

  • When a user books a reservation on your system and the availability slot is no longer available.
  • When a user cancels a reservation on your system, and the slot becomes available.
  • When a user books a reservation through Reserve with Google and the availability slot is no longer available.
  • When a reservation made through Reserve with Google is cancelled on your side, for example, by the merchant directly. You will need to update the booking as well as the availability because the original slot is now available again.
  • When a merchant changes their schedule (availability) on your system
  • When a booking server CheckAvailability call returns inventory that does not match the actual inventory

Not all Maps Booking API calls are required. The following are mandatory:

  • BookingNotification.UpdateBooking
  • InventoryUpdate.ReplaceServiceAvailability or InventoryUpdate.BatchServiceAvailability

Real-Time Updates: replace

There are two types of replace methods available:

  • Batch Replace (InventoryUpdate.BatchServiceAvailability): Completely replaces the availability data for a merchant and multiple services.
    • Note: This batch call does not guarantee atomicity. Only successfully updated availability slots will be returned.
  • Single Replace (InventoryUpdate.ReplaceServiceAvailability): Completely replaces the availability for a single merchant and service.

Please use the following reference guide for more details.

Real-time updates must use the same availability structure as the data that are sent through feeds. They must use one of:

  • Spots Open
  • Recurrence

Please reference the availability structure guide to determine which format is better for you.

Choosing a Replace Method to Call

Use the following guide to help you determine which replace method is more suitable:

  • Are multiple services impacted with a single booking? For example, a haircut and coloring (each is a distinct Service) is booked with a stylist, so all services tied to the stylist for that time slot should be removed.
  • Are all downstream effects to services immediately transparent to you regarding a booking?
  • None of these apply?
    • Single Replace
    • Note: You can use multiple single replace calls to emulate a batch replace call, but it would be more efficient to use a single batch replace call

Real-Time Updates: Spots Open Format

It is important to use the same format across the feeds, booking server, and real-time updates.

A Spots Open feed snippet looks like:

Feed Snippet

   "availability": [
          {
            "merchant_id": "1001",
            "service_id": "12310",
            "spots_open": 2,
            "spots_total": 2,
            "start_sec": 1412263800, # October 02, 2014 15:30:00
            "duration_sec": 1800,
            "availabilityTag": "1000001"
          }
    ]

For the Inventory Update API, the replace request body format for when a 3:30 PM slot gets booked:

Replace Real-Time Updates Snippet

  {
    "extendedServiceAvailability": [
      {
        "merchantId": "1001",
        "serviceId": "12310",
        "startTimeRestrict": "2014-10-02T15:01:23.045123456Z",
        "endTimeRestrict": "2014-10-02T19:01:23.045123456Z",
        "availability": [
          {
            "startTime": "2014-10-02T15:30:00.00Z",
            "duration": "3600",
            "spotsOpen": "1",
            "spotsTotal": "2",
            "availabilityTag": "1000001"
          }
        ]
      }
    ]
  }

However, when there is no more availability left (spots_open is 0), there are 2 formats of sending the replace request for the Inventory API.

  • Explicit specification: This is the recommended method if you have spots_total > 1
  {
    "extendedServiceAvailability": [
      {
        "merchantId": "1001",
        "serviceId": "12310",
        "startTimeRestrict": "2014-10-02T15:01:23.045123456Z",
        "endTimeRestrict": "2014-10-02T19:01:23.045123456Z",
        "availability": [
          {
            "startTime": "2014-10-02T15:30:00.00Z",
            "duration": "3600",
            "spotsOpen": "0",
            "spotsTotal": "2",
            "availabilityTag": "1000001"
          }
        ]
      }
    ]
  }
  • Empty specification: This is recommended only if spots_total = 1 for most merchants and services.
  {
  "extendedServiceAvailability": [
    {
      "merchantId": "1001",
      "serviceId": "12310",
      "startTimeRestrict": "2014-10-02T15:01:23.045123456Z",
      "endTimeRestrict": "2014-10-02T19:01:23.045123456Z",
      "availability": [
        {}
      ]
    }
  ]
}

Here's an example of what we expect in the next daily feed, if a new slot at 3:30 PM gets booked:

Feed Snippet

"availability": [
        {
          "merchant_id": "1001",
          "service_id": "12310",
          "spots_open": 1,
          "spots_total": 2,
          "start_sec": 1412263800, # October 02, 2014 15:30:00
          "duration_sec": 1800,
          "availabilityTag": "1000001"
        }
      ]

Real-Time Updates: Recurrence Format

It is important to use the same format across the feeds, booking server, and real-time updates.

A feed that uses recurrence looks like:

Feed Snippet

  "availability": [
        {
          "merchant_id": "1001",
          "service_id": "12310",
          "spots_open": 1,
          "spots_total": 1,
          "start_sec": 1540890000, # October 30, 2018 9:00:00 AM
          "duration_sec": 1800,
          "recurrence": {
            "repeat_every_sec": 1800,
            "repeat_until_sec": 1540918800 # October 30, 2018 5:00:00 PM
          },
          "schedule_exception": [
            {
              "time_range": {
                "begin_sec": 1540902600, # October 30, 2018 12:30:00 PM
                "end_sec": 1540904400 # October 30, 2018 1:00:00 PM
              }
            }
          ],
        }
      ]

For the Inventory Update API, the replace request body format for when a 3:30 PM slot gets booked, looks like:

  {
    "extendedServiceAvailability": [
      {
        "merchantId": "1001",
        "serviceId": "12310",
        "startTimeRestrict": "2018-10-30T15:01:23.045123456Z",
        "endTimeRestrict": "2018-10-30T19:01:23.045123456Z",
        "availability": [
          {
            "startTime": "2018-10-30T15:30:00.00Z",
            "duration": "3600",
            "spotsOpen": "1",
            "scheduleException": [
             {
                "timeRange": {
                  "startTime": "2018-10-30T12:30:00.00Z",
                  "endTime": "2018-10-30T13:00:00.00Z"
                }
              },
              {
                "timeRange": {
                  "startTime": "2018-10-30T15:30:00.00Z",
                  "endTime": "2018-10-30T16:00:00.00Z"
                }
              }
            ]
          }
        ]
      }
    ]
  }

Here's an example of what is expected in the next daily feed. Notice that it is the entire service's availability for that merchant, and all of its previous and new schedule_exceptions:

Feed Snippet

   "availability": [
        {
          "merchant_id": "1001",
          "service_id": "12310",
          "spots_open": 1,
          "spots_total": 1,
          "start_sec": 1540890000, # October 30, 2018 9:00:00 AM
          "duration_sec": 1800,
          "recurrence": {
            "repeat_every_sec": 1800,
            "repeat_until_sec": 1540918800 # October 30, 2018 5:00:00 PM
          },
          "schedule_exception": [
            {
              "time_range": {
                "begin_sec": 1540902600, # October 30, 2018 12:30:00 PM
                "end_sec": 1540904400 # October 30, 2018 1:00:00 PM
              }
            },
            {
              "time_range": {
                "begin_sec": 1540913400, # October 30, 2018 3:30:00 PM
                "end_sec": 1540915200 # October 30, 2018 4:00:00 PM
              }
            }
          ],
        }
      ]

When to Submit Real-Time Updates

Real-time updates should be sent continuously whenever availability changes. This is in addition to a comprehensive availability feed that should be submitted once daily, in order to ensure that availability is synchronized between your and Google's systems.