# Pipe Website Change Data Into Google Sheets for Live Dashboards

Source: PageCrawl.io Blog
URL: https://pagecrawl.io/blog/website-changes-to-google-sheets-live-dashboard

---

You are monitoring forty competitor pricing pages, a dozen API changelogs, and a handful of supplier stock pages. The alerts land in email and Slack, which is fine for the moment a change happens. But the moment passes. Three weeks later someone asks "how often did Competitor X change pricing last quarter?" and you have nothing but a scrollback of notifications to dig through.

Alerts are good at telling you something changed right now, the way a school closure alert has to reach you the instant the district posts it. They are terrible at building history you can query, chart, or share with a stakeholder who does not live in your alerting tool. A spreadsheet, on the other hand, is the universal dashboard. Everyone already knows how to filter a column, draw a chart, and pivot a table. If every website change your monitoring catches lands as a new row in Google Sheets, you get a running log you can slice however you want, with zero new tools to learn.

There is an obvious cousin to this idea. We have written before about [monitoring a Google Sheet as a source](/blog/monitor-google-docs-sheets-changes), where the spreadsheet is the thing being watched and PageCrawl tells you when its cells change. This guide is the inverse. Here the spreadsheet is the destination, and the web pages are the source. PageCrawl watches the pages, and every detected change becomes a row in your Sheet. This guide covers four ways to wire that up: a raw webhook, Make, Zapier, and a runnable Google Apps Script you can paste in and use today.

<iframe src="/tools/website-changes-to-google-sheets-live-dashboard.html" style="width: 100%; height: 500px; border: none; border-radius: 4px;" loading="lazy"></iframe>

### Why route change data into a spreadsheet

A spreadsheet sitting downstream of your monitoring gives you four things a notification stream cannot.

#### A queryable history

Once changes accumulate as rows, you can answer questions retroactively. How many times did a page change this month? Which monitor is the noisiest? What was the value on the third Tuesday of last quarter? `FILTER`, `QUERY`, and pivot tables turn the log into analysis without any code.

#### Charts and dashboards for free

A column of timestamps and values is one click away from a chart. Plot change frequency over time, track a monitored price as a line graph, or build a `QUERY`-backed dashboard tab that summarizes every monitor at a glance. Stakeholders who would never open your alerting tool will happily open a shared Sheet.

#### Shareability and access control

Google Sheets sharing is something every organization already understands. Give the procurement team view access to the pricing tab. Let an analyst pivot the raw data without touching your monitoring config. No seats to provision, no permissions model to learn.

#### A staging area for other systems

A Sheet is a convenient buffer between monitoring and whatever comes next. Apps Script can read new rows and forward them to a BI tool, a billing system, or a Slack digest. Looker Studio connects directly to a Sheet for richer dashboards. The spreadsheet becomes the seam between "something changed on the web" and "do something about it."

### What PageCrawl sends when a page changes

Every method below starts from the same place: PageCrawl detects a change and fires a webhook with a JSON payload. Understanding that payload shape makes the rest straightforward. The [webhook automation guide](/blog/webhook-automation-website-changes) covers this in depth, but here is the short version of a typical payload.

```json
{
  "monitor_id": 48213,
  "monitor_name": "Competitor X Pricing",
  "url": "https://competitor-x.com/pricing",
  "changed_at": "2026-07-22T09:14:03Z",
  "change_type": "text",
  "summary": "Pro plan price changed from $49/mo to $59/mo.",
  "old_value": "$49/mo",
  "new_value": "$59/mo",
  "screenshot_url": "https://app.pagecrawl.io/screenshots/...",
  "diff_url": "https://app.pagecrawl.io/changes/..."
}
```

The exact fields depend on your tracking mode. A price or number element gives you clean `old_value` and `new_value` fields. A full-page text monitor gives you a `summary` written in plain language plus a `diff_url` you can click through to. Your job for a Sheets dashboard is to map the fields you care about to columns. For most dashboards that is timestamp, monitor name, URL, summary, old value, new value, and the diff link.

Note: Do not depend on every field being present in every payload. A boolean availability monitor will not have a numeric `old_value`. Build your column mapping defensively, defaulting missing fields to an empty string.

### Method 1: Google Apps Script web app (no third-party tools)

This is the most direct route and costs nothing beyond a Google account. You publish a tiny Apps Script web app that accepts PageCrawl's webhook POST and appends a row. No Make or Zapier subscription, no task quotas, and the data never leaves Google.

