Migrate from HTTP batch requests

HTTP batch requests, a feature that lets you send multiple API calls in a single HTTP request, is deprecated for the Google Sheets API as of July 19, 2021. Requests sent as part of an HTTP batch request will fail after July 19, 2022.

To migrate away from HTTP batch requests, we recommend that you execute the individual requests separately.

Alternative batching methods

If the batch requests you want to make are within a single document, you might be able to use the methods below, instead. This includes requests with multiple Sheet IDs as long as the Spreadsheet ID is the same.

Unlike HTTP batch requests, these batch methods each count as a single API call for quota usage, and might have stronger guarantees of ordering and atomicity.

Migration example

The following code sample shows an HTTP batch request that needs to be updated to individual executions.

C#

// Create a batch to add the requests to:
var batch = new BatchRequest(sheetsService);

// Build some regular Sheets API requests, but don't execute them yet:
SpreadsheetsResource.ValuesResource.UpdateRequest request1 =
    sheetsService.Spreadsheets.Values.Update(requestBody1, spreadsheetId1, range1);
request1.ValueInputOption =
    SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;

SpreadsheetsResource.ValuesResource.UpdateRequest request2 =
    sheetsService.Spreadsheets.Values.Update(requestBody2, spreadsheetId2, range2);
request2.ValueInputOption =
    SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;

// Queue up the requests to be executed as part of the batch, providing
// callbacks to run when the requests finish.
batch.Queue<Data.UpdateValuesResponse>(
    request1,
    (response, error, i, message) => {
      if (error != null) {
        // Do something in the event of failure:
        Console.WriteLine(error);
      } else {
        // Do something with the result:
        Console.WriteLine(response);
      }
    });

batch.Queue<Data.UpdateValuesResponse>(
    request2,
    (response, error, i, message) => {
      if (error != null) {
        // Do something in the event of failure:
        Console.WriteLine(error);
      } else {
        // Do something with the result:
        Console.WriteLine(response);
      }
    });

// Execute all queued requests as a single batch.
await batch.ExecuteAsync();

Java

// Create a batch to add the requests to:
BatchRequest batch = sheetsService.batch();

// Build some regular Sheets API requests, but don't execute them yet:
Sheets.Spreadsheets.Values.Update request1 =
    sheetsService.spreadsheets().values()
        .update(spreadsheetId1, range1, requestBody1);
request1.setValueInputOption("RAW");

Sheets.Spreadsheets.Values.Update request2 =
    sheetsService.spreadsheets().values()
        .update(spreadsheetId2, range2, requestBody2);
request2.setValueInputOption("RAW");

// Queue up the requests to be executed as part of the batch, providing
// callbacks to run when the requests finish.
request1.queue(
    batch,
    new JsonBatchCallback<UpdateValuesResponse>() {
      public void onSuccess(UpdateValuesResponse response, HttpHeaders responseHeaders) {
          // Do something with the result:
          System.out.println(response);
        }
        public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
          // Do something in the event of failure:
          System.out.println(e);
        }
    });

request2.queue(
    batch,
    new JsonBatchCallback<UpdateValuesResponse>() {
      public void onSuccess(UpdateValuesResponse response, HttpHeaders responseHeaders) {
          // Do something with the result:
          System.out.println(response);
        }
        public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
          // Do something in the event of failure:
          System.out.println(e);
        }
    });

// Execute all queued requests as a single batch.
batch.execute();

Python

# Create a batch to add the requests to:
batch = sheetsService.new_batch_http_request()

# Build some regular Sheets API requests, but don't execute them yet:
request1 = sheetsService.spreadsheets().values().update(
    spreadsheetId=spreadsheet_id1, range=range1,
    valueInputOption='RAW', body=value_range_body1)
request2 = sheetsService.spreadsheets().values().update(
    spreadsheetId=spreadsheet_id2, range=range2,
    valueInputOption='RAW', body=value_range_body2)

