Sheets, warehouses and webhooks

Deliver every new dataset version to Google Sheets or a webhook you own, read a sheet into a dataset, and see which warehouse connectors are coming.

A sink is a destination that receives a dataset. You connect it once to one dataset worksheet; from then on, every time that worksheet gets a new version, the sink gets the rows. A source goes the other way: it brings rows from outside into a dataset. Google Sheets can do either.

Where a dataset can goA published dataset version is pushed to Google Sheets and outgoing webhooks, served over HTTP and MCP, and used by dashboards, newsletters and share links. Warehouse and cloud-storage connectors are coming soon.Dataset versionchecked rowsGoogle SheetsWarehouses · storage (soon)Outgoing webhookServe APIMCP · your agentDashboardsNewslettersShare links
One published version, every destination. Sinks, dashboards, alert rules and the serve API all read the same version.

What a sink receives, and when

A sink fires on every new dataset version of the worksheet it is bound to. New versions come from a pipeline run that publishes, from rows sent to a Receive JSON webhook, from a source sync, and from an upload or edit on the dataset page. The sink does not care which; it sees a version.

Each sink chooses a Payload:

  • Only new/changed rows (the default). Jsonify compares the new version with the previous one using the dataset’s key columns and sends the rows whose key was not there before. On the very first delivery, that is every row.
  • Full dataset snapshot. Every row of the new version, every time.

“Only new/changed rows” needs key columns. If the dataset has none, every row in the new version looks new and the sink receives all of them. Ask Jason to set the key, for example “the key for this dataset is product URL plus retailer”, and the diff becomes meaningful.

Delivery is recorded on the run that produced the version. A successful delivery appears as “Sent 120 rows to Sheets pricing”; a failed one as “Delivery to Sheets pricing failed:” with the reason. A failed delivery never blocks the publish and is not retried on its own; the next version is delivered as usual once you fix the destination.

Google Sheets

Choose Google Sheets from the catalogue and Jsonify asks What should this do?:

  • Pull rows from a sheet — “We read the sheet on a schedule and append rows to the dataset.”
  • Push rows to a sheet — “Every time a pipeline updates the dataset, we write rows to the sheet.”

Both work on the sheet’s share link. Jsonify never asks for your Google sign-in.

Pull rows from a sheet

Use this 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.

Option Values Default What it does
Label Text “Pull rows from a sheet” How the integration appears in pickers
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 First tab Which tab to read
Target dataset A dataset, or + Create new dataset Required Where the rows go
Target worksheet A worksheet of that dataset Required Which worksheet receives them (main for a new dataset)

The first row of the tab is treated as the column headers. Connect reads the sheet once; “Could not read sheet — is it public?” means the share setting is wrong.

When it syncs. Despite the wording in the picker, a pull source has no timer of its own. Jsonify reads the sheet:

  • before every run of a pipeline that uses the target dataset as an input, so the run always starts from the sheet’s current rows, and
  • when you use the dataset’s sync action by hand.

Each sync that finds rows writes a new dataset version. If the dataset has key columns the rows are merged by key; otherwise they are appended below the previous rows. A sync that finds no rows changes nothing.

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 a source by hand

A pulled source also syncs on demand. Open the dataset it feeds; its Connections strip lists the source with its status and, when a pulled source is live, a Sync button.

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

Push rows to a sheet

Use this when people want to look at, filter or chart the data in a spreadsheet without opening Jsonify.

Option Values Default What it does
Label Text “Push rows to a sheet” How the integration appears in pickers
Sheet URL A docs.google.com/spreadsheets/d/… link Required The sheet to write. It must be shared as “Anyone with the link can edit”
Worksheet (tab) Tab name First tab Which tab to write
Source dataset A dataset Required The dataset to deliver
Source worksheet A worksheet of that dataset Required Which worksheet to deliver
Write mode Replace — wipe and rewrite / Append — add rows below existing Required Replace clears the tab and writes a header row plus every delivered row. Append reads the tab’s first row as the header and adds rows below, matching columns by name
Payload Only new/changed rows / Full dataset snapshot Required Which rows are delivered on each version

Connect opens the sheet as Jsonify’s service account and checks the tab exists; “Worksheet ‘Prices’ not found” means the tab name does not match.

The two settings combine like this:

Write mode Payload Result in the tab
Replace Full dataset snapshot The tab always mirrors the latest version. The usual choice for a live view
Replace Only new/changed rows The tab shows only what changed in the latest version
Append Only new/changed rows The tab grows by the new rows each time. A running log
Append Full dataset snapshot Every version is appended in full. Rarely what you want

A sheet mirrors one worksheet of one dataset. To deliver a second worksheet, or the same dataset into a second sheet, create another Push rows to a sheet integration.

Send rows to a webhook

Send rows webhook posts rows as JSON to a URL you own after every new version. Use it to load your own database, feed a warehouse through your own loader, or drive a system that has a REST endpoint.

Option Values Default What it does
Label Text “Webhook” How the integration appears in pickers
Target URL An http:// or https:// URL Required Where rows are sent
Source dataset A dataset Required The dataset to deliver
Source worksheet A worksheet of that dataset Required Which worksheet to deliver
Payload Only new/changed rows / Full dataset snapshot Required Which rows are delivered on each version
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

Connect checks the URL and your selections only; nothing is sent until the dataset next publishes.

With One POST with all rows, each version produces one request:

{
  "kind": "sink",
  "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"
    },
    {
      "product_url": "https://www.example-store.com/p/12399",
      "retailer": "Example Store",
      "title": "Espresso machine 19 bar",
      "price": 189.0,
      "currency": "GBP",
      "in_stock": false,
      "observed_at": "2026-09-15T06:02:14Z"
    }
  ]
}

With One POST per row, each row arrives on its own as {"kind": "sink", "row": { ... }}. Your endpoint must answer each request within thirty seconds with a success status; anything else is recorded as a failed delivery on the run.

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

Alerts also have a webhook channel, with a different payload. If you want a message when a condition is met rather than the rows themselves, see Alert webhooks.

Serve a dataset instead

If your system would rather fetch than be sent to, Publish Dataset API gives a dataset worksheet a secret URL that returns the latest rows on request. It is a sink too, but nothing is pushed; you read it whenever you like. See Serve a dataset over HTTP.

Warehouses and cloud storage

Warehouse, storage and BI connectors are coming soon. Snowflake, BigQuery, Amazon Redshift, Databricks and Azure Synapse for warehouses; Amazon S3, Dropbox and SFTP for storage; Microsoft Excel and Airtable for spreadsheets; Tableau and Power BI for BI; Salesforce and HubSpot for CRM. They appear in the catalogue on the Disabled tab and cannot be connected yet.

If one of these matters to your rollout, tell us which one. That is what decides the order they ship in.

Removing a destination

Delete the integration from its card or its Danger tab. The dataset keeps publishing; only that destination goes quiet, from the next version on. A sheet keeps whatever was last written to it.

What’s next

Connect your data assistant

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

Connect in ChatGPT

  1. Open Settings → Security and login and enable Developer mode.
  2. Open Plugins and select + to create a connection. Name it Jsonify, add a short description, and paste the URL below.
  3. Use OAuth for authentication, select Create, and sign in to your Jsonify account when prompted.
  4. Start a new chat and select Jsonify from + → More, then describe your dataset.
Server URLhttps://factory.jsonify.com/mcp

If Developer mode is unavailable, your plan or workspace settings may restrict custom connections.

Official ChatGPT setup guide ↗

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