list_google_sheets_rows
List or find Google Sheet rows with bounded cursor pagination.
list_google_sheets_rows(
sheet_id: str,
sheet_name: str = None,
limit: int = 50,
cursor: str = None,
where: dict = None,
include_cell_details: bool = False,
) -> dictReturns a bounded page of rows from a Google Sheet. Pass where to match exact
values in one or more columns. Multiple conditions are combined with AND and
matches are case-sensitive.
Each row has this shape:
{
"rowNumber": 42,
"values": {
"Order ID": "1000123",
"Status": "Pending",
},
}Parameters
| Name | Type | Description |
|---|---|---|
sheet_id | str | Spreadsheet ID from the Google Sheets URL |
sheet_name | str | Optional tab name; defaults to the first tab |
limit | int | Maximum rows to return, from 1 to 100; defaults to 50 |
cursor | str | Opaque nextCursor from the previous response |
where | dict | Optional exact column-value matches, such as {"Order ID": "1000123", "Status": "Pending"} |
include_cell_details | bool | Optional; defaults to False. Add displayed text, formulas, and hyperlink URLs in each row's cells map. |
Returns
{
"rows": [...],
"nextCursor": "opaque cursor or None",
}When nextCursor is not None, pass it back unchanged to continue. Do not
conclude that a filtered search has no more matches until nextCursor is
None.
Why filtered results are paginated by scan position
Google Sheets has no indexed structured row search. A filtered call scans at most 5,000 rows so a large or sparsely matching sheet cannot consume an unbounded action run. The cursor continues from the last scanned position.
Cursors and row numbers are not permanent IDs
Inserting, deleting, or sorting rows can make a cursor or row number stale. When updating by row number, pass expected values so the write fails closed if the row has moved.
Examples
Find pending requests for an order
page = list_google_sheets_rows(
"YOUR_SHEET_ID",
where={"Order ID": "1000123", "Status": "Pending"},
limit=10,
)
for row in page["rows"]:
print(row["rowNumber"], row["values"])Read hyperlinks and formulas
page = list_google_sheets_rows(
"YOUR_SHEET_ID",
sheet_name="Resources",
include_cell_details=True,
)
for row in page["rows"]:
resource = row["cells"]["Resource"]
print(resource["displayText"], resource["hyperlinks"])For example, a cell displaying "Installation guide" with a hyperlink formula returns:
{
"rowNumber": 12,
"values": {"Resource": "Installation guide"},
"cells": {
"Resource": {
"displayText": "Installation guide",
"formula": '=HYPERLINK("https://example.com/guide", "Installation guide")',
"hyperlinks": ["https://example.com/guide"],
},
},
}The existing values map, exact where filtering, and cursor pagination are
unchanged. When include_cell_details is omitted or False, cells is absent
and no additional metadata request is made. The REST API option is
includeCellDetails: true on POST /rest/v1/sheets/rows/search.
Each named column has displayText (the formatted text shown in Sheets) and
hyperlinks (distinct URLs, or an empty list). formula is present only for
formula cells. Links can come from a HYPERLINK formula, a cell-level link, or
rich-text links on parts of the text; manually attached links need no formula.
This option returns these cell details, not all formatting or smart-chip data.
Metadata is fetched only for returned rows. Values and metadata are separate reads, so editing or sorting a sheet during a request can cause them to differ; the response is not a transactional snapshot.
Process every page
cursor = None
while True:
page = list_google_sheets_rows(
"YOUR_SHEET_ID",
sheet_name="Refunds",
limit=100,
cursor=cursor,
)
for row in page["rows"]:
process(row)
cursor = page["nextCursor"]
if cursor is None:
breakPrerequisites
Share the spreadsheet with
[email protected]. Viewer access is enough
for listing; use Editor access if the same workflow also appends or updates.