> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automate.ax/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Automate.ax automations are TypeScript programs.
> Use Bun for installation and command examples.
> Use Automate.ax for the product name and automate.ax for the package, CLI, and domain.
> Treat documented public APIs as current; do not invent transitional or deprecated names.

# On cells changed

> Run an automation when formulas or effective cell values change in Google Sheets.

`googleSheets.onCellsChanged` emits batches of net cell changes after Google reports that a spreadsheet changed. Use it to react to edited values, formulas, recalculated results, cleared cells, and populated cells.

## Example

```ts theme={null}
import { automation } from "automate.ax"
import { googleSheets } from "automate.ax/google-sheets"

export default automation("Handle order changes", () => {
  const batch = googleSheets.onCellsChanged({
    spreadsheet: "https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit",
    range: "'Orders'!A2:F",
  })

  batch.changes.forEach((change) => {
    change.cell.a1
    change.before.value
    change.after.value
  })
})
```

You can also describe the range with one-based coordinates:

```ts theme={null}
const batch = googleSheets.onCellsChanged({
  spreadsheet: "SPREADSHEET_ID",
  range: {
    sheet: 123456789,
    startRow: 2,
    startColumn: 1,
    endColumn: 6,
  },
})
```

## Options

* `spreadsheet` is a static spreadsheet ID or standard Google Sheets URL.
* `range` optionally limits deliveries. Pass an A1 string or an object with `sheet` plus inclusive, one-based `startRow`, `endRow`, `startColumn`, and `endColumn` bounds. Omitted ending bounds are unbounded. Omit `range` to monitor every sheet.
* `account` is an optional static Google Account binding.

A1 strings accept cells and two-ended ranges, including `A1`, `A1:C10`, `A:C`, `1:10`, `A1:C`, and `A:C10`. Quote sheet titles that contain spaces or punctuation, and double embedded apostrophes: `'Lead''s Sheet'!A1:C10`.

An A1 range without a sheet prefix applies to the spreadsheet's first visible sheet.

Use a numeric `sheet` ID in the object form when the trigger should survive sheet-title changes.

## Trigger data

```ts theme={null}
type CellsChangedEvent = {
  spreadsheet: {
    id: string
    title: string
    url: string
  }
  observedAt: string
  chunk: {
    index: number
    total: number
  }
  changes: Array<{
    sheet: {
      id: number
      title: string
    }
    cell: {
      a1: string
      row: number
      column: number
    }
    before: CellState
    after: CellState
  }>
}

type CellState = {
  value: string | number | boolean | null
  formula?: string
  error?: {
    type: string
    message?: string
  }
}
```

`value` is Google's effective value without display formatting. A cleared or empty cell uses `null`. Formula cells also include the user-entered formula, so replacing `=1` with the literal value `1` still counts as a change. Formatting-only edits do not trigger a batch.

One observation can produce several batches of up to 500 changes. `chunk.index` starts at `0`; `chunk.total` is the number of batches created for that trigger and range.

## Observation semantics

Google reports that the file changed but does not provide a cell-level edit log. Automate.ax reads the current spreadsheet and compares it with the preceding complete observation. The trigger therefore reports net differences, not every intermediate edit, and does not include editor identity or edit order.

Provider notifications normally start an observation promptly. A five-minute repair sync catches missed or coalesced notifications. The first complete read establishes a baseline and emits nothing.

The spreadsheet can contain at most 100,000 populated or formula-bearing cells. Range filtering controls which changes your trigger receives; Automate.ax still observes the complete spreadsheet so formulas and multiple range subscriptions share one correct baseline.

<Warning>
  An automation that writes to the same spreadsheet can trigger itself. Restrict
  the monitored range or make the write path idempotent when building feedback
  loops.
</Warning>