#### How it works

Apps Script can deploy a function as a web app with its own URL. When PageCrawl POSTs a change to that URL, the `doPost` function parses the JSON body and appends a row to your Sheet. You give PageCrawl the web app URL as the webhook target, and that is the whole pipeline.

#### Step 1: Create the Sheet and header row

Create a new Google Sheet. Name the first tab `Changes`. In row 1, add these headers across columns A to G:

```
Received At | Monitor | URL | Summary | Old Value | New Value | Diff Link
```

#### Step 2: Add the Apps Script

In the Sheet, open Extensions > Apps Script and replace the default code with this. It is runnable as written.

```javascript
// PageCrawl -> Google Sheets webhook receiver.
// Deploy as a Web app (Execute as: Me, Access: Anyone).

var SHEET_NAME = 'Changes';
var SHARED_SECRET = 'change-me-to-a-long-random-string';

function doPost(e) {
  try {
    var body = JSON.parse(e.postData.contents);

    // Optional: reject anything that doesn't carry the shared secret.
    var token = (e.parameter && e.parameter.token) || body.token;
    if (SHARED_SECRET && token !== SHARED_SECRET) {
      return json_({ ok: false, error: 'unauthorized' }, 401);
    }

    var sheet = SpreadsheetApp
      .getActiveSpreadsheet()
      .getSheetByName(SHEET_NAME);

    sheet.appendRow([
      new Date(),                         // Received At
      body.monitor_name || '',            // Monitor
      body.url || '',                     // URL
      body.summary || '',                 // Summary
      str_(body.old_value),               // Old Value
      str_(body.new_value),               // New Value
      body.diff_url || ''                 // Diff Link
    ]);

    return json_({ ok: true });
  } catch (err) {
    return json_({ ok: false, error: String(err) }, 500);
  }
}

function str_(v) {
  return (v === undefined || v === null) ? '' : String(v);
}

function json_(obj) {
  return ContentService
    .createTextOutput(JSON.stringify(obj))
    .setMimeType(ContentService.MimeType.JSON);
}
```

#### Step 3: Deploy the web app

Click Deploy > New deployment. Choose type "Web app". Set "Execute as" to yourself and "Who has access" to "Anyone". Deploy, authorize the script when prompted, and copy the web app URL. It looks like `https://script.google.com/macros/s/AKfy.../exec`.

Note: Apps Script web apps must be set to "Anyone" access to receive an unauthenticated POST. That is why the script checks a shared secret. Pick a long random string for `SHARED_SECRET` so only PageCrawl can write rows.

#### Step 4: Point PageCrawl at the web app

In PageCrawl, open your monitor's notification settings and add a webhook. Set the URL to your web app URL with the token appended as a query parameter:

```
https://script.google.com/macros/s/AKfy.../exec?token=change-me-to-a-long-random-string
```

Save it, then trigger a manual check or wait for the next real change. A new row should appear in your `Changes` tab within seconds.

#### Pros

- Free, with no per-task limits beyond Apps Script's generous daily quotas
- Data stays inside Google, no third-party processor in the path
- Fully customizable: route different monitors to different tabs, transform values, compute derived columns

#### Cons

- Requires comfort editing and deploying a script
- You maintain the code when payload shapes or requirements change
- Apps Script execution quotas can throttle very high volumes

#### Best for

Teams comfortable with a little code who want a free, self-contained pipeline with no extra subscriptions.

### Method 2: Make (visual, no code)

[Make](/blog/make-com-website-monitoring-automation) (formerly Integromat) is the cleanest no-code option for this. Its visual scenario builder maps webhook fields to spreadsheet columns by drag and drop, and it parses JSON without any scripting.

#### How it works

You create a scenario that starts with a "Custom webhook" trigger and ends with a "Google Sheets: Add a Row" action. Make generates a webhook URL, you hand it to PageCrawl, and Make handles the parsing and the API call to Sheets.

#### Setup

**Step 1:** In Make, create a new scenario and add a "Webhooks > Custom webhook" trigger module. Copy the generated webhook URL.

**Step 2:** In PageCrawl, add that URL as a webhook on your monitor. Trigger a check so Make receives a sample payload. Make uses that sample to learn the field structure, which is what makes the field mapping in the next step effortless.

