{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Sheet Monitor API - Track Row Changes on a Schedule",
    "description": "Watch a Google Sheet and get told what moved. Every row comes back stamped added, updated, removed or unchanged against the previous run, so a schedule becomes a change feed for Slack, a webhook or another Actor. Unchanged rows are never billed, so an hourly cron stays affordable.",
    "version": "1.0",
    "x-build-id": "Nlvh47Lix5sBfs6Pk"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/vonsensey~google-sheet-monitor-change-tracker-scraper-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-vonsensey-google-sheet-monitor-change-tracker-scraper-api",
        "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/vonsensey~google-sheet-monitor-change-tracker-scraper-api/runs": {
      "post": {
        "operationId": "runs-sync-vonsensey-google-sheet-monitor-change-tracker-scraper-api",
        "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/vonsensey~google-sheet-monitor-change-tracker-scraper-api/run-sync": {
      "post": {
        "operationId": "run-sync-vonsensey-google-sheet-monitor-change-tracker-scraper-api",
        "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",
        "properties": {
          "url": {
            "title": "Sheet URL",
            "type": "string",
            "description": "The sheet's share link — copy it from Share → Copy link while the sheet is shared as 'Anyone with the link → Viewer'. Also accepted: the export/gviz/published-to-web CSV URL, the htmlview link, or the bare spreadsheet ID. No Google sign-in, no OAuth screen and no Drive permission prompt.",
            "default": "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit?usp=sharing"
          },
          "urls": {
            "title": "More sheet URLs",
            "type": "array",
            "description": "Optional. Extra sheets to read in the SAME run — paste one share link per line. Every row is stamped with the spreadsheet it came from, so twelve client sheets come back in one dataset and one schema. The row budget is split across the sheets so the first one cannot eat it.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "spreadsheetId": {
            "title": "Spreadsheet ID (advanced)",
            "type": "string",
            "description": "Optional. The long ID from the sheet URL, used directly instead of parsing the URL. It replaces the Sheet URL above when both are set; any entries in More sheet URLs are still read as well."
          },
          "tabs": {
            "title": "Tabs",
            "type": "array",
            "description": "Optional. Sheet tab names or gid numbers to read, e.g. `Leads` or `0`. Leave empty to read every tab — all tabs come back in one run and one schema, with the tab name on every row.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "query": {
            "title": "Query (SQL-like)",
            "type": "string",
            "description": "Optional. Google's visualization query language, executed by Google before any rows are returned: `select A, B where C > 100 order by B desc limit 50`. Column letters refer to the sheet's columns. Link mode only — the Sheets API ignores it."
          },
          "headersRow": {
            "title": "Header row",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "The row the column names live on. 1 is the sheet's first row. Set 0 when the sheet has no header row and columns will be named A, B, C… like the sheet's own column letters.",
            "default": 1
          },
          "skipRows": {
            "title": "Rows to skip after the header",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Optional. How many rows to drop between the header and the data — for sheets that carry a title or a blank line under the header. Rows skipped here are never billed.",
            "default": 0
          },
          "typed": {
            "title": "Typed values",
            "type": "boolean",
            "description": "On: numbers come back as numbers, booleans as booleans, dates as ISO-8601 strings — ready for JSON pipelines, spreadsheets and LLM prompts. Off: every value is the exact text the sheet displays.",
            "default": true
          },
          "trimEmpty": {
            "title": "Drop empty columns and rows",
            "type": "boolean",
            "description": "Sheets carry invisible trailing columns and blank rows from edits long deleted. On drops columns that have no header and no data in any row, and rows that are completely empty.",
            "default": true
          },
          "includeMetadata": {
            "title": "Emit a sheet metadata row",
            "type": "boolean",
            "description": "Adds one free row describing what was read: the spreadsheet title, every tab with its gid, and the per-tab row counts.",
            "default": false
          },
          "maxItems": {
            "title": "Maximum rows",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "Hard ceiling on billable rows for the whole run, split evenly across the sheets you gave. Free rows — errors, coverage, removed-row notices, the summary — never count against it.",
            "default": 1000
          },
          "maxCostUsd": {
            "title": "Cost ceiling (USD)",
            "minimum": 0.01,
            "maximum": 1000,
            "type": "number",
            "description": "A backstop, not an estimate: the run stops delivering and reports budgetReached once billed rows would cost more than this. The default sits well above a full 1,000-row run at every rate, so the row cap is what normally stops a run — lower it if you want a tighter guard.",
            "default": 25
          },
          "monitor": {
            "title": "Monitor for changes",
            "type": "boolean",
            "description": "Remembers what each sheet looked like last run (key-value store, scoped to this Actor) and stamps every row: added, updated, unchanged, or removed. Pair with a schedule to watch a living sheet — unchanged rows are never billed, so a quiet sheet on an hourly cron costs only its per-sheet sync fee.",
            "default": true
          },
          "monitorChangesOnly": {
            "title": "Return only changes",
            "type": "boolean",
            "description": "When monitoring, emit only added, updated and removed rows — unchanged rows are counted in the free coverage row but not delivered, and are never billed.",
            "default": false
          },
          "monthlyPass": {
            "title": "Monthly pass (30 days, no per-row or per-sync charges)",
            "type": "boolean",
            "description": "Charge one monthly pass instead of paying per row and per sheet sync. Charged once, right before the first charge of the run would be billed, and only again after 30 days if you run with this on. While it is active every run you start with this on delivers rows and sheet syncs without per-unit charges. Worth it above roughly 3,800 billed rows or 1,300 sheet syncs a month. Keep Cost ceiling (USD) above the pass price, or the run stops before the pass is charged.",
            "default": false
          },
          "mode": {
            "title": "Access mode (advanced)",
            "enum": [
              "auto",
              "link",
              "apiKey",
              "serviceAccount"
            ],
            "type": "string",
            "description": "Auto picks by what you supplied: a service-account key if present, else an API key, else plain link access. Force one only when Google's endpoints misbehave.",
            "default": "auto"
          },
          "googleApiKey": {
            "title": "Google API key (optional)",
            "type": "string",
            "description": "Optional. A Google Cloud API key with the Sheets API enabled. Gives exact tab names and gids from the official API instead of the public HTML page. The sheet must still be link-shared; a key alone cannot read a Restricted sheet."
          },
          "serviceAccountKey": {
            "title": "Service account JSON (private sheets)",
            "type": "string",
            "description": "Optional. The full JSON key of a Google Cloud service account. Share the sheet with the account's email (Share → add editor-less viewer) and this Actor reads PRIVATE sheets through the official Sheets API — the only way to reach a sheet that is not link-shared. Billed at the private-sheet rate."
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}