# Queue up the requests to be executed as part of the batch, providing
# callbacks to run when the requests finish.
def callback(request_id, response, exception):
  if exception is not None:
    pprint(exception)
  else:
    pprint(response)

batch.add(request1, callback)
batch.add(request2, callback)

# Execute all the queued requests as a single batch.
batch.execute()

Ruby

# Create a batch to run requests in.
sheetsService.batch do |batch|
  # Queue up requests to be run as part of the batch. The block will be
  # executed when the request completes.
  batch.update_spreadsheet_value(spreadsheet_id1, range1, request_body1) do |res, err|
    if err != nil then
      puts "#{err}"
    else
      puts res.to_json
    end
  end

  batch.update_spreadsheet_value(spreadsheet_id2, range2, request_body2) do |res, err|
    if err != nil then
      puts "#{err}"
    else
      puts res.to_json
  end
end
# All batch requests queued as part of the block will be executed
# automatically.

The following code sample shows the previously batched requests as individual executions.

C#

SpreadsheetsResource.ValuesResource.UpdateRequest request1 =
    sheetsService.Spreadsheets.Values.Update(requestBody1, spreadsheetId1, range1);
request1.ValueInputOption =
    SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;

try {
  Data.UpdateValuesResponse response = await request1.ExecuteAsync();
  // Do something with the result:
  Console.WriteLine(response);
} catch (GoogleApiException error) {
  // Do something in the event of failure:
  Console.WriteLine(response);
}

SpreadsheetsResource.ValuesResource.UpdateRequest request2 =
    sheetsService.Spreadsheets.Values.Update(requestBody2, spreadsheetId2, range2);
request2.ValueInputOption =
    SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;

try {
  Data.UpdateValuesResponse response = await request2.ExecuteAsync();
  // Do something with the result:
  Console.WriteLine(response);
} catch (GoogleApiException error) {
  // Do something in the event of failure:
  Console.WriteLine(response);
}

Java

Sheets.Spreadsheets.Values.Update request1 =
    sheetsService.spreadsheets().values()
        .update(spreadsheetId1, range1, requestBody1);
request1.setValueInputOption("RAW");

try {
  UpdateValuesResponse response = request1.execute();
  // Do something with the result:
  System.out.println(response);
} catch (IOException e) {
  // Do something in the event of failure:
  System.out.println(e);
}

Sheets.Spreadsheets.Values.Update request2 =
    sheetsService.spreadsheets().values()
        .update(spreadsheetId2, range2, requestBody2);
request2.setValueInputOption("RAW");

try {
  UpdateValuesResponse response = request2.execute();
  // Do something with the result:
  System.out.println(response);
} catch (IOException e) {
  // Do something in the event of failure:
  System.out.println(e);
}

Python

# Build some regular Sheets API requests, but don't execute them yet:
request1 = sheetsService.spreadsheets().values().update(
    spreadsheetId=spreadsheet_id1, range=range1,
    valueInputOption='RAW', body=value_range_body1)

try:
  response = request1.execute()
  # Do something with the result:
  pprint(response)
except HttpError as exception:
  # Do something in the event of failure:
  pprint(exception)

request2 = sheetsService.spreadsheets().values().update(
    spreadsheetId=spreadsheet_id2, range=range2,
    valueInputOption='RAW', body=value_range_body2)

try:
  response = request2.execute()
  # Do something with the result:
  pprint(response)
except HttpError as exception:
  # Do something in the event of failure:
  pprint(exception)

Ruby

sheetsService.update_spreadsheet_value(spreadsheet_id1, range1, request_body1) do |res, err|
  if err != nil then
    puts "#{err}"
  else
    puts res.to_json
  end
end

sheetsService.update_spreadsheet_value(spreadsheet_id2, range2, request_body2) do |res, err|
  if err != nil then
    puts "#{err}"
  else
    puts res.to_json
end