{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Sheets Export & Import: Dataset to Sheet, No Failed Runs",
    "description": "Writes an Apify dataset, JSON or CSV to a Google Sheet (append, replace, update by key) or imports a sheet. Waits out Google's 429 limit, no duplicate rows, rolls over at the cell cap. Inputs: spreadsheet, mode, datasetId. $0.005 per job + $0.0002 per row. Agent-ready via x402 and MCP, no OAuth.",
    "version": "0.1",
    "x-build-id": "5ehNpAnAQpLVT1BYb"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nerolabs~google-sheets-export/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nerolabs-google-sheets-export",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/nerolabs~google-sheets-export/runs": {
      "post": {
        "operationId": "runs-sync-nerolabs-google-sheets-export",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/nerolabs~google-sheets-export/run-sync": {
      "post": {
        "operationId": "run-sync-nerolabs-google-sheets-export",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "spreadsheet"
        ],
        "properties": {
          "spreadsheet": {
            "title": "Spreadsheet",
            "type": "string",
            "description": "The Google Sheet link (or its ID). Before the first run, open the sheet, click Share, add nerolabs-sheets@nero-labs-sheets.iam.gserviceaccount.com as an Editor and untick 'Notify people'. No Google login or OAuth step is needed, so it also works from the API, schedules, n8n, Make, Zapier and AI agents. The prefilled demo sheet belongs to Nero Labs and is cleared on every run; use your own sheet for real data."
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "append",
              "replace",
              "update",
              "import"
            ],
            "type": "string",
            "description": "append adds rows after the last row with data. replace writes the new rows over the old ones, then removes old rows left below (the sheet is never left empty while it works). update matches rows on 'Key column' and changes only the fields your data has, adding rows for new keys. import reads the tab into this run's dataset (first row = column names). In every mode the sheet's own column order is kept and new fields are added as new columns on the right.",
            "default": "append"
          },
          "sheetName": {
            "title": "Tab name",
            "type": "string",
            "description": "Which tab to use. Created if it does not exist. Leave empty to use the tab in your link (#gid=...) or the first tab."
          },
          "datasetId": {
            "title": "Dataset",
            "type": "string",
            "description": "The Apify dataset to send to the sheet, for example a scraper run's results. In an integration (run after another Actor) use {{resource.defaultDatasetId}}. Picked this way so the Actor runs with limited permissions: it can read the dataset you choose and nothing else on your account."
          },
          "rawData": {
            "title": "Raw data",
            "type": "array",
            "description": "A JSON array of objects to send instead of a dataset. Each object becomes a row; its keys become columns."
          },
          "fileUrl": {
            "title": "File link",
            "type": "string",
            "description": "A link to a CSV, TSV, Excel (.xlsx, first sheet), JSON or JSON Lines file to send instead of a dataset. Up to 100 MB. The download is not charged."
          },
          "keyColumn": {
            "title": "Key column (update mode)",
            "type": "string",
            "description": "Update mode only. The field that identifies a row, such as url, id, sku or email. It must be a column in the sheet's header row (or in your data, for a new tab). Rows whose key matches are updated in place; only the fields present in your data are written, so other cells (formulas, notes, your own columns) are left alone. Matching ignores spaces at either end."
          },
          "addNewRows": {
            "title": "Add rows for new keys",
            "type": "boolean",
            "description": "Update mode only. On: rows whose key is not in the sheet yet are added at the bottom (an upsert). Off: they are skipped and not charged.",
            "default": true
          },
          "columns": {
            "title": "Columns to export",
            "type": "array",
            "description": "Optional. Only these fields, in this order (nested fields as parent/child, for example address/city). Leave empty to export every field. Columns already in the sheet keep their position either way.",
            "items": {
              "type": "string"
            }
          },
          "flatten": {
            "title": "Flatten nested fields",
            "type": "boolean",
            "description": "On: nested objects become their own columns named parent/child (the same names Apify's CSV export uses). Lists of plain values go in one cell separated by '; '; lists of objects go in one cell as JSON. Off: every nested value is written as JSON text.",
            "default": true
          },
          "parseValues": {
            "title": "Let Google read values (dates, numbers, formulas)",
            "type": "boolean",
            "description": "Off (safe default): every value is written exactly as it is, so text starting with = or + stays text. On: values are entered as if typed into Google Sheets, so '2026-10-29' becomes a date and '=SUM(B2:B9)' becomes a formula.",
            "default": false
          },
          "importValues": {
            "title": "Import values as",
            "enum": [
              "formatted",
              "unformatted"
            ],
            "type": "string",
            "description": "Import mode only. Formatted gives the text you see (for example '£1,200.00'); unformatted gives the underlying value (1200).",
            "default": "formatted"
          },
          "limit": {
            "title": "Max rows",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Send (or import) at most this many rows. 0 or empty = all, up to 2,000,000 per run."
          },
          "offset": {
            "title": "Skip first rows",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Skip this many rows of the source (or of the sheet, in import mode) first."
          },
          "overflowSpreadsheets": {
            "title": "Overflow spreadsheets",
            "type": "array",
            "description": "Optional. Extra Google Sheets (links or IDs, each shared with the same service account email) to continue in when the main one reaches Google's limit of 10 million cells. Rows carry on in the same tab name with the same columns. Without one, rows that do not fit are listed, saved as UNWRITTEN_ROWS.csv and not charged; nothing is dropped silently. Not used in update mode.",
            "items": {
              "type": "string"
            }
          },
          "rowsPerTab": {
            "title": "Rows per tab",
            "minimum": 0,
            "type": "integer",
            "description": "Optional, append and replace modes. Start a new tab ('Sheet1 2', 'Sheet1 3' ...) after this many data rows, to keep big tabs fast. 0 or empty = no limit."
          },
          "maxCellsPerSpreadsheet": {
            "title": "Cell limit per spreadsheet",
            "minimum": 100,
            "maximum": 10000000,
            "type": "integer",
            "description": "Advanced. When to move on to the next overflow spreadsheet. Google's own limit is 10,000,000 cells across all tabs; set it lower to keep sheets lighter.",
            "default": 10000000
          },
          "rowsPerRequest": {
            "title": "Rows per request",
            "minimum": 10,
            "maximum": 50000,
            "type": "integer",
            "description": "Advanced. How many rows go to Google in one write (each write is also kept under about 1.5 MB). Large batches mean fewer requests and fewer chances to hit Google's 60 writes a minute limit.",
            "default": 10000
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}