Ingest and serve API

Send rows into a dataset, read the latest rows of a dataset, and have Jsonify fetch rows from your own endpoint, all over plain HTTPS with a secret URL.

Three integrations give a workspace an HTTP surface without any sign-in dance. Each one is a single secret URL created in Jsonify.

Integration Direction URL shape Purpose
Receive JSON webhook You send rows in POST https://factory.jsonify.com/api/ingest/<id> Each request writes a new version of a dataset worksheet
Pipeline Trigger You start a run POST https://factory.jsonify.com/api/ingest/<id> Starts one pipeline, optionally with parameters, and gives you URLs to follow it
Publish an API You read rows out GET https://factory.jsonify.com/api/serve/<id> Returns the latest version of a dataset worksheet as JSON

<id> is the integration’s own identifier; the full URL is on its Settings tab. A fourth integration, Read from an API, goes the other way round: Jsonify fetches rows from a URL of yours. It is covered at the end. Pipeline triggers have their own page.

Ask Jason for any of them: Integrations → Connect Input → Webhooks (receive rows, or start a run), Connect Input → Read from an API, or Connect Output → Publish an API. Jason creates the integration and links to it. See Connecting a service.

The URL is the secret. There is no separate key, header or signature: anyone who has the URL can use it until the integration is deleted. Keep it out of shared documents and front-end pages, and if it leaks, delete the integration and create a new one; the old URL stops resolving the moment you delete it.

Receive rows over a webhook

Receive JSON webhook gives a dataset worksheet an address that other systems can post rows to: a form tool, an internal service, a partner’s export, a scheduled job.

Set it up

“Create a secret POST URL. Send one JSON object or an array of objects; each request writes a new dataset version.”

Option Values Default What it does
Target dataset A dataset Required “Rows POSTed to the ingest URL land here.”
Target worksheet A worksheet of that dataset Required Which worksheet receives them

There is nothing to test at Save. Once the integration is Live, its Settings tab shows the Ingest endpoint block, “Send one JSON object or an array of objects. Treat the URL as a secret.”, with the URL, the dataset’s current version and when it last changed. The Code tab holds Python, cURL and JavaScript (Node.js) samples, each with Copy.

A Receive JSON webhook integration's Settings tab showing the Ingest endpoint block with the URL and a Copy link
The ingest endpoint. Copy the URL from here; it is the only credential.

Send rows

Post one JSON object, or an array of objects. Each object is a row; its keys are column names.

curl -X POST https://factory.jsonify.com/api/ingest/int7f2c9a1b3 \
  -H 'Content-Type: application/json' \
  -d '[
    {"product_url": "https://www.example-store.com/p/12345", "retailer": "Example Store", "price": 149.0, "currency": "GBP"},
    {"product_url": "https://www.example-store.com/p/12399", "retailer": "Example Store", "price": 189.0, "currency": "GBP"}
  ]'

The answer confirms what was written:

{"ok": true, "integration": "int7f2c9a1b3", "dataset": "dsa41b7c9e2f0", "version": 18, "rows_ingested": 2}

Every successful request creates a new dataset version. If the dataset has key columns, incoming rows replace rows with the same key and new keys are added; if it has none, the rows are appended below the existing ones. Keys become column names, so keep them consistent between requests. Anything in the array that is not an object is dropped.

After the version is written, the dataset does everything it does after a pipeline publish: alert rules are checked and send to their outputs, and dashboards recompute. The dataset page shows the version with the source Ingested, and the integration’s Activity tab records “Received 2 rows into Supplier catalogue v18”.

Errors

Answer Meaning
400 “response must be a JSON object or array of objects” The body was not JSON, or not an object or array
400 “No rows to write” An empty array, or an array with no objects in it
400 “Integration is not live” The integration is not Live. Open it and check its status
400 “This integration is configured for pull mode” You posted to a Read from an API integration, which Jsonify reads from, not one you write to
404 “Integration not found” Wrong URL, or the integration was deleted
404 “Target dataset not found” The dataset was deleted. Open the integration and pick another

Refused requests are recorded on the Activity tab as “Rejected a request”, with the reason.

A partner emails a nightly CSV, and a small job on your side converts it to JSON and posts it to the ingest URL. The dataset Partner stock gains a version each night, one alert rule watches for products that disappeared, and an Every update rule keeps a sheet matching it for the buying team. No pipeline involved.

Start a run from a webhook

