Sheets, warehouses and webhooks

Outputs are destinations. Alert rules decide which rows reach Google Sheets, a warehouse or your webhook, and how they are written. Plus reading a sheet into a dataset.

An output is a destination for rows: a Google Sheet, a warehouse table, an S3 bucket or a URL you own. Connecting one gives it nowhere to send from and nothing to send. An alert rule decides that. The rule watches a pipeline or a dataset, and when it fires it sends rows to the output it names. One output can serve many rules, on many pipelines.

Where a dataset can goAlert rules send a published dataset version's rows to Google Sheets, warehouses and S3, and webhook outputs, either the whole dataset on every update or only the matching rows. The serve API and MCP read the version on request, and dashboards and the workspace share link show it.Dataset versionchecked rowsAlert ruleevery update or matching rowsGoogle SheetsWarehouses · S3Webhook outputServe APIMCP · your agentDashboardsWorkspace share link
Where a published dataset version can go. Rules send rows to outputs; APIs, your agent, dashboards and the share link read the data themselves.

What a rule sends

What arrives depends on what the rule watches:

Rule Rows sent when it fires
Every update (“Every time the dataset updates”) The whole dataset, every worksheet or the one you chose, each worksheet into its own tab or table
A run rule (“When a run fails”, “…succeeds”, “…finishes”) Every dataset the run published, each into its own tab or table
Any other data rule (new rows, rows disappear, a value changes, a value matches) Only the rows that matched, into one tab or table named after the rule

Every fire is recorded on the rule’s History tab, and a data rule’s matching rows are kept there for you to look at. See One notification.

Write modes

On a rule that sends to an output, Rows chooses how each delivery is written:

Rows What happens at the destination Offered by
Keep it matching (replace) The tab or table is emptied and refilled, so it always holds exactly what the rule last sent Every output
Add new rows to the bottom (append) The rows are added below what is already there. Reads as a running log Every output
Update rows by key, add the rest (upsert) Rows whose key already exists are replaced; new keys are added Snowflake, BigQuery, Postgres, MySQL

The default is Add new rows to the bottom for a “new rows appear” rule and Keep it matching for everything else. You can change it on the rule’s page at any time.

Upsert matches rows on the dataset’s key columns, for example product_url plus retailer, so set them before you choose it. Ask Jason: “the key for this dataset is product URL plus retailer.” When there is no key to match on, the delivery fails with “Upsert needs a key: set the dataset’s key columns, or use replace or append”.

Where the rows land

Each rule writes to its own place at the output, so two rules sending to one spreadsheet never overwrite each other.

  • Google Sheets. A tab in the output’s spreadsheet.
  • Snowflake, BigQuery, Postgres, MySQL. A table in the schema or dataset you configured. Jsonify creates it on the first delivery and adds columns when new ones appear.
  • S3. An object under the prefix you configured.
  • Webhook. The name travels in the request as "table".

The rule’s Tab, Table, Object name or, for a webhook, Destination field sets the name. Leave it blank and the rule’s own name is used, so a rule called “Retail prices to Sheets” writes to a tab called “Retail prices to Sheets”. A rule that sends several worksheets or datasets writes each one to its own tab or table, named “{rule} — {worksheet}”.

A rule named “Price drops” on Live product offers, sending to a Google Sheets output with Add new rows to the bottom, builds a tab called “Price drops” that grows by the matching offers on every run. A second rule, “Retail prices”, with Every update and Keep it matching, keeps a second tab in the same spreadsheet as an exact copy of the dataset.

Setting up an output

  1. Connect the output. Open Integrations → Outputs → Connect Output, choose the service and tell Jason what it is for, for example “Keep a Google Sheet in sync with a pipeline’s latest results”. See Connecting a service.
  2. Finish its settings. Jason links to the integration page. Connect Google, or type the keys and connection details, then Save and Test.
  3. Add a rule. Jason usually creates the rule as part of the request. Otherwise open the output’s Rules tab and press Add alert rule, or create one from Integrations → Rules. Choose the output under Send to, then Rows and the tab or table name.
  4. Check it. On the rule’s Test tab, Send rows now writes what the rule would send right now. The output’s Activity tab and the run’s Integrations tab record every delivery.

A failed delivery never blocks the run or the publish, and it is not retried on its own. The error is on the output’s Activity tab, on the rule’s History tab and in Notifications. The next fire delivers as usual once you fix the destination.

An output's Activity tab listing deliveries with their rule, run and dataset version, and one failed delivery with its error
The Activity tab. Every delivery is listed with the rule that sent it and the dataset version it came from.

Google Sheets

Google Sheets works both ways. As an output, rules write to a spreadsheet in your Google Drive. As an input, Jsonify reads a public sheet into a dataset.

Push rows to a sheet

A Google Sheets output writes as your own Google account. There are no fields to fill in.

  1. Connect Google. On the integration’s Settings tab, the Connect your Google account panel says “Jsonify creates a spreadsheet named “{integration name}” in your Google Drive. It can only see and edit spreadsheets it creates.” Press Connect Google and sign in.
  2. Allow access. Google asks whether Jsonify may see and edit the spreadsheets it creates. Allow it. Back in Jsonify the toast reads “Google connected and spreadsheet created”.
  3. Add a rule. The panel now reads “Writes as {you}, connected by {you}. Add an alert rule on the Rules tab to send rows here.”
The Google account panel of a Google Sheets output showing the connected account, Open spreadsheet and Reconnect
A connected Sheets output. Each rule writes into its own tab of this spreadsheet.

The panel’s buttons:

  • Open spreadsheet. Opens the spreadsheet in a new tab, once the output is live.
  • Try again. Shown when the last setup attempt failed, with the reason above it. Retries without signing in again.
  • Reconnect. Signs in again, for example with a different Google account.
  • Connect again. Replaces Connect Google after a failed first attempt.

