Structuring Real-Time Updates

Use Cases for Real-Time Updates

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

  • When a user cancels a reservation on your system, and the slot becomes available.
  • When a user books a reservation through the Actions Center and the availability slot is no longer available.
  • When a reservation made through the Actions Center 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.

Additionally, if you implement Availability Replace RTU, Real-Time Updates should be issued in the following scenarios:

  • When a merchant changes their schedule (availability) on your system.
  • When a user books a reservation on your system and the availability slot is no longer available.
  • If you are using a legacy integration with CheckAvailability, 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:

Depending on the type of integration the following might also be available or required:

Update Booking RTU

In the event that an update has been made to an Actions Center booking (e.g. canceled or modified) on your system, a notification.partners.bookings.patch (BookingNotification.UpdateBooking) must be sent.

Modifiable Fields

  • status
  • startTime
  • duration
  • partySize
  • paymentInformation.prepaymentStatus

Cancellation example

Request:
PATCH https://mapsbooking.googleapis.com/v1alpha/notification/partners/<PARTNER_ID>/bookings/<BOOKING_ID>?updateMask=status

Body:
{
  "name": "partners/<PARTNER_ID>/bookings/<BOOKING_ID>",
  "merchantId": "10001",
  "serviceId": "1001",
  "startTime": "2014-10-02T15:01:23.045123456Z",
  "duration": "3000s",
  "status": "CANCELED"
}

Availability Replace RTU

There are two types of replace methods available to update your availability:

  • 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 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:

  • spotsOpen
  • recurrence

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.
  • Your system will synchronize with Google's from time to time by sending all availability changes since last update (not recommended).
    • Batch Replace
    • Note: We expect the Inventory RTU to be sent within 5 minutes of an update occurring on your side. So you should check and send any updates at least every 5 minutes.
  • 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": "3600s",
            "spotsOpen": "1",
            "spotsTotal": "2",
            "availabilityTag": "1000001"
          }
        ]
      }
    ]
  }

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": "3600s",
            "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.