**Step 3:** Add a "Google Sheets > Add a Row" module. Connect your Google account, pick the spreadsheet and the `Changes` tab, then map each PageCrawl field to the matching column by clicking into the column field and selecting the parsed value.

**Step 4:** Turn the scenario on and set it to run immediately on each webhook. Every future change becomes a row.

#### Pros

- No code, visual field mapping
- Built-in filters, routers, and transforms (only log changes above a threshold, split by monitor, format dates)
- Easy to extend with extra steps later (post to Slack, call another API)

#### Cons

- Free plan caps operations per month, so high-volume monitoring may need a paid tier
- A third-party processor sits between PageCrawl and your Sheet

#### Best for

Non-developers who want a maintainable pipeline and may add branching logic later.

### Method 3: Zapier (widest app ecosystem)

[Zapier](/blog/zapier-website-monitoring) works almost identically to Make and is the right pick if your wider automation already lives there. The trade-off is that Zapier's task pricing tends to be less generous than Make's for high-volume webhook traffic.

#### Setup

**Step 1:** Create a new Zap with a "Webhooks by Zapier > Catch Hook" trigger. Copy the custom webhook URL Zapier provides.

**Step 2:** Add that URL as a webhook in PageCrawl and trigger a check so Zapier captures a sample.

**Step 3:** Add a "Google Sheets > Create Spreadsheet Row" action. Select your spreadsheet and worksheet, then map each catch-hook field to a column.

**Step 4:** Turn the Zap on.

#### Pros

- Largest catalog of downstream apps if you want to fan out beyond Sheets
- Familiar to many teams already standardized on Zapier
- No code

#### Cons

- Task-based pricing can get expensive at high change volumes
- Catch Hook field parsing is less flexible than Make's for nested payloads

#### Best for

Teams already invested in Zapier who want change data in Sheets alongside their existing automations.

### Comparison of methods

| Method | Cost | Code required | Best volume | Stays in Google | Easy to extend |
|--------|------|---------------|-------------|-----------------|----------------|
| Apps Script web app | Free | Yes (small) | Medium to high | Yes | Yes, in script |
| Make | Free tier, paid above | No | High | No | Yes, visual |
| Zapier | Paid above free tier | No | Low to medium | No | Yes, huge app catalog |
| Direct (no Sheets) | n/a | n/a | n/a | n/a | n/a |

For most teams the choice comes down to two questions. Do you want to avoid third-party processors and keep everything in Google? Use Apps Script. Do you want zero code and a visual builder you will extend later? Use Make, or Zapier if that is where your stack already lives.

### Building the dashboard once data is flowing

Rows are not a dashboard. Here is how to turn the raw `Changes` tab into something people actually look at.

[Image: PageCrawl dashboard tracking a portfolio of client websites at a glance]

#### A summary tab with QUERY

Add a second tab called `Dashboard`. Use `QUERY` to roll up the raw log. For example, change counts per monitor over all time:

```
=QUERY(Changes!A2:G, "select B, count(B) where B is not null group by B order by count(B) desc label count(B) 'Changes'", 0)
```

That single formula produces a live league table of your noisiest monitors that updates automatically as new rows arrive.

#### A frequency chart

Select the `Received At` column, insert a chart, and group by week or day to visualize change frequency over time. A spike in changes on a competitor's pricing page the week before a product launch is the kind of pattern a chart surfaces instantly and a notification stream hides.

#### Tracking a numeric value over time

If you are monitoring a [price or number element](/blog/css-selector-guide-target-elements-monitoring), the `New Value` column holds a clean numeric series. Filter the log to one monitor and plot `New Value` against `Received At` for a price-history line chart, the same view you would pay a dedicated price tracker for, built from your own data.

#### Connecting Looker Studio

For richer dashboards, connect the Sheet to Looker Studio as a data source. You get interactive filters, multiple chart types, and shareable report links, all driven by the same rows your webhook is appending.

### Practical patterns

#### Route different monitors to different tabs

In the Apps Script version, switch on `body.monitor_name` or a tag in the payload and append to a different tab per category. Pricing changes go to a `Pricing` tab, API changelog changes to an `API` tab. In Make, use a router module to do the same thing visually.

#### Only log significant changes

You rarely want every micro-edit. Filter before the row is written. In Make and Zapier add a filter step that only continues when the summary indicates a meaningful change. In Apps Script, add a condition in `doPost` that skips appends for changes you classify as noise. Tuning your monitor's tracking mode and sensitivity first, as covered in the [CSS selector guide](/blog/css-selector-guide-target-elements-monitoring) and [XPath and CSS selector guide](/blog/xpath-css-selectors-web-monitoring), keeps the noise out at the source so your dashboard stays clean.