If Google did not give access, the toast reads “Google didn’t give Jsonify access to your spreadsheets”; sign in again and allow it. If you cancelled, it reads “Google connection cancelled”.

Jsonify can open only the spreadsheets it created, and each output has one spreadsheet. Keep it matching makes a tab exactly the rows sent, with a header row. Add new rows to the bottom reads the tab’s first row as the header and adds rows below, matching columns by name. Sheets outputs do not offer upsert.

Pull rows from a sheet

Use a Google Sheets input when a spreadsheet is the source of truth for something a pipeline needs: a list of stores, a product catalogue, a set of URLs to visit. The sheet becomes a dataset, and the dataset becomes an input to a pipeline.

“We read the sheet when you sync the dataset and before each run that uses it, and add its rows to the target dataset as a new version. First row is treated as column headers. The sheet must be public (anyone with the link can view).”

Option Values Default What it does
Sheet URL A docs.google.com/spreadsheets/d/… link Required The sheet to read. It must be shared as “Anyone with the link can view”
Worksheet (tab) Tab name Blank, the first tab Which tab to read
Target dataset A dataset Required Where the rows go
Target worksheet A worksheet of that dataset Required Which worksheet receives them

Save reads the sheet once. “Could not read sheet — is it public?” means the share setting is wrong.

A pulled sheet has no timer of its own. Jsonify reads it before every run of a pipeline that uses the target dataset as an input, so the run starts from the sheet’s current rows, and when you press Sync on the dataset. Each read that finds rows writes a new dataset version. If the dataset has key columns the rows are merged by key; otherwise they are added below the previous rows.

A retailer keeps its 140 store addresses in a sheet the operations team edits. The sheet is pulled into the dataset Stores, which is an input to the store-checker pipeline. Adding a row to the sheet and running the pipeline is all it takes to cover a new store.

Sync an input by hand

Open the dataset the input feeds. Its Connections strip lists the input with its status and, when a pulled input is live, a Sync button.

  1. Open the dataset the input writes to.
  2. Press Sync. Every live pulled input of the dataset is read once.
  3. Read the result. “Synced 140 row(s) from 1 source(s)” means a new version was written; “Already up to date” means nothing came back; “1 source(s) failed:” gives the first reason, usually a share setting or a renamed tab.

The same Sync reads warehouse and S3 inputs and Read from an API inputs.

Send rows to a webhook

A webhook output posts rows as JSON to a URL you own whenever a rule sends to it. Use it to load your own database, drive a system that has a REST endpoint, or feed a loader for a store Jsonify does not connect to.

“Alert rules POST rows to your URL: a whole dataset on every update, what a run published, or only the rows that match. Send a batch or one request per row.”

Option Values Default What it does
Target URL An http:// or https:// URL Required Where rows are sent. A secret: only you type it
Delivery One POST with all rows / One POST per row Required One request carrying every row, or one request per row for endpoints that expect a single event at a time

With One POST with all rows, each delivery is one request:

{
  "kind": "sink",
  "table": "Price opportunities to the repricer",
  "mode": "append",
  "rows": [
    {
      "product_url": "https://www.example-store.com/p/12345",
      "retailer": "Example Store",
      "title": "Espresso machine 15 bar",
      "price": 149.0,
      "currency": "GBP",
      "in_stock": true,
      "observed_at": "2026-09-15T06:02:11Z"
    }
  ]
}

table is the rule’s Destination name (the rule’s name when blank) and mode is its write mode, replace or append, so your endpoint knows whether to clear before it writes. With One POST per row, each row arrives on its own as {"kind": "sink", "table": "…", "mode": "…", "row": { ... }}. Your endpoint must answer each request within thirty seconds with a success status; anything else is recorded as a failed delivery.

The columns are the dataset’s columns as you see them on the dataset page, sent as JSON types: numbers as numbers, booleans as booleans, everything else as text.

Alerts also have a webhook, with a different payload. If you want a message when a rule fires rather than the rows themselves, see Alert webhooks.

Warehouses and S3

Snowflake, BigQuery, Postgres, MySQL and S3 are outputs and inputs too. As outputs they work like any other: a rule sends rows, each rule into its own table or object, with the write modes above. As inputs they fill a dataset from a query or an object. Every field is on Warehouses and S3.

Serve a dataset instead

If your system would rather fetch than be sent to, Publish an API gives a dataset worksheet a secret URL that returns its latest rows on request. Nothing is pushed and no rule is needed. See Serve a dataset over HTTP.

Removing an output

Delete the output from its card or its Delete tab. “Rows will stop being sent when the dataset updates.” The rules that sent to it remain and deliver to Local Notifications only until you give them another destination. A sheet or table keeps whatever was last written to it.

What’s next

Connect your data assistant

Build datasets and work with your data in Claude, ChatGPT, Copilot or another assistant.

Connect in Claude

  1. Open the Jsonify connector: Open on Claude.ai ↗
  2. Select Connect and sign in to Jsonify.
  3. In a chat, enable Jsonify under + → Connectors and describe the data you need.
Advanced

Team or Enterprise account? Your workspace owner enables Jsonify once for everyone from Admin settings → Connectors. Jsonify is a community connector in the directory — some admins allow those by default, some review them first.

No directory? Add it by hand: Settings → Connectors → + Add custom connector, name it Jsonify, paste the server URL below, then Connect.

Server URLhttps://factory.jsonify.com/mcp

Official Claude custom-connector guide ↗

Then say: “build me a dataset of competitor product prices and availability, refreshed daily”. Full instructions per client on /connect.