# Google Sheets Import: Read Sheet Rows to JSON/CSV (`ucchiii/google-sheets-import`) Actor

Read rows from a Google Sheet into an Apify dataset (JSON/CSV): public link or your service account, tab/range, headers, number/boolean/date types. Empty input = free demo. $0.05 per 1,000 rows.

- **URL**: https://apify.com/ucchiii/google-sheets-import.md
- **Developed by:** [Actor Factory](https://apify.com/ucchiii) (community)
- **Categories:** Integrations, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.00 / 1,000 1,000 rows reads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 — read Google Sheet rows into JSON/CSV, reliably

Turns any Google Sheet tab into an Apify dataset (export as JSON, CSV, Excel or via API) with real numbers, booleans and dates. **Built to just work**: retries on Google rate limits (429) and server errors, and when something is wrong it stops with a plain message ("sheet is not shared", "tab 'X' not found, tabs are: ...") instead of failing silently or returning nothing.

**For** developers, analysts and ops teams who keep input lists, keywords, URLs, prices or leads in a Google Sheet and want to feed them to scrapers, automations or AI pipelines.

- **No setup for public sheets**: share as "Anyone with the link" and paste the URL, no credentials
- **Private sheets**: use your own Google service account (the key is used only in memory and never logged or stored)
- **Clean data**: header row to column names (duplicates and blanks fixed), numbers / booleans / dates converted, empty rows skipped, tab and range selectable

Example output (one dataset item per sheet row):

```json
{ "Student Name": "Alexandra", "Gender": "Female", "Class Level": "4. Senior", "Home State": "CA",
  "Major": "English", "Extracurricular Activity": "Drama Club" }
```

**Price: $0.05 per 1,000 rows** saved (partial thousands round up). Example: a 2,500-row sheet costs 3 x $0.05 = **$0.15**; a 300-row sheet costs $0.05. Header rows, skipped empty rows and failed runs are not charged. Set a max charge per run to cap spend.

**Free demo**: leave the input empty and the Actor reads Google's public "Class Data" sample sheet (10 rows, not charged).

### Input

| Field | What it does |
|---|---|
| `spreadsheet` | Sheet URL or ID. A `#gid=` in the URL selects that tab. |
| `serviceAccountKey` | Optional. JSON key of your service account, for private sheets. |
| `sheetName` / `sheetGid` | Tab by name or by numeric gid. Default: the URL's gid, else the first tab. |
| `range` | A1 range such as `A1:F500`, `A:F`, `2:100`. Default: whole tab. |
| `headerMode`, `skipTopRows` | First row is the header (default) or no header (`column_1`, ...); skip title rows above it. |
| `coerceTypes`, `coerceNumbers`, `coerceBooleans`, `coerceDates`, `dateFormat` | Value conversion. Empty cells are `null`. ZIP-style values with leading zeros and numbers over 15 digits stay text. `03/31/2026`-style dates are converted only if you pick `mdy` or `dmy`. |
| `skipEmptyRows`, `maxRows` | Drop fully blank rows; stop after N data rows (default 10,000). |

```json
{ "spreadsheet": "https://docs.google.com/spreadsheets/d/1AbC.../edit#gid=0", "headerMode": "first", "maxRows": 5000 }
```

### Public sheet in 30 seconds

In Google Sheets click **Share > General access > Anyone with the link > Viewer**, copy the URL into `spreadsheet`, run.

### Private sheet (service account, about 5 minutes)

1. In [Google Cloud Console](https://console.cloud.google.com/) create or pick a project and enable the **Google Sheets API**.
2. **IAM & Admin > Service Accounts > Create service account** (no roles needed), then **Keys > Add key > JSON**.
3. Share your sheet with the account's **`client_email`** as **Viewer**.
4. Paste the whole JSON file into **Service account key**.

### Output

The default dataset has one item per sheet row. Run details are in the key-value store record `RESULT`: source, mode (`public-csv` or `api`), tab, columns, rows in sheet, rows saved, skipped empty rows, `truncatedAtMaxRows` and a `warning` if the tab was empty.

### Common problems

- **"the spreadsheet is not shared publicly"**: set sharing to "Anyone with the link" (Viewer), or use a service account key.
- **"Tab 'X' not found. Tabs in this spreadsheet: ..."** (service account): fix the name or use `sheetGid`.
- **Public sheet and tab by name**: Google's name-based CSV endpoint can drop cells in columns that mix numbers and text. Use `sheetGid` (or the `#gid=` in the URL) for exact values, or use a service account key.
- **403 with a service account**: share the sheet with the `client_email` and check the Sheets API is enabled.
- **"Key creation is disabled"**: many Google Workspace organizations block service account keys (`iam.disableServiceAccountKeyCreation`). Ask your admin, or create the project with a personal Google account.
- **Dates read as text**: only year-first dates (`2026-03-31`) are converted by default; choose `mdy` or `dmy` for slash dates.

### Billing and privacy

You are charged only for rows saved to the dataset. Your key stays in memory for the run and is never written to logs, the dataset or the key-value store. Use a dedicated service account with access only to the sheets you need. The Actor only reads; it never writes to your sheet.

### Pricing

Pay per event: **$0.05 per 1,000 rows** (partial thousands round up). The demo is free.

### More tools from the same developer

- [Google Sheets Export](https://apify.com/ucchiii/google-sheets-export) — export an Apify dataset to Google Sheets
- [Dataset Transform](https://apify.com/ucchiii/dataset-transform) — flatten, filter, rename and convert any Apify dataset, export CSV / JSON / JSONL with a link
- [Dataset Merge & Dedup](https://apify.com/ucchiii/dataset-dedup-merge) — merge Apify datasets and remove duplicates by the fields you choose
- [Dataset Change Detector](https://apify.com/ucchiii/dataset-change-detector) — compare two runs of any scraper: only added, removed and changed items
- [RAG Chunker](https://apify.com/ucchiii/rag-chunker) — split scraped pages into chunks for RAG and vector stores

# Actor input Schema

## `spreadsheet` (type: `string`):

The Google Sheet to read: paste its URL or the ID. Without a service account key the sheet must be shared as 'Anyone with the link' (Viewer). Leave empty for a free demo on a Google sample sheet (not charged).

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

Only for private sheets: paste the full JSON key of your own Google service account and share the sheet (Viewer) with its client_email. It is used only in memory during the run and is never logged or stored. Leave empty to read a public sheet.

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

Name of the tab to read, for example 'Leads'. If empty, the gid below or the #gid= in the URL is used, otherwise the first tab. With a public sheet and no key, prefer sheetGid for exact values.

## `sheetGid` (type: `integer`):

Numeric tab id: the number after #gid= in the browser URL (the first tab is usually 0). Used when the tab name is empty.

## `range` (type: `string`):

Cells to read in A1 notation, for example A1:F500, A:F or 2:100. Empty = the whole tab. The first row of the range is the header row.

## `headerMode` (type: `string`):

How to name the columns. Empty or duplicate headers are fixed automatically (column_3, name_2).

## `skipTopRows` (type: `integer`):

Ignore this many rows at the top (titles, notes) before the header row. Default 0.

## `coerceTypes` (type: `boolean`):

Master switch. On: cells that look like numbers, booleans (TRUE/FALSE) or dates become real JSON numbers, booleans and ISO dates; everything else stays text. Off: all values stay text. Empty cells are always null. Values with leading zeros (ZIP codes) stay text.

## `coerceNumbers` (type: `boolean`):

Cells like 42, -3.5, 1e6 or 1,234.50 become numbers. Needs 'Convert value types' on.

## `coerceBooleans` (type: `boolean`):

TRUE / FALSE (any case) become true / false. Needs 'Convert value types' on.

## `coerceDates` (type: `boolean`):

Cells like 2026-03-31, 2026/03/31 or 2026-03-31 14:30 become ISO text (2026-03-31, 2026-03-31T14:30:00). Needs 'Convert value types' on.

## `dateFormat` (type: `string`):

Slash and dot dates such as 03/31/2026 are ambiguous, so they are converted only if you choose the order here. Unconvertible values stay as text.

## `skipEmptyRows` (type: `boolean`):

Leave out rows where every cell is blank. Skipped rows are not charged.

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

Stop after this many data rows (header excluded). Rows beyond it are not saved or charged. Default 10,000.

## Actor input object example

```json
{
  "headerMode": "first",
  "skipTopRows": 0,
  "coerceTypes": true,
  "coerceNumbers": true,
  "coerceBooleans": true,
  "coerceDates": true,
  "dateFormat": "ymd",
  "skipEmptyRows": true,
  "maxRows": 10000
}
```

# Actor output Schema

## `rows` (type: `string`):

The rows of the sheet, one dataset item per row, columns named from the header row.

## `result` (type: `string`):

Record RESULT: source, tab, columns, rows saved, rows skipped and any warning.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ucchiii/google-sheets-import").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ucchiii/google-sheets-import").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 '{}' |
apify call ucchiii/google-sheets-import --silent --output-dataset

```

## MCP server setup

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

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/FqOuZBwzmGL2aSAg3/builds/8LkwSakj4vBTZ9P6Z/openapi.json