#### Fan out from the Sheet

Once a row lands, an `onChange` Apps Script trigger or a second Make scenario can react: post a weekly digest to [Slack](/blog/website-change-alerts-slack), kick off a [downstream automation in n8n](/blog/n8n-website-monitoring-automate-change-detection), or feed an [AI agent that acts on the change](/blog/ai-agents-react-website-changes-webhooks). The Sheet becomes the durable record while other systems consume from it.

#### Combine with API monitoring

If you are tracking [API changelogs and documentation](/blog/api-monitoring-track-changes-alerts), a Sheets log gives you a permanent, queryable record of every breaking change across every third-party API your stack depends on, which is far more useful at audit time than a buried email thread.

### Common challenges

#### Duplicate rows

If a webhook is retried, you can get duplicate rows. In Apps Script, store the last seen `monitor_id` plus `changed_at` in `PropertiesService` and skip exact repeats. In Make and Zapier, a filter or a data store lookup achieves the same.

#### Timezones

`new Date()` in Apps Script uses the script's timezone, set under Project Settings. If your team is distributed, log the raw `changed_at` ISO string from the payload in its own column alongside the local timestamp so nobody argues about when something actually happened.

#### Payload fields that vary by tracking mode

As noted earlier, not every monitor produces every field. Default missing fields to empty strings (the `str_` helper in the script does this) so a boolean monitor does not break a pipeline expecting numeric values.

#### Sheet row limits

Google Sheets caps out around 10 million cells. At seven columns that is well over a million rows, plenty for years of monitoring. If you somehow approach it, archive old rows to a second Sheet on a schedule with a small Apps Script function.

### Choosing your PageCrawl plan

PageCrawl's **Free plan** lets you monitor **6 pages** with **220 checks per month**, which is enough to validate the approach on your most critical pages. Most teams graduate to a paid plan once they see the value.

| Plan | Price | Pages | Checks / month | Frequency |
|------|-------|-------|----------------|-----------|
| Free | $0 | 6 | 220 | every 60 min |
| Standard | $8/mo or $80/yr | 100 | 15,000 | every 15 min |
| Enterprise | $30/mo or $300/yr | 500 | 100,000 | every 5 min |
| Ultimate | $99/mo or $999/yr | 1,000 | 100,000 | every 2 min |

Annual billing saves two months across every paid tier. Enterprise and Ultimate scale up to 100x if you need thousands of pages or multi-team access.

At an engineering hourly rate, Standard at $80/year pays for itself the first time you catch a breaking API change, a deprecated endpoint, or a silent config change before it takes down production. 100 monitored pages is enough to cover the changelogs and docs of every third-party API your stack depends on. Enterprise at $300/year adds higher check frequency, 500 pages, and full API access. All plans include the **PageCrawl MCP Server**, which plugs directly into Claude, Cursor, and other MCP-compatible tools. Developers can ask "what changed in the Stripe API docs this month?" and get a summary pulled from your own monitoring history. AI assistants can create monitors through conversation on every plan, including Free, turning your tracked pages into a living knowledge base instead of a pile of alert emails.

### Getting Started

Start with one monitor and the Apps Script method. It is free, it keeps your data inside Google, and it takes about ten minutes end to end: create the Sheet, paste the script, deploy the web app, and add the URL as a webhook on a single page you already care about. Trigger a check and watch the first row appear.

Let it run for a week. Once you have a handful of rows, add the `QUERY` summary tab and a frequency chart so you can feel what a live dashboard buys you. Then expand: point more monitors at the same web app, route categories to separate tabs, and if you outgrow the script's simplicity, move the pipeline to Make for visual branching.

PageCrawl's free tier includes 6 monitors, enough to prove the whole pipeline on your most important pages before you commit to anything. New monitors come with screenshots on by default and a plain-language AI summary on every change, so the rows you log are already readable rather than raw HTML diffs. Once the dashboard earns its place in your workflow, the Standard plan at $80/year scales it to 100 pages and 15-minute checks.

---

Need more? The complete PageCrawl.io help center, with every article, is available as a single document at https://pagecrawl.io/llms-full.txt. Read it for context on anything this page does not cover.
