Google Sheets Sync – Reliable Import & Export
Pricing
from $0.30 / 1,000 row synceds
Google Sheets Sync – Reliable Import & Export
Import a Google Sheet into an Apify dataset or export a dataset/JSON into a Sheet tab. Public sheets need no auth; private sheets use your service-account JSON. Chunked writes with retries. $0.50 per 1,000 rows; failed writes are free.
Pricing
from $0.30 / 1,000 row synceds
Rating
0.0
(0)
Developer
Chris Elder
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 hours ago
Last modified
Categories
Share
Google Sheets Sync moves data between Apify and Google Sheets without the flaky timeouts that plague the popular free Sheets Actors. Import a public or private sheet into the default dataset; export an Apify dataset or pasted JSON into a sheet tab (append or replace), with nested objects flattened, batched writes and retries on 429/5xx.
Store page: apify.com/chris_elder/google-sheets-sync
✅ Pay per result: $0.50 per 1,000 rows synced · 🆓 Failed writes / reads are never charged · 🔑 You bring your own Google service account (no shared Google project)
▶ Try it with one click · 📄 Real example output · 💲 Pricing · 🔗 Use after any Actor run · 🔌 API & integrations · ❓ FAQ · 🛟 Support
What does Google Sheets Sync do?
- 📥 Import a Google Sheet tab into an Apify dataset (JSON/CSV/Excel download from Storage)
- 📤 Export an Apify dataset or pasted JSON rows into a Sheet tab (append or replace)
- 🌐 Public sheets need no auth – uses Google's CSV export URL (one-click prefill)
- 🔐 Private sheets use your service-account JSON; share the sheet with that email as Editor
- 📦 Flatten nested JSON into dotted columns (
meta.city) on export - 🔁 Chunked writes + retries with backoff on HTTP 429/5xx so large jobs do not time out
- 🆘 Actionable errors for the usual failures: sheet not shared, wrong ID, Sheets API not enabled, bad JSON
- 🆓 Failed rows free – only successfully synced rows are charged
Use cases
- Scraper users – push a run's dataset into Google Sheets for ops / clients without writing Apps Script
- Agents & n8n/Make/Zapier – "write this dataset to Sheet X" or "read Sheet Y into Apify" as one step
- Analysts – pull a public reporting sheet into Apify for further Actors (e.g. Dataset Transformer)
- Teams on private Sheets – keep credentials in your Google Cloud project; nothing is shared with GPT Shop Ltd
How to use it
- Click Try for free – the prefill imports Google's public sample "Class Data" sheet (no service account). Expect about 30 student rows for roughly $0.015 (start + rows at Free tier).
- For a private sheet or any export, create a Google Cloud service account (2 minutes – see below), paste the JSON into
serviceAccountJson, and Share the sheet with theclient_emailas Editor. - Download the dataset from the run's Storage tab, or open the Sheet to see exported rows.
Service account setup (export & private import) – about 2 minutes
- Open Google Cloud Console → create or pick a project.
- APIs & Services → Library → "Google Sheets API" → Enable.
- IAM & Admin → Service accounts → Create → open the account → Keys → Add key → JSON → download the file.
- Open your Google Sheet → Share → paste the
client_emailfrom the JSON → role Editor → uncheck "Notify people" → Share. - Paste the entire JSON file into the Actor input field
serviceAccountJson(secret; never logged).
You do not need to give GPT Shop Ltd or Apify access to your Google account. The key stays in your Actor run input.
Input example (public import – prefill)
{"mode": "import","spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms","sheetName": "Class Data","maxRows": 30}
Input example (export)
{"mode": "export","spreadsheetId": "YOUR_SHEET_ID","sheetName": "Apify Export","writeMode": "replace","flattenNested": true,"datasetId": "YOUR_DATASET_ID","serviceAccountJson": "{ \"type\": \"service_account\", \"client_email\": \"...\", \"private_key\": \"...\" }","maxRows": 5000}
Other options: items (paste JSON instead of datasetId), dryRun (free export preview, nothing written), gid (public import), range (A1 range for private import).
Output example (from a real public run)
Public run data (no login needed): dataset JSON · dataset CSV · RUN_SUMMARY · console run
First dataset item:
{"Student Name": "Alexandra","Gender": "Female","Class Level": "4. Senior","Home State": "CA","Major": "English","Extracurricular Activity": "Drama Club"}
RUN_SUMMARY from that run (30 rows charged; platform usage ≈ $0.000055):
{"mode": "import","spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms","sheetName": "Class Data","auth": "public_csv","rowsRead": 30,"rowsSynced": 30,"skippedBudget": 0,"budgetHit": false,"clientEmail": null}
| Field | Meaning |
|---|---|
mode | import or export |
rowsSynced | Rows charged (successfully written to dataset or Sheet) |
auth | public_csv or service_account (import) |
sheetTitle / headers | Export: tab written and column headers used |
budgetHit | Stopped early because of Max cost per run |
How much does it cost to sync Google Sheets?
| Event | Free / Bronze | Silver | Gold+ |
|---|---|---|---|
| Actor start (× memory GB, min 1) | $0.0005 | $0.0005 | $0.0005 |
| Row synced | $0.0005 | $0.0004 | $0.0003 |
Failed, skipped and invalid rows are free. Only rows successfully imported into the dataset or written to the Sheet are charged.
| Job | Approx. cost |
|---|---|
| Prefill import (~30 rows, 512 MB) | 30 × $0.0005 + $0.0005 start ≈ $0.0155 |
| 1,000 rows import or export | $0.50 + start |
| 10,000 rows (Gold) | 10,000 × $0.0003 = $3.00 + start |
Use Max cost per run to cap spend; the Actor stops syncing when the cap is reached (budgetHit: true in RUN_SUMMARY).
Use as an integration after any Actor run
Send every new scraper result to a Sheet automatically, with no code:
- Open the Actor (or saved task) whose results you want in Sheets → Integrations tab → Add integration → search Google Sheets Sync.
- Start when: Run succeeded.
- Input:
mode=export,datasetId={{resource.defaultDatasetId}}(Apify swaps in the triggering run's dataset and grants this Actor read access to just that dataset), plus yourspreadsheetId,sheetName,writeMode(appendkeeps history,replacekeeps only the latest run) and yourserviceAccountJson. - Click Test with a past run. Turn on
dryRunfirst to preview the column headers and 3 sample rows for free (nothing is written to Google, no service account needed). Then turndryRunoff.
{"mode": "export","spreadsheetId": "YOUR_SHEET_ID","sheetName": "Scraper results","writeMode": "append","datasetId": "{{resource.defaultDatasetId}}","serviceAccountJson": "{ ...your key JSON... }"}
The dataset is read in pages of 1,000 items (up to maxRows), and RUN_SUMMARY records which run triggered the export (triggeredBy). The Actor keeps Apify's limited permissions: it can read only the dataset you pass in datasetId, nothing else in your account.
Integrations (API, AI agents, Make, Zapier)
curl -X POST "https://api.apify.com/v2/acts/chris_elder~google-sheets-sync/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"mode":"import","spreadsheetId":"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms","sheetName":"Class Data","maxRows":30}'
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("chris_elder/google-sheets-sync").call(run_input={"mode": "export","spreadsheetId": "YOUR_SHEET_ID","sheetName": "Export","writeMode": "append","datasetId": "YOUR_DATASET_ID","serviceAccountJson": open("sa.json").read(),})print(client.dataset(run["defaultDatasetId"]).list_items().items)
- MCP:
https://mcp.apify.com/?tools=chris_elder/google-sheets-sync - Make / Zapier / n8n: module Run Actor →
chris_elder/google-sheets-sync - Chain after scrapers: add it on the scraper's Integrations tab (see above), or pass the previous run's
defaultDatasetIdasdatasetId - Pair with Dataset Transformer to clean/dedupe before export
Limits and good to know
- Public import requires the sheet to be viewable by anyone with the link (or fully public). Otherwise use a service account.
- Export and private import need the Google Sheets API enabled on your Cloud project and the sheet shared with the service account email.
- Very large sheets: raise memory if needed; writes are chunked (500 rows) with retries. Soft cap via
maxRows(default 50,000). - Nested objects are flattened on export; arrays become JSON strings in a single cell.
- This Actor does not use any Google Cloud project owned by GPT Shop Ltd / Chris Elder. Your key, your project, your quotas.
Is it legal?
You must only sync spreadsheets you own or are allowed to access. The Actor calls Google's documented Sheets API / public CSV export using credentials you supply. Follow Google APIs Terms and Apify's legal / ToS guidance. Do not scrape or export personal data unlawfully.
Need the data done for you?
If you'd rather not set up runs yourself, the UK company behind these tools (GPT Shop Ltd) offers a fixed-price done-for-you scrape. Tell us the website and the fields you need, and you get a clean CSV or Google Sheet within 48 hours of the confirmed brief, up to 5,000 rows, for £149 or $179. If we can't get the data, you're refunded in full. See the done-for-you scraper service
FAQ
Do I need a Google API key from you?
No. Public import needs nothing. Private import and export use a service account you create. We never ask for your Google password.
Why did I get "Permission denied"?
Share the Sheet with the exact client_email from your JSON as Editor, and enable the Google Sheets API on that Cloud project. The error message repeats both steps.
Why did public import return an HTML page error?
The sheet is not link-shared for viewing. Change sharing to "Anyone with the link → Viewer", or switch to a service account.
Can I append without wiping the sheet?
Yes – writeMode: "append" (default). Use "replace" to clear the tab and rewrite header + rows.
Are failed writes charged?
No. Only successfully synced rows trigger the row-synced event.
How is this different from lukaskrivka/google-sheets?
That Actor has hundreds of monthly users but a high public failure rate. This one focuses on chunked writes, retries, public-CSV import without OAuth, and errors that tell you exactly what to fix. Pricing is pay-per-event so idle failures cost you nothing.
Support, reliability and feature requests
- Failed items are free.
- Every release is tested on real public inputs; the one-click example works.
- Issues answered within 2 business days via the Actor Issues tab.
- Breaking input or price changes are announced in this README first.
Built by Chris Elder with AI-assisted development; every release is reviewed and tested. Tested on: Google's public Class Data sample spreadsheet (import), mocked Sheets API (export unit tests).
More tools by Chris Elder
- Dataset Transformer – filter, dedupe, flatten, JSON↔CSV before you export
- Bulk File Downloader
- HTTP Request Sender
- All tools: apify.com/chris_elder