{
  "openapi": "3.0.1",
  "info": {
    "title": "Dataset to Google Sheets Sync (append, replace, upsert)",
    "description": "Send any Apify dataset to a Google Sheet without OAuth: share the sheet with a service account, then append, replace or upsert by key. Retries Google rate limits, dedupes, never fails on an empty dataset.",
    "version": "0.1",
    "x-build-id": "RcLlsZiLJeQ1YatnF"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/osel_house~dataset-to-google-sheets/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-osel_house-dataset-to-google-sheets",
        "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/osel_house~dataset-to-google-sheets/runs": {
      "post": {
        "operationId": "runs-sync-osel_house-dataset-to-google-sheets",
        "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/osel_house~dataset-to-google-sheets/run-sync": {
      "post": {
        "operationId": "run-sync-osel_house-dataset-to-google-sheets",
        "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": [
          "spreadsheetUrl"
        ],
        "properties": {
          "spreadsheetUrl": {
            "title": "Google Sheet link",
            "type": "string",
            "description": "Paste the sheet's URL from your browser (or just its id). First share the sheet with the service account email shown in the README as an Editor. A #gid=... in the link selects that tab unless \"Tab name\" is set."
          },
          "sheetName": {
            "title": "Tab name",
            "type": "string",
            "description": "Which tab (worksheet) to write. Leave empty for the first tab. A missing tab is created when \"Create tab if missing\" is on."
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "append",
              "replace",
              "upsert"
            ],
            "type": "string",
            "description": "append = add rows under the existing ones. replace = clear the tab and write everything fresh. upsert = update rows whose key columns match, append the rest (needs Key fields).",
            "default": "append"
          },
          "keyFields": {
            "title": "Key fields (upsert)",
            "type": "array",
            "description": "Column(s) that identify a row, e.g. url or id. Required for upsert; also used for deduplication. Nested fields use dots: seller.id.",
            "items": {
              "type": "string"
            }
          },
          "deleteMissing": {
            "title": "Delete sheet rows missing from the data (upsert)",
            "type": "boolean",
            "description": "Upsert only: remove sheet rows whose key is not in this dataset, so the tab mirrors the dataset exactly. Off by default. Skipped automatically when the source has no items or was cut off by Max items, so one empty scrape cannot wipe the tab.",
            "default": false
          },
          "dedupe": {
            "title": "Remove duplicate rows",
            "type": "boolean",
            "description": "Drop repeated rows before writing (by Key fields, or whole-row identical when no keys are set); the last occurrence wins. Defaults to on for upsert, off otherwise."
          },
          "datasetId": {
            "title": "Dataset",
            "type": "string",
            "description": "The Apify dataset to send. When this Actor runs from another Actor's Integrations tab this is filled in with the finished run's dataset ({{resource.defaultDatasetId}}). A dataset always wins over the sample Rows below."
          },
          "rows": {
            "title": "Rows (instead of a dataset)",
            "type": "array",
            "description": "Optional JSON array of objects to write instead of a dataset. Handy for testing or for calling this Actor from your own code."
          },
          "columns": {
            "title": "Columns",
            "type": "array",
            "description": "Write only these data columns. On a new tab or in replace mode they appear in this order; an existing tab keeps its layout and new columns are added on the right. Columns your data does not include are never touched.",
            "items": {
              "type": "string"
            }
          },
          "limit": {
            "title": "Max items",
            "minimum": 1,
            "type": "integer",
            "description": "Read at most this many dataset items.",
            "default": 250000
          },
          "offset": {
            "title": "Skip items",
            "minimum": 0,
            "type": "integer",
            "description": "Skip this many dataset items before reading.",
            "default": 0
          },
          "flattenDepth": {
            "title": "Flatten nested objects (levels)",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Nested objects become dotted columns (address.city) down to this depth; anything deeper, and every array, is stored as JSON text in one cell.",
            "default": 2
          },
          "maxColumns": {
            "title": "Max columns",
            "minimum": 1,
            "type": "integer",
            "description": "Safety cap on the number of columns written; extra fields are dropped and listed in the run summary.",
            "default": 200
          },
          "parseValues": {
            "title": "Let Google parse values",
            "type": "boolean",
            "description": "Off (default): values are stored exactly as sent (text stays text). On: Google interprets them as if typed, so '2026-01-05' becomes a date and '=SUM(A1)' a formula.",
            "default": false
          },
          "createSheet": {
            "title": "Create tab if missing",
            "type": "boolean",
            "description": "Create the named tab when the spreadsheet does not have it.",
            "default": true
          },
          "resetSheetBinding": {
            "title": "Reset sheet link (Actor author only)",
            "type": "boolean",
            "description": "Each Google Sheet is linked to the first Apify account that syncs it, so nobody else can write to it through this Actor. The Actor's author runs this to unlink a sheet when a customer moves to a new Apify account. Nothing is written in that run.",
            "default": false
          },
          "serviceAccountJson": {
            "title": "Your own Google service account key (optional)",
            "type": "string",
            "description": "Paste the JSON key of your own Google Cloud service account to use your own Google quota instead of the shared one. Stored encrypted. Share the sheet with that account's email instead."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}