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.
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” 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?:
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:
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.
- Open the dataset the source writes to.
- Press Sync. Every live pulled source of the dataset is read once.
- 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.