Google Sheets is organized around a single primary identifier: the spreadsheetId. Everything you do—reading values, changing structure, searching developer metadata, copying sheets—starts with a spreadsheetId. Within a spreadsheet there are sheets (tabs) identified by a numeric sheetId and a human-facing title (sheet name). Many operations accept A1 notation ranges (which can include a sheet name), and some accept richer data filters or developer metadata references instead of A1 ranges.
Key entities and how they relate
-
Spreadsheet: the top-level resource. Use
spreadsheetIdfor almost every call. The spreadsheet resource (spreadsheets.get) containssheets[],developerMetadata[], and high-level properties. -
Sheet (tab): referenced by
sheetId(numeric) andtitle(string). Structural changes (add, delete, reorder, resize) are performed against the spreadsheet via structural requests; many value operations use sheet names inside A1 notation. -
Value ranges: reading and writing cell content uses A1/R1C1 ranges or data filters. Value operations target a
spreadsheetIdand arange(or multipleranges) or aDataFilterpayload for filter-based access. -
Developer metadata: metadata entries attached to the spreadsheet, sheets, or ranges. Each entry has a numeric
metadataIdyou cangetorsearchfor; developer metadata is a first-class way to locate ranges without brittle A1 strings.
What to call first (entry points)
-
If you need sheet names,
sheetIds, or developer metadata IDs, callspreadsheets.get(omitincludeGridDataunless you need cell-level grid data). Thesheetsarray in the response givessheetId,title,index, and existing developer metadata entries. -
To read cell values only, call
spreadsheets.values.get(single range) orspreadsheets.values.batchGet(multiple ranges). These requirespreadsheetIdand A1/R1C1rangevalues. -
To write or update values, decide between single-range updates and batch operations: simple writes use
spreadsheets.values.update; multi-range or many-row operations usespreadsheets.values.batchUpdateorspreadsheets.values.appendfor append semantics. -
To perform structural or formatting changes (add a sheet, move columns, set frozen rows, add named ranges, create charts), call
spreadsheets.batchUpdatewith arequests[]array of spreadsheet-level Requests. This endpoint is the entry point for any change that is not purely value-level. -
To create a brand new spreadsheet, call
spreadsheets.createwith the desiredpropertiesand optionalsheetsdefinitions.
Common user tasks — how to accomplish them (operation patterns)
Read values
- Single range: call
spreadsheets.values.getwithspreadsheetIdandrange. - Multiple ranges at once: call
spreadsheets.values.batchGetwithranges[]. - When you need formulas, return raw formulas with
valueRenderOption=FORMULA. For date/time formatting choices, usedateTimeRenderOption.
Write or update values
- Replace a range: call
spreadsheets.values.updatewith therangeandbodycontainingvalues. ChoosevalueInputOption=RAWfor literal text orUSER_ENTEREDto interpret as user input (formulas, dates). - Update multiple ranges in one request: call
spreadsheets.values.batchUpdatewith adata[]array and a singlevalueInputOptionfor the whole batch. - Append rows to a table: call
spreadsheets.values.appendwith arangethat identifies the table andvalueInputOption.appendwill insert after the last row of that logical table. UseinsertDataOption=INSERT_ROWSto ensure new rows are added rather than overwriting. - If you need the updated values returned, set
includeValuesInResponse=trueand pickresponseValueRenderOptionandresponseDateTimeRenderOptionto control how returned values look.
Clear values
- Clear a single range: call
spreadsheets.values.clear. - Clear multiple explicit ranges: call
spreadsheets.values.batchClearwithranges[]. - Clear by data filters: use
spreadsheets.values.batchClearByDataFilterand pass adataFilters[]body.
Structural changes (sheets, columns, formats, named ranges, charts)
- Bundle structural/formatting changes into one atomic request by calling
spreadsheets.batchUpdatewith arequests[]array. Each entry is a specific Request (addSheet, deleteSheet, updateSheetProperties, repeatCell, addDeveloperMetadata, etc.). The response returns areplies[]array with one reply per request in order.
Copy a sheet to another spreadsheet
- Call
spreadsheets.sheets.copyTowithspreadsheetId(source) andsheetId. The request body specifies the destination spreadsheet (typicallydestinationSpreadsheetId). The call returns the new sheet'sSheetPropertiesin the destination (including its newsheetId).
Create a spreadsheet
- Call
spreadsheets.createwith apropertiesobject and optionalsheetsdefinitions. The response is the created spreadsheet resource includingspreadsheetId.
Developer metadata lookup and use
- To find metadata entries that match criteria, call
spreadsheets.developerMetadata.searchwith a search request; results includemetadataIdand location. Usespreadsheets.developerMetadata.getwithmetadataIdandspreadsheetIdto retrieve a specific entry. - Developer metadata can be used in DataFilter payloads to target ranges in subsequent
getByDataFilter,batchGetByDataFilter,batchClearByDataFilter, andbatchUpdateByDataFiltercalls.
Using data filters instead of A1 notation
- If sheet names change or ranges are dynamic, prefer DataFilters (by developer metadata or grid range) for stability. Endpoints that accept DataFilters include
spreadsheets.getByDataFilter,spreadsheets.values.batchGetByDataFilter,spreadsheets.values.batchUpdateByDataFilter, andspreadsheets.values.batchClearByDataFilter.
Non-obvious behaviors and gotchas
-
spreadsheetIdis required for nearly every call; fetch it first from the user or by creating a spreadsheet. Usespreadsheets.getwhen you needsheetIdvalues or to inspectdeveloperMetadata. -
sheetIdvstitle: many user requests reference a sheet by name. Some API calls require the numericsheetId. Usespreadsheets.getto map titles tosheetIds. When referring to a range in A1 notation, include the sheet name (for example,Sheet1!A1:B10). If the sheet name contains spaces or special characters, surround it with single quotes:'Quarter 1'!A1:B10. -
Two different update models exist—structural
spreadsheets.batchUpdateand value-levelspreadsheets.values.*. Do not confuse them:- Use
spreadsheets.batchUpdatefor structural/formatting/chart/metadata requests (it accepts arequests[]array of operations and returnsreplies[]). - Use
spreadsheets.values.update/append/batchUpdate/clearfor cell values only. Value-batch endpoints take different request shapes and return different response types.
- Use
-
spreadsheets.gethas anincludeGridDataflag. Turning it on returns full grid data (cell-level objects including formatting,userEnteredValue,effectiveValue, etc.) and can be very large. If you only need sheet metadata, omit it. For formulas specifically, you can often usespreadsheets.values.getwithvalueRenderOption=FORMULAinstead ofincludeGridData. -
spreadsheets.batchUpdateis atomic per call. When you send multiple Requests, the API applies them in order and returns areplies[]array aligned with yourrequests[]. Use that ordering to correlate replies to requests. -
spreadsheets.values.appendtreats therangeas a table anchor. It finds the last row of that logical table and appends after it. If your range is not a table, or if you want to ensure new rows are inserted, specifyinsertDataOption=INSERT_ROWS. -
valueInputOptionmatters:RAWwrites exactly what you send;USER_ENTEREDparses the input like the Sheets UI—formulas and date parsing are applied. Choose deliberately. -
Response rendering options differ by endpoint:
- Use
valueRenderOption/dateTimeRenderOptionon value reads to control returned formatting. - Use
responseValueRenderOption/responseDateTimeRenderOptionon write/append calls when you request returned values.
- Use
-
Developer metadata IDs are numeric and created when metadata is added. Search for metadata entries (via search) to obtain
metadataIdbefore callingdeveloperMetadata.get. -
Copying a sheet into another spreadsheet returns the new sheet's
SheetProperties(including itssheetIdin the destination). If you need thatsheetIdfor subsequent operations, read it from the copy response. -
Large responses can be trimmed with the
fieldsquery parameter. When you only need sheet titles orsheetIds, request only those fields to reduce payload size.
Practical sequencing patterns
- Inspect spreadsheet: call
spreadsheets.get(noincludeGridData) to learnsheets[],sheetIds, anddeveloperMetadata[]. - Read values: call
spreadsheets.values.getorbatchGetwith properly quoted A1 ranges or use data filters found via metadata search. - Prepare structural changes and apply them together: build a
requests[]array and callspreadsheets.batchUpdateonce to apply them atomically. - For many value changes across ranges, batch them with
spreadsheets.values.batchUpdateto reduce round trips. - When copying between spreadsheets, call
spreadsheets.sheets.copyToand use the returnedsheetIdfrom the response for further edits in the destination.
Focus on spreadsheetId first, map sheet names to sheetId when needed, choose the correct endpoint family (structural spreadsheets.batchUpdate vs value-level spreadsheets.values.*), and prefer DataFilters/developer metadata when ranges must be robust to sheet renames or moving content.