Ctrio Lab · Updated 2026-10-24
Google Sheets and Apify: export a dataset to a sheet, import a sheet to JSON
Our Google Sheets Import & Export Actor on Apify does two jobs. Export writes an Apify dataset (for example the results of another Actor run) or inline JSON rows into a Google Sheets tab. Import reads a tab or an A1 range into the run's dataset, one JSON object per row.
mode to import and paste the sheet URL. No key is needed. To write to a sheet, or to read a private one, paste a Google service account JSON key and share the sheet with the key's client_email.Inputs
| Field | What it does |
|---|---|
mode | import (sheet to dataset) or export (dataset or JSON rows to sheet). |
spreadsheet | Sheet URL or ID. Without a key, the #gid= part of the URL picks the tab. |
serviceAccountKey | The whole JSON key file of a Google Cloud service account. Stored encrypted. Needed for export and private sheets. |
sheetName, range | Tab name (needs a key; export creates the tab if missing) and an optional A1 range for import, such as A1:F500. |
datasetId, rows | What to export: an Apify dataset ID (in an integration, {{resource.defaultDatasetId}}) or inline JSON rows. |
writeMode | append adds rows below the existing data; replace writes the new table from A1, then clears the rest of the tab. |
dedupeKey | On append, skip rows whose value in this column already exists in the sheet. Skipped rows are not charged. |
columns, columnNames | Keep only some columns in your order, and rename them. |
Example: import a public sheet
{
"mode": "import",
"spreadsheet": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit#gid=0",
"range": "A1:F31"
}
This reads Google's sample class data sheet. On 2026-10-24 the run returned 30 rows in about 3 seconds. The first two:
[
{ "Student Name": "Alexandra", "Gender": "Female", "Class Level": "4. Senior",
"Home State": "CA", "Major": "English", "Extracurricular Activity": "Drama Club" },
{ "Student Name": "Andrew", "Gender": "Male", "Class Level": "1. Freshman",
"Home State": "SD", "Major": "Math", "Extracurricular Activity": "Lacrosse" }
]
With "columns": ["Student Name", "Major", "Home State"] and "columnNames": {"Student Name": "name", "Major": "major", "Home State": "state"} the same rows come back as {"name": "Alexandra", "major": "English", "state": "CA"}.
Example: export another Actor's results
Add the Actor as an integration to your scraper and set the dataset to {{resource.defaultDatasetId}}. Every finished run then lands in the sheet:
{
"mode": "export",
"spreadsheet": "https://docs.google.com/spreadsheets/d/<ID>/edit",
"serviceAccountKey": "{ ...contents of your JSON key... }",
"sheetName": "Leads",
"datasetId": "{{resource.defaultDatasetId}}",
"writeMode": "append",
"dedupeKey": "url"
}
Nested fields become columns with /: {"address": {"city": "Paris"}} becomes the column address/city. On append, rows are matched to the existing header by name, and new fields are added as new columns at the right end.
Service account key in four steps
- In Google Cloud Console, pick a project and enable the Google Sheets API.
- IAM & Admin, Service Accounts, Create service account. No roles are needed. Then Keys, Add key, Create new key, JSON.
- Paste the whole JSON file into the Actor's key field.
- In Google Sheets, share the sheet with the
client_emailfrom the file: Editor for export, Viewer for import.
Coming from lukaskrivka/google-sheets
| Old input | Here |
|---|---|
mode: "append" or "replace" | mode: "export" with writeMode: "append" or "replace" |
mode: "read" | mode: "import" (rows go to the dataset) |
spreadsheetId | spreadsheet (ID or URL) |
deduplicateByField | dedupeKey |
columnsOrder | columns |
| Google account connection | serviceAccountKey |
Not included: modify, load backup and the custom transform function.
Limits
- A spreadsheet holds at most 10,000,000 cells across all tabs. The Actor checks this before writing anything.
- Google allows about 60 write requests per minute per user. The Actor writes up to about 1.5 MB per request and retries on HTTP 429.
- Cells longer than 50,000 characters are cut, and the log says how many.
- Apify input is limited to 9 MB, so put large data in a dataset rather than inline rows.
- Only real Google Sheets. An .xlsx file in Drive must first be saved as Google Sheets.
Price
$0.05 per 1,000 rows read or written, plus $0.002 per run. Rows skipped as duplicates are free. A daily export of 2,000 rows costs $0.102 per run. Higher Apify plans get up to 30% off the row price.
Open Google Sheets Import & Export Merge and deduplicate Apify datasets
FAQ
Do I need a Google key to read a sheet?
Not for a sheet shared as "Anyone with the link can view". Import works without a key, and the #gid= part of the URL picks the tab. Private sheets and every export need a Google service account JSON key.
Why a service account key instead of signing in with Google?
A service account key does not expire like a browser sign-in token, so scheduled runs keep working. You share the sheet with the client_email from the key file.
Sources: Google Sheets API usage limits; Google Drive file size limits; our own run on 2026-10-24.