Inserts and deletes rows, columns and sheets, and changes merges, sorting, charts and validation. Requires sheets.structure.write, which is separate from writing values.
POST/v1/spreadsheets/:id/batch-update
Permission
The key must be grantedsheets.structure.write
A key without it gets 403 insufficient_scope, with the missing permission named in details.
Needs an If-Match header carrying the state from /state, and answers 422 without one. These are the changes that move data other requests address by position — inserting a row shifts every reference below it — so one applied against a stale view merges cleanly into a corrupt grid. A 409 means the document changed since your read: read state again and reapply. Retrying is safe on its own, because a successful apply moves the state and a replay answers 409 rather than applying twice.
Path parameters
Field
Type
Description
idrequired
string
The spreadsheet to restructure.
Headers
Field
Type
Description
If-Matchrequired
string
The state token from the spreadsheet's /state, which is what makes this change conditional on the document you actually read. Without it the request is refused rather than applied to whatever the document has become.
Request body
Requests apply in order and each sees the effect of the one before, so adding a sheet and writing to it in the same batch works.
Field
Type
Description
requestsrequired
object[]
The changes to apply, in order. Each entry names exactly one operation. At least one.
Its fields are below.
Each item in requests
Field
Type
Description
add_sheet
object
Add a tab. Its reply carries the new sheet_id.
Its fields are below.
delete_sheet
object
Remove a tab and everything on it. The last remaining sheet cannot be deleted.
Its fields are below.
update_sheet_properties
object
Rename, move, recolour or hide a tab.
Its fields are below.
merge_cells
object
Merge a rectangle, dropping any merge it overlaps. Its reply carries merge_id.
Its fields are below.
unmerge_cells
object
Split the merges in a range. Its reply carries how many were removed.
Its fields are below.
update_dimension_properties
object
Resize or hide rows and columns.
Its fields are below.
repeat_cell
object
Apply formatting across a range.
Its fields are below.
sort_range
object
Sort a range by one of its columns.
Its fields are below.
The add_sheet
Field
Type
Description
title
string
Defaults to the next free SheetN.
index
integer
Where among the tabs. Appends when omitted.
The delete_sheet
Field
Type
Description
sheet_idrequired
string
The update_sheet_properties
Field
Type
Description
sheet_idrequired
string
propertiesrequired
object
What to change. Omitted properties are left alone.
Its fields are below.
The properties
Field
Type
Description
name
string
index
integer
color
string
Hex, for example #cc0000. An empty string clears it.
hidden
boolean
The merge_cells
Field
Type
Description
rangerequired
A1 range
The unmerge_cells
Field
Type
Description
rangerequired
A1 range
The update_dimension_properties
Field
Type
Description
sheet_idrequired
string
dimensionrequired
string
ROWSCOLUMNS
indexrequired
integer
Which row or column, from 0.
pixel_size
integer
null restores the default size.
hidden
boolean
The repeat_cell
Field
Type
Description
rangerequired
A1 range
style
object
Merged with the formatting already on each cell, so applying bold does not wipe a fill. A null value clears one attribute.
Its fields are below.
number_format
string
A format pattern, for example $#,##0.00.
The style
Field
Type
Description
b
0 or 1
Bold.
i
0 or 1
Italic.
s
0 or 1
Strikethrough.
u
0 or 1
Underline.
fg
string
Text colour, hex.
bg
string
Fill colour, hex.
ha
string
leftcenterright
va
string
topmiddlebottom
The sort_range
Field
Type
Description
rangerequired
A1 range
columnrequired
integer
Absolute column index, not an offset within the range.
Idempotency-Key is required on every write. Retrying with the same key returns the original response rather than repeating the operation, so a timeout is something you retry rather than something you investigate.
Response
Field
Type
Description
replies
object[]
One entry per request, in the same order, carrying whatever that operation returns: sheet_id for add_sheet, merge_id for merge_cells, removed for unmerge_cells. An empty object where an operation returns nothing.
state
string
The document's state after the write. Send it as If-Match on a structural change, or compare it with your last one to notice somebody else's edit.
changed
boolean
False when the write stored nothing new — writing a cell the value it already holds. Not an error and not worth retrying: no new state was produced and no collaborator was notified.
Structural changes only, and they need If-Match carrying the state you read: inserting a row moves everything below it, so applying one against a stale view leaves a corrupt grid. Requests apply in order and each sees the one before, so adding a sheet and formatting it in one batch works. replies is positional, with {} where a request has nothing to return.
Errors
Every failure uses the same shape, with a stable string code you can branch on.
See the error reference.