A pipeline trigger gives one pipeline an address that starts a run, with inputs, and returns the exact rows that run produced. Up to four runs of a pipeline can be queued or running at once; a fifth request gets 429 “Pipeline has 4 outstanding runs; retry after one finishes”. Everything about triggers, including the status and result URLs, the test dialog and the code samples, is on Start runs from your systems.

Serve a dataset over HTTP

Publish an API gives a dataset worksheet an address that returns its latest rows. Your app, your BI tool’s web connector, or a scheduled loader fetches it whenever it likes.

Set it up

“Create a secret GET URL for the latest rows in a dataset. Apps and scripts can fetch it anytime.”

Option Values Default What it does
Source dataset A dataset Required “The dataset whose rows are returned on GET.”
Source worksheet A worksheet of that dataset Required Which worksheet is returned

Once Live, the Settings tab shows the Serve endpoint block, “Returns dataset metadata and rows as JSON.”, with the URL and the dataset’s current version. The Code tab has samples, Python first.

Read rows

curl https://factory.jsonify.com/api/serve/int9c4e2b7d1a
{
  "integration": "int9c4e2b7d1a",
  "dataset": "marketdata01",
  "dataset_name": "Live product offers",
  "table": "main",
  "version": 42,
  "updated_at": 1789452498,
  "row_count": 3120,
  "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},
    {"...": "..."}
  ]
}

The endpoint always returns the active version of the worksheet, in full, as JSON. There are no query parameters: no paging, no filters, no other formats. A dataset that has not published yet answers with "version": null and an empty rows array. Compare version between fetches to know whether anything changed.

For a filtered or paged read, or CSV, use the command line or an MCP assistant instead; both sign in with a credential rather than a URL.

Serve URLs are read by whoever holds them. Do not embed one in a public web page or a shared notebook. For showing data to people, use the workspace share link, which can be turned off and shows a proper page.

Fetch rows from your own endpoint

Read from an API is the mirror of the ingest webhook: instead of you posting rows, Jsonify fetches them from a URL you own and writes them into a dataset. “Pull rows from a JSON endpoint into a dataset. Use this for read-only APIs you already own.”

Option Values Default What it does
Endpoint URL An http:// or https:// URL Required Where rows are fetched from. “Must return JSON — either an array of rows or an object containing one.”
Target dataset A dataset Required Where the rows go
Target worksheet A worksheet of that dataset Required Which worksheet receives them
Auth header (optional) A full header line, for example Authorization: Bearer … Empty “Full header line. Sent on every fetch. Leave blank for unauthenticated endpoints.”

Save fetches the endpoint once, without the auth header, and checks the answer is JSON. If your endpoint refuses unauthenticated requests, the check fails; make it answer with an empty JSON array for unauthenticated calls, or allow Jsonify’s check through some other way, then save.

The endpoint may return an array of objects, or an object whose data, results, items or rows key holds the array.

Like a pulled sheet, this input has no timer of its own: Jsonify fetches it before every run of a pipeline that uses the dataset as an input, and when you press Sync on the dataset. Each fetch that returns rows writes a new version, merged by key when the dataset has key columns and added below the previous rows otherwise. See Pull rows from a sheet for the same behaviour explained for sheets.

Test from Jsonify

Test, in the integration’s page header, opens the Test API request dialog. Requests are sent from your browser, for real.

  • Receive JSON webhook. A Rows (JSON) box, prefilled with [{"example": "value"}]. Send request posts it and writes a real dataset version. The Response box shows the HTTP status and the answer; “Rows must be valid JSON.” if the box does not parse.
  • Publish an API. “Fetch data from the configured API URL.” Fetch reads the serve URL and shows the response.
  • Read from an API. Fetch reads your endpoint from the browser, without the auth header. An endpoint that does not allow browser requests from Jsonify answers with an error here even when Sync works.

Close leaves the dialog. Rows sent to a Receive JSON webhook are recorded on its Activity tab like any other request.

Keeping URLs private

  • Store the URL where you keep secrets. A CI secret, a secret manager, an environment variable. Not in the request log of a shared tool.
  • One integration per caller. If two systems post to the same dataset, give each its own Receive JSON webhook. Then a leak, or a decommissioned system, costs you one delete rather than a migration.
  • Rotate by replacing. There is no rotate button for a URL. Create a new integration, move the caller to the new URL, then delete the old one. The old URL stops working the moment it is deleted; nothing else changes.
  • Watch for use. Ingest and trigger requests are on the integration’s Activity tab, and show up as dataset versions with the source Ingested or runs with the trigger webhook. An unexpected one is the signal to replace the URL.

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.