Appending to a spreadsheet is the foundation of any log — add a new row below the last one without overwriting anything. What does that call look like?
It probably takes a spreadsheet id, a range like Sheet1, and a row of values? And picks up where the last row ended?
Exactly. GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND needs a spreadsheetId, a range pointing at the tab, a 2D values array (even for one row), and a valueInputOption:
result = toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": "abc123",
"range": "Sheet1",
"values": [["2026-04-20", "42"]],
"valueInputOption": "USER_ENTERED",
})[[...]] — a list of lists even for a single row? Why not just pass the row directly?
The API lets you append many rows in one call. The outer list holds rows, the inner list holds cells. For one row you pass [row]; for five, you pass [row1, row2, row3, row4, row5]:
def append_to_log(spreadsheet_id: str, row: list) -> dict:
result = toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": spreadsheet_id,
"range": "Sheet1",
"values": [row],
"valueInputOption": "USER_ENTERED",
})
return resultWhat does USER_ENTERED do? Sounds important.
It tells Sheets to parse the values like the UI does — a string like "42" becomes a number, "=SUM(A:A)" becomes a live formula. The other option, RAW, stores everything as text. USER_ENTERED is almost always what you want when building a log.
So every row I append shows up at the bottom of the sheet, parsed the same way Google Sheets parses manual entries?
The row will sit at the bottom of the tab the next time you refresh. A log built from Python, read from a browser — that is the foundation of every reporting pipeline you will build.
TL;DR: Append lands below the last existing row — perfect for logs. USER_ENTERED parses like the UI.
Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPENDvalues is always 2D ([row] or [row1, row2])USER_ENTERED — strings become numbers and formulasRAW — everything stored verbatim as text| Field | Meaning |
|---|---|
updatedRange | where the append landed |
updatedRows | how many rows were added |
spreadsheetId | confirms the target sheet |
Appending to a spreadsheet is the foundation of any log — add a new row below the last one without overwriting anything. What does that call look like?
It probably takes a spreadsheet id, a range like Sheet1, and a row of values? And picks up where the last row ended?
Exactly. GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND needs a spreadsheetId, a range pointing at the tab, a 2D values array (even for one row), and a valueInputOption:
result = toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": "abc123",
"range": "Sheet1",
"values": [["2026-04-20", "42"]],
"valueInputOption": "USER_ENTERED",
})[[...]] — a list of lists even for a single row? Why not just pass the row directly?
The API lets you append many rows in one call. The outer list holds rows, the inner list holds cells. For one row you pass [row]; for five, you pass [row1, row2, row3, row4, row5]:
def append_to_log(spreadsheet_id: str, row: list) -> dict:
result = toolset.execute_action(Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND, {
"spreadsheetId": spreadsheet_id,
"range": "Sheet1",
"values": [row],
"valueInputOption": "USER_ENTERED",
})
return resultWhat does USER_ENTERED do? Sounds important.
It tells Sheets to parse the values like the UI does — a string like "42" becomes a number, "=SUM(A:A)" becomes a live formula. The other option, RAW, stores everything as text. USER_ENTERED is almost always what you want when building a log.
So every row I append shows up at the bottom of the sheet, parsed the same way Google Sheets parses manual entries?
The row will sit at the bottom of the tab the next time you refresh. A log built from Python, read from a browser — that is the foundation of every reporting pipeline you will build.
TL;DR: Append lands below the last existing row — perfect for logs. USER_ENTERED parses like the UI.
Action.GOOGLESHEETS_SPREADSHEETS_VALUES_APPENDvalues is always 2D ([row] or [row1, row2])USER_ENTERED — strings become numbers and formulasRAW — everything stored verbatim as text| Field | Meaning |
|---|---|
updatedRange | where the append landed |
updatedRows | how many rows were added |
spreadsheetId | confirms the target sheet |
Create a free account to get started. Paid plans unlock all tracks.