Google Sheets to JSON
How to convert Google Sheets to JSON without Apps Script
rows.page converts Google Sheets to JSON for $0, with no signup: drop a downloaded CSV of up to 1.5 GB, or open the tab's CSV export link, then click Export > JSON. You get 1 array of objects keyed by the header row, built in your browser without Apps Script.
No file handy? Open CO2 emissions by country and year (50k rows, 14 MB).
Can you download Google Sheets as JSON?
No. File > Download in Google Sheets offers Microsoft Excel, OpenDocument, PDF, Web page, CSV and TSV, with no JSON option, and the CSV download covers only the tab you have open.
So you either convert that CSV into JSON objects or read the cells through Google's APIs and build the keys yourself. The 4 routes compare like this:
| Method | Code needed | Output shape | Stays in sync |
|---|---|---|---|
| rows.page + CSV export link | None | Array of objects (or JSONL) | Yes, fetched fresh each time you open the link |
| CSV download + rows.page | None | Array of objects (or JSONL) | No, you download again after edits |
Sheets API v4 values.get | Yes | Array of row arrays (values) | Yes, live API read |
| Google Apps Script | Yes | Whatever your script builds | Yes, if deployed or triggered |
Convert a public Google Sheet to JSON from its link
A sheet shared as Anyone with the link has a CSV export URL that Google does not officially document: https://docs.google.com/spreadsheets/d/<id>/export?format=csv&gid=<gid>. Put it after https://rows.page/ and rows.page opens it as a table.
- In Google Sheets, set sharing to Anyone with the link.
- From the address bar, copy the
<id>(the part after/d/) and the<gid>of the tab (the number after#gid=). - Open
https://rows.page/https://docs.google.com/spreadsheets/d/<id>/export?format=csv&gid=<gid>. - Click Export and pick JSON for one array of objects, or JSONL for one object per line.
Google's export link allows cross-origin requests, so your browser downloads the CSV straight from Google instead of through the rows.page proxy, and nothing is stored on rows.page. The link has no file extension, so rows.page reads the format from the bytes and opens it as CSV.
Before exporting, trim the data in the grid. Type a filter such as price:>20 or -name:* (rows where name is empty), or run SQL that starts with SELECT, WITH or FROM against the table data. Export writes the current view: every matching row of a filter, or up to 1,000,000 rows of a SQL result.
Convert a private Google Sheet to JSON
rows.page fetches links without your Google login, so a sheet that is not shared publicly will not load from its export link. Use File > Download > Comma Separated Values (.csv) instead, drop the file on rows.page and click Export > JSON.
The file is read by DuckDB-WASM inside your browser tab, up to 1.5 GB, and is not uploaded. DuckDB detects the delimiter and the header row for you.
For a quick slice, copy the cells in Google Sheets, click Paste data on rows.page, paste them into the box and click Open. Copied cells arrive tab-separated and open as a table you can export as JSON.
Get JSON from the Google Sheets API v4
For an app that reads a sheet in code, Google's official route is the Sheets API v4 spreadsheets.values.get. It returns a ValueRange object with range, majorDimension and values, where values is an array of row arrays rather than objects keyed by header. Map values[0] onto the other rows yourself:
// Example ValueRange response from spreadsheets.values.get
const response = {
range: "Sheet1!A1:C3",
majorDimension: "ROWS",
values: [
["id", "name", "price"],
["101", "Widget", "25"],
["102", "Gadget", "40"]
]
};
const [headers, ...rows] = response.values;
const jsonObjects = rows.map(row =>
Object.fromEntries(headers.map((key, i) => [key, row[i] ?? null]))
);The API keeps your app connected to the live sheet, but you handle authentication, quotas and types yourself. Values come back as formatted strings by default, and empty trailing cells are left out of each row, which is why the mapper falls back to null.
Convert Google Sheets to JSON with Apps Script
Apps Script does the conversion inside Google: click Extensions > Apps Script, read the sheet's values into a 2D array, build objects from the header row and call JSON.stringify(). Deploy the script as a web app if you want a URL that returns the JSON.
It suits custom logic tied to one spreadsheet. The cost is a script to write and maintain for each sheet, while the export link in rows.page needs no code.
Keep the JSON in sync with the sheet
If a person needs the latest JSON, bookmark the https://rows.page/https://docs.google.com/... link. Google marks the export as no-store, so every visit downloads the current sheet.
If a script needs a stable URL, save the JSON and push it from a terminal:
# First push: prints the dataset link, an owner link and the command for the next version
curl -T data.json https://rows.page
# Push a new version (v2, v3) to the same link with the rpt_ owner token
curl -T data.json -H "Authorization: Bearer rpt_..." https://rows.page/<id>Each hosted dataset serves https://rows.page/<id>/raw.json (latest version, no-cache) and pinned versions such as https://rows.page/<id>/v1/raw.json, both with access-control-allow-origin: *. Without an account a link lasts 7 days and holds up to 20 versions; sign in with Google to keep it, and the Free plan keeps 10 datasets.
rows.page limits and prices
| What | Limit or price |
|---|---|
| Open a file in your browser | Files up to 1.5 GB, $0, no account, nothing uploaded |
| Share a link without an account | $0, files up to 100 MB, link deleted 7 days after creation |
| Free account | $0, 10 datasets kept, last 3 versions |
| Pro | $12/month, 100 datasets, files up to 500 MB, private links |
| Max | $39/month, 1,000 datasets, files up to 2 GB, private links |
Questions
Can I convert an .xlsx download from Google Sheets?
No. rows.page does not read .xlsx or .xls files, and pushing one returns "This looks like an Excel or zip file. Export it as CSV and push again." Download the tab as CSV or TSV instead.
How big a Google Sheet can rows.page convert to JSON?
Google Sheets stops at 20 million cells or 100 MB per spreadsheet, and rows.page reads CSV files up to 1.5 GB per browser tab. Google's export link downloads straight to your browser, so the 100 MB cap of the rows.page proxy does not apply.
What happens to cells that already hold JSON text?
If 90% or more of a column's values in the first 1,000 rows are JSON objects, rows.page expands the column into dot-path columns such as user.address.city, up to 8 levels deep and 200 child fields per object. Arrays stay list columns and export as real JSON arrays.
Can I drop rows or columns before exporting to JSON?
Yes. Export writes the current view, so filters, sort order, hidden columns and SQL results carry over. SQL results stop at 1,000,000 rows, while a filtered view exports every matching row.
Does rows.page keep a copy of my sheet?
No. A dropped CSV is read inside your browser and only uploaded if you choose to share it, and the export-link viewer stores nothing.