> [!NOTE]
> **Note:** [Create a new support case in the Partner Portal](https://actionscenter.google.com/support/cases) if you are interested in enabling Asynchronous Bookings.

Synchronous bookings are defined as bookings that are confirmed or declined
in real time.

Asynchronous bookings are defined as bookings that the merchant confirms or
declines at a later time.

A booking is specified as either synchronous or asynchronous at the
availability-level. This also means that for a given merchant and service,
there could be both synchronous and asynchronous availability slots.

To determine the appropriate implementation, first identify which category
your inventory falls under:

- [Enabling synchronous bookings only](https://developers.google.com/actions-center/verticals/reservations/e2e/add-ons/add-async#sync): All merchants and services are instantly confirmed.
- [Enabling asynchronous bookings](https://developers.google.com/actions-center/verticals/reservations/e2e/add-ons/add-async#async): Some or all merchants and services require merchant manual confirmation.

## Asynchronous booking criteria

- Modification of an async booking on the Actions Center is **not** supported.
- Merchants should be able to accept or decline the booking through the partner's online system (e.g. host panel for the restaurant). Calling the merchant on behalf of the user to determine if the merchant accepts or declines a booking is **not** allowed.
- Merchant proposal of a new booking time is **not** supported. The booking request must be accepted or declined in the original state.

## Enabling synchronous bookings only

The standard implementation defaults to synchronous bookings. Please consult
the Reservations End-to-End integration documentation for further information.

## Enabling asynchronous booking

If some or all of the merchants use an asynchronous booking flow, the
following changes need to be made:

- **Confirmation mode:** All representations of availability slots now
  contain a `confirmation_mode` field which describes how bookings
  of that availability slot are confirmed. Specify the
  `confirmation_mode` of each availability slot for the
  following:

  - In the Availability Feed, `confirmation_mode` is specified at the availability level
  - In the Booking Server API methods, `confirmation_mode` is specified at the slot level
  - In the Real-Time Updates API methods, `confirmation_mode` is specified at the availability level
- **Booking status:** All representations of bookings contain a `status` field that represents the state of the booking. Three new asynchronous status values have beeen introduced: `PENDING_CONFIRMATION`, `DECLINED_BY_MERCHANT`, and `FAILED`. Use these new status values when processing creations, declines, and failures of asynchronous bookings.
- **Booking updates:** All asynchronous updates to the status of the bookings should be reported via the Booking Notification API's [bookings.patch](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/notification.partners.bookings/patch) method.

The diagram below shows how confirmation mode and booking status are used
in a typical asynchronous booking interaction.
![Figure 1: Asynchronous booking flow](https://developers.google.com/static/actions-center/images/enabling_async_1.png) **Figure 1:** Asynchronous booking flow

1. Availability feeds have been updated so that each availability slot's confirmation mode is specified. It is important to have this information in the feed so that we can explain the asynchronous nature of the booking to the user early on in the flow.
2. When [`BatchAvailabilityLookup`](https://developers.google.com/actions-center/verticals/reservations/e2e/reference/booking-server-api-rest/e2e-methods/batchavailabilitylookup-method) or [`CheckAvailability`](https://developers.google.com/actions-center/legacy/reference/booking-server/checkavailability-method) is called, we pass along the confirmation mode and ideally the same confirmation mode to be returned. This ensures the user is shown the appropriate messaging.
3. When [`CreateBooking`](https://developers.google.com/actions-center/verticals/reservations/e2e/reference/booking-server-api-rest/e2e-methods/createbooking-method) is called, we pass along the confirmation mode to indicate the anticipated confirmation mode. When the asynchronous booking request is submitted, the booking is returned with status `PENDING_MERCHANT_CONFIRMATION`.
4. When the merchant accepts or declines a booking request, the booking status is updated via the real-time update Booking Notification API's [bookings.patch](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/notification.partners.bookings/patch) method. If you want to auto-decline bookings that are not responded to in a timely fashion, do so via the same real-time update method.

## Availability Feeds

In the availability feed, specify if each slot is synchronous or
asynchronous. To do this, set the new `confirmation_mode`
field.

> [!NOTE]
> **Note:** The `confirmation_mode` is stored in the availability section of the Availability Feeds and Real-Time Updates, however, this field is stored in the slot level for the Booking Server APIs.

```protobuf
// Mode by which bookings for an availability slot are confirmed.
enum ConfirmationMode {
  // The confirmation mode was not specified.
  // Synchronous confirmation will be assumed.
  CONFIRMATION_MODE_UNSPECIFIED = 0;

  // Bookings for this availability will be confirmed synchronously.
  CONFIRMATION_MODE_SYNCHRONOUS = 1;

  // Bookings for this availability will be confirmed asynchronously.
  CONFIRMATION_MODE_ASYNCHRONOUS = 2;
}
```

Although the confirmation mode is assumed to be synchronous if no mode is
specified, it is strongly encouraged to explicitly specify a mode since
that removes any confusion around accidental omissions.

### Async

```
{
  "availability": [
    {
      "merchant_id": "10001",
      "service_id": "1000",
      "spots_open": 3,
      "spots_total": 3,
      "duration_sec": 3600,
      "start_sec": 1535806800,
      "resources": {
        "party_size": 4
      },
      "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
    }
  ]
}
```

### Sync

```
{
  "availability": [
    {
      "merchant_id": "10001",
      "service_id": "1000",
      "spots_open": 3,
      "spots_total": 3,
      "duration_sec": 3600,
      "start_sec": 1535806800,
      "resources": {
        "party_size": 4
      },
      "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
    }
  ]
}
```

### Async and Sync

```
{
  "availability": [
    {
      "merchant_id": "10001",
      "service_id": "1000",
      "spots_open": 3,
      "spots_total": 3,
      "duration_sec": 3600,
      "start_sec": 1535806800,
      "resources": {
        "party_size": 4
      },
      "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
    },
    {
      "merchant_id": "10002",
      "service_id": "1000",
      "spots_open": 4,
      "spots_total": 4,
      "duration_sec": 3600,
      "start_sec": 1535806800,
      "resources": {
        "party_size": 2
      },
      "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
    }

  ]
}
```

## Booking Server

### BatchAvailabilityLookup or CheckAvailability

In the
[`BatchAvailabilityLookupResponse`](https://developers.google.com/actions-center/verticals/reservations/e2e/reference/booking-server-api-rest/e2e-methods/batchavailabilitylookup-method) (BAL)
or
[`CheckAvailabilityResponse`](https://developers.google.com/actions-center/legacy/reference/booking-server/checkavailability-method) (CA), return the same `confirmation_mode` as is specified in the
availability feed and passed along via the
[`BatchAvailabilityLookupRequest`](https://developers.google.com/actions-center/verticals/reservations/e2e/reference/booking-server-api-rest/e2e-methods/batchavailabilitylookup-method)
or
[`CheckAvailabilityRequest`](https://developers.google.com/actions-center/legacy/reference/booking-server/checkavailability-method).

### BAL-Async

```
{
  "slot_time_availability": [
    {
      "slot_time": {
        "duration_sec": "3600",
        "resource_ids": {
          "party_size": 3
        },
        "service_id": "1000",
        "start_sec": "1546458300",
        "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
      },
      "available": true
    }
  ]
}
```

### BAL-Sync

```
{
  "slot_time_availability": [
    {
      "slot_time": {
        "duration_sec": "3600",
        "resource_ids": {
          "party_size": 3
        },
        "service_id": "1000",
        "start_sec": "1546458300",
        "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
      },
      "available": true
    }
  ]
}
```

### CA-Async

```
{
  "slot": {
    "duration_sec": "3600",
    "merchant_id": "317652",
    "resources": {
      "party_size": 3
    },
    "service_id": "1000",
    "start_sec": "1546458300",
    "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
  },
  "count_available": 1,
  "duration_requirement": "DO_NOT_SHOW_DURATION"
}
```

### CA-Sync

```
{
  "slot": {
    "duration_sec": "3600",
    "merchant_id": "317652",
    "resources": {
      "party_size": 3
    },
    "service_id": "1000",
    "start_sec": "1546458300",
    "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
  },
  "count_available": 1,
  "duration_requirement": "DO_NOT_SHOW_DURATION"
}
```

### CreateBooking

Make sure to return the correct status for the booking using the available
options below:

```protobuf
// Status of a booking.
//
// Updating booking status does not change the status of the associated payment.
// Prepayment status updates should be done using the PrepaymentStatus enum.
enum BookingStatus {
  // Not specified.
  BOOKING_STATUS_UNSPECIFIED = 0;

  // Booking has been confirmed
  CONFIRMED = 1;

  // Booking is awaiting confirmation by the merchant before it can transition
  // into CONFIRMED status. Only applicable to non-payments Dining or
  // Beauty verticals.
  PENDING_MERCHANT_CONFIRMATION = 2;

  // Booking has been canceled on behalf of the user.
  // The merchant can still trigger a manual refund.
  CANCELED = 3;

  // User did not show for the appointment
  NO_SHOW = 4;

  // User did not show for the appointment in violation of the cancellation
  // policy.
  NO_SHOW_PENALIZED = 5;

  // Booking could not be completed by the async backend due to a failure.
  FAILED = 6;

  // Booking was asynchronously declined by the merchant. Only applicable to
  // non-payments Dining or Beauty verticals.
  DECLINED_BY_MERCHANT = 7;
}
```

In the [`CreateBookingResponse`](https://developers.google.com/actions-center/verticals/reservations/e2e/reference/booking-server-api-rest/e2e-methods/createbooking-method),
return the current `confirmation_mode` for the booking's aggregated slot provided
in the CreateBookingRequest. In addition, when the booking is asynchronous,
set the `status` to `PENDING_MERCHANT_CONFIRMATION`. Please ensure
the `confirmation_mode` is what the user and what Reserve with
Google expects to avoid confusing the user.

### Async

```
{
  "booking": {
    "slot": {
      "duration_sec": "3600",
      "merchant_id": "100001",
      "resources": {
        "party_size": 2
      },
      "service_id": "1000",
      "start_sec": "1546647234",
      "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
    },
    "user_information": {
      "email": "johnsmith@gmail.com",
      "family_name": "John",
      "given_name": "Smith",
      "telephone": "+1 800-123-4567",
      "user_id": "2017492857928759285"
    },
    "payment_information": {
      "prepayment_status": "PREPAYMENT_NOT_PROVIDED"
    },
    "status": "PENDING_MERCHANT_CONFIRMATION"
  }
}
```

### Sync

```
{
  "booking": {
    "slot": {
      "duration_sec": "3600",
      "merchant_id": "100001",
      "resources": {
        "party_size": 2
      },
      "service_id": "1000",
      "start_sec": "1546647234",
      "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
    },
    "user_information": {
      "email": "johnsmith@gmail.com",
      "family_name": "John",
      "given_name": "Smith",
      "telephone": "+1 800-123-4567",
      "user_id": "2017492857928759285"
    },
    "payment_information": {
      "prepayment_status": "PREPAYMENT_NOT_PROVIDED"
    },
    "status": "CONFIRMED"
  }
}
```

### UpdateBooking

In the initial release of async, user modifications to an existing booking
are not supported. Instead, the user should cancel the booking and create a
new booking.

## Real-Time Updates

For real-time updates to availabilities, `confirmation_mode`
should be specified. This applies for the following methods:

### Inventory RTU (ReplaceServiceAvailability or BatchReplaceServiceAvailability)

Using
[`availability.replace` (batch) method](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/inventory.partners.availability/replace)
or
[`services.availability.replace` method](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/inventory.partners.merchants.services.availability/replace),
set `confirmation_mode` to `CONFIRMATION_MODE_ASYNCHRONOUS` in the [`Availability`](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/inventory.partners.merchants.services.availability#Availability)

### Async

```
{
  "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": "0",
          "spotsTotal": "2",
          "availabilityTag": "1000001",
          "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
        }
      ]
    }
  ]
}
```

### Sync

```
{
  "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": "0",
          "spotsTotal": "2",
          "availabilityTag": "1000001",
          "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
        }
      ]
    }
  ]
}
```

### Async and Sync

```
{
  "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": "0",
          "spotsTotal": "2",
          "availabilityTag": "1000001",
          "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS"
        },
        {
          "startTime": "2014-10-03T11:00:00.00Z",
          "duration": "5400s",
          "spotsOpen": "1",
          "spotsTotal": "1",
          "availabilityTag": "1000002",
          "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS"
        }
      ]
    }
  ]
}
```

### Booking Notification API

Asynchronous updates to a booking status should be made via the Booking
Notification API [bookings.patch](https://developers.google.com/maps-booking/reference/maps-booking-api/rest/v1alpha/notification.partners.bookings/patch) method.

When updating the status, make sure to include the `status` field name in the
`updateMask`.

| Status | Description |
|---|---|
| CONFIRMED | merchant confirmed the booking |
| FAILED | partner could not confirm or decline the booking with the merchant |
| DECLINED_BY_MERCHANT | merchant declined the booking |

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

Body:
{"name":"partners/<PARTNER_ID>/bookings/<BOOKING_ID>", "status":"DECLINED_BY_MERCHANT"}
```

In the event of a booking failure, set the booking status to `FAILED` and
specify the booking_failure. If the status is set to anything else, the
`booking_failure` is ignored.

> [!NOTE]
> **Note:** `booking_failure` fields are passed as query arguments on the URL.

```
Request:
PATCH https://mapsbooking.googleapis.com/v1alpha/notification/partners/<PARTNER_ID>/bookings/<BOOKING_ID>?updateMask=status&booking_failure.cause="SLOT_UNAVAILABLE"

Body:
{"name":"partners/<PARTNER_ID>/bookings/<BOOKING_ID>", "status":"FAILED"}
```

### Email Notifications

For asynchronous bookings, there are five potential emails related to the
status of the booking that are sent to users.

> [!NOTE]
> **Note:** Reminder and feedback emails will be sent in addition to emails corresponding to the following booking statuses:

- `PENDING_MERCHANT_CONFIRMATION`
- `CONFIRMED`
- `DECLINED_BY_MERCHANT`
- `FAILED`
- `CANCELED`