# Google Sheets Import & Export (Reliable) (`ensorcelling_melilot/google-sheets-sync`) Actor

- **URL**: https://apify.com/ensorcelling_melilot/google-sheets-sync.md
- **Developed by:** [ensorcelling \_melilot](https://apify.com/ensorcelling_melilot) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 row writtens

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Sheets Import & Export (Reliable)

Send the results of **any Apify Actor** to **Google Sheets**, or pull a sheet into a dataset. It's built to not fail:

- **Rate limits are retried automatically.** Google allows about 60 writes a minute. When you hit that, this Actor waits and retries instead of crashing with nothing written.
- **Append really appends.** New rows go under your existing data, and your columns never get reshuffled. New fields become new columns at the end.
- **Upsert by key.** It updates rows whose `id` or `url` already exists and adds the rest, so you can run it daily and get no duplicates.
- **Checks the cell limit before writing.** If the data won't fit in Google's 10M-cell limit, you get a clear message and your sheet is left untouched. Nothing gets half-written.
- **No surprise conversions.** By default values are written exactly as they are, so `1.10` stays `1.10` and IDs don't turn into dates.
- **Long values are safe.** Text over Google's 50,000-character cell limit is truncated instead of failing the run.

### Use it as an integration (most common)

1. Open the Actor whose results you want in Sheets (for example Google Maps Scraper), then go to **Integrations** and choose **Apify Actor**.
2. Pick this Actor, set the spreadsheet URL, key and write mode, and set **Dataset ID** to `{{resource.defaultDatasetId}}`.
3. Every time that Actor finishes, its dataset lands in your sheet automatically.

You can also run it on its own with a **Dataset ID**, or paste JSON into **Raw data**.

### One-time setup: a Google service account (about 2 minutes)

A service account is a robot Google user. It never expires and doesn't need you to log in again.

1. Go to [console.cloud.google.com](https://console.cloud.google.com/). Create a project (any name) or pick an existing one.
2. Enable the **Google Sheets API**: open APIs & Services, then Library, search "Google Sheets API" and click **Enable**.
3. Go to APIs & Services, then **Credentials**, then **Create credentials** and choose **Service account**. Give it any name and click **Done**.
4. Click the new service account, open **Keys**, choose **Add key**, then **Create new key**, then **JSON**. A `.json` file downloads.
5. Open that file, copy **everything**, and paste it into **Google service account key**. It's stored encrypted.
6. Open your spreadsheet, click **Share**, and add the service account's email (it ends with `iam.gserviceaccount.com`) as an **Editor**.

That's it. If you forget step 6, the run tells you exactly which email to share with.

### Modes

| Mode | What it does |
|---|---|
| Export → **Append** | Adds rows under the existing data. Existing columns stay where they are. |
| Export → **Replace** | Clears the tab and writes fresh data. |
| Export → **Upsert** | Matches rows on **Key column**, updates matches (columns your data does not include are left as they are) and appends new rows. |
| **Import** | Reads the tab (first row = headers) into the run's dataset. A sheet shared as "Anyone with the link can view" can be imported with no key at all. |

The tab is created automatically if it doesn't exist.

### Pricing

You pay per row written or read, and nothing for failed runs. See the pricing tab.

### FAQ

**Why a service account instead of "Sign in with Google"?** Sign-in tokens expire and are the most common reason sheet exports break. A service account keeps working.

**How big can it go?** Up to Google's limit of 10 million cells per spreadsheet. The Actor checks this before writing.

**Nested data?** By default `{"address": {"city": "Paris"}}` becomes a column `address/city`. Turn off **Flatten nested data** to write JSON text instead.

**Problem or feature request?** Open an issue on the Issues tab.

# Actor input Schema

## `spreadsheetId` (type: `string`):

Paste the full Google Sheets URL or just its ID.

## `serviceAccountKey` (type: `string`):

Paste the whole JSON key file of a Google service account, then share your spreadsheet with that account's email as Editor. 2-minute setup in the README. Not needed to import a sheet shared as "Anyone with the link can view".

## `mode` (type: `string`):

Export writes data into the sheet. Import reads the sheet into this run's dataset.

## `sheetName` (type: `string`):

Created automatically if it doesn't exist.

## `writeMode` (type: `string`):

Append adds rows below existing data. Replace clears the tab first. Upsert updates rows whose key already exists and adds the rest.

## `keyColumn` (type: `string`):

Column that uniquely identifies a row, e.g. url or id.

## `datasetId` (type: `string`):

Dataset to export. When you add this Actor as an integration after another Actor, set this to {{resource.defaultDatasetId}}.

## `rawData` (type: `array`):

Alternatively, paste an array of objects to export.

## `fields` (type: `array`):

Export only these top-level fields, in this order. Leave empty for all.

## `flattenData` (type: `boolean`):

Turn nested objects into columns like address/city. If off, nested values are written as JSON text.

## `delimiter` (type: `string`):

Separator used in flattened column names, e.g. address/city.

## `valueInputOption` (type: `string`):

Raw keeps values exactly as they are (recommended; no surprise date or number conversions). User entered makes Google parse them like typed input, including formulas.

## `maxRows` (type: `integer`):

Stop after this many rows. Leave empty for no limit.

## Actor input object example

```json
{
  "spreadsheetId": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit",
  "mode": "export",
  "sheetName": "Sheet1",
  "writeMode": "append",
  "flattenData": true,
  "delimiter": "/",
  "valueInputOption": "RAW"
}
```

# Actor output Schema

## `summary` (type: `string`):

Spreadsheet link, sheet name, and how many rows were added, updated or skipped (export) or read (import).

## `importedRows` (type: `string`):

Rows read from the sheet in import mode, one item per row keyed by the header row.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "spreadsheetId": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ensorcelling_melilot/google-sheets-sync").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "spreadsheetId": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit" }

# Run the Actor and wait for it to finish
run = client.actor("ensorcelling_melilot/google-sheets-sync").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "spreadsheetId": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit"
}' |
apify call ensorcelling_melilot/google-sheets-sync --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ensorcelling_melilot/google-sheets-sync"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/8ex5ITZVHH83VhBZv/builds/A5KmhRhHBGmwkTro9/openapi.json
