Start runs from your systems

A pipeline trigger is a secret URL that starts a run with your inputs and returns the exact rows that run produced. Up to four runs at once, a test dialog, and ready-made code.

A pipeline trigger gives one pipeline a secret URL. POST JSON to it and a run starts with the inputs you sent. The answer carries a status URL for that run alone, and once the run completes, result URLs that return exactly the rows it produced. Use it from a scheduler you already have, a deploy step, a Zapier zap, or your own application.

Start
POST /api/ingest/<trigger>, answers 202
Follow
status_url for that run
Read
result_url, 100 rows a page
At once
Up to four runs per pipeline; 429 beyond that

The URL is the secret. There is no separate key, header or signature. Anyone who has the trigger URL, or a status or result URL built from it, can use it until the trigger is deleted. Keep it server-side, and if it leaks, delete the trigger and create a new one.

Create a trigger

  1. Ask for one. Open Integrations → Inputs → Connect Input, choose Webhooks, and pick the suggestion “Start a pipeline run when my system calls a URL”, or say which pipeline. From a pipeline’s Integrations tab, Add input does the same with the pipeline already named.
  2. Open it. Jason creates the trigger and links to it. The card and the page header show the pipeline’s icon.
  3. Copy the URL. It is on the Settings tab.

The pipeline’s own Run dialog shows a banner, “Pipeline Trigger attached”, with a link to the trigger (“2 triggers attached” when there are several), so anyone running it by hand knows it can also be started from outside.

Trigger settings

A Pipeline Trigger's Settings tab with the Trigger endpoint heading, the Pipeline to run selector, the URL with Copy, and the list of pipeline inputs
The Settings tab of a trigger. The inputs listed are the fields you may send.

The Settings tab reads, top to bottom:

  1. Trigger endpoint. “POST JSON to start a run. Up to four can run at once (429 if full). The response includes run_id and a secret status_url for exact results.”
  2. Pipeline to run. A pipeline with an active version. Required. A workspace with none shows “No pipelines with an active revision in this workspace yet.”
  3. URL. The trigger URL, with Copy.
  4. Pipeline inputs. One row per input the pipeline accepts: its id, its type (string, int, list[url] and so on), “Default:” with its default value when it has one, and its description. These are the fields you may send in the body.
  5. Save. Stores a change of pipeline.

The tabs after Settings are Code (see Code samples), Activity (every request, accepted or refused, with the run it started) and Delete. Deleting the trigger stops its URL, and every status and result URL built from it, immediately.

Start a run

An empty body starts the pipeline with its defaults and its default row cap, exactly as pressing Run would:

curl -X POST https://factory.jsonify.com/api/ingest/marketint009

To pass inputs, send them as top-level JSON fields. Two optional run controls sit alongside them:

Field Values Default What it does
each input id As its type The input’s default One field per pipeline input, as listed on the Settings tab
row_limit 0 or a positive number The pipeline’s default row cap The row cap for this run. 0 runs all rows
pipeline_version A version number The active version Run a specific version instead
curl -X POST https://factory.jsonify.com/api/ingest/marketint009 \
  -H 'Content-Type: application/json' \
  -d '{"region": "uk", "include_out_of_stock": false, "row_limit": 0}'

The nested form {"params": {"region": "uk"}, "row_limit": 0} is also accepted. Do not send the same input both ways; the request is refused. Inputs are checked as in the Run dialog: a wrong type or an unknown name is a 400 with the reason.

The answer is HTTP 202 Accepted as soon as the run is queued:

{
  "ok": true,
  "run_id": "mrun00000361",
  "pipeline": "marketpipe03",
  "status": "queued",
  "status_url": "https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361"
}

Runs started this way show the trigger webhook on the runs list, and the run’s Integrations tab names the trigger under In. They count rows like any other run, and a failing one is eligible for automatic repair in the same way as a scheduled run.

Up to four runs at once

Each pipeline can have up to four runs queued or running at the same time, whether they came from the trigger, the Run button or another tool. Every accepted request gets its own run, even when two requests send identical inputs.

A fifth request, while four are still outstanding, is refused with HTTP 429:

{"error": "Pipeline has 4 outstanding runs; retry after one finishes"}

Nothing is queued behind it. Wait a moment and send it again; the code samples do this for you. The same limit applies to the Run button in Jsonify, and the pipeline page shows one “Run 3f9a2c is active” banner per run in flight. A scheduled run is skipped while its pipeline has a run outstanding.

Runs of the same pipeline each publish their own dataset version. The one that finishes publishing last becomes the dataset’s active version. That is why you should always read results through the URLs a request returned, never through the dataset’s latest version: they point at the exact version your run wrote.

Check the status

status_url belongs to one run and to the trigger that started it. Fetch it until status is completed, failed or cancelled; every couple of seconds is plenty.

curl https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361
{
  "ok": true,
  "run_id": "mrun00000361",
  "pipeline": "marketpipe03",
  "status": "completed",
  "created_at": 1789452131,
  "finished_at": 1789452498,
  "results": [
    {
      "dataset": "marketdata02",
      "dataset_name": "Price observations",
      "version": 61,
      "table": "main",
      "row_count": 1184,
      "result_url": "https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361/results/marketdata02?table=main"
    }
  ],
  "results_truncated": false
}
  • results is empty until the run completes. There is one entry per worksheet of each dataset the run published.
  • error is added when the run failed.
  • results_truncated is true when the run produced more than 100 results; the first 100 are listed. Open the run in Jsonify for the rest.

Output results

A pipeline that publishes no dataset, and only produces run outputs, lists those instead. Each entry has output, description, row_count and a result_url ending in /results/output-<id>:

{
  "output": "Weekly price summary",
  "description": "One row per retailer",
  "row_count": 24,
  "result_url": "https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361/results/output-8812"
}

Read the results

Each result_url returns a page of the exact version, or output, that the run produced. Pages hold up to 100 rows; add offset and limit to choose, and follow next_url while has_more is true.

curl 'https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361/results/marketdata02?table=main&offset=0&limit=100'
{
  "ok": true,
  "run_id": "mrun00000361",
  "pipeline": "marketpipe03",
  "dataset": "marketdata02",
  "dataset_name": "Price observations",
  "version": 61,
  "table": "main",
  "row_count": 1184,
  "offset": 0,
  "limit": 100,
  "rows": [ { "...": "..." } ],
  "has_more": true,
  "next_url": "https://factory.jsonify.com/api/ingest/marketint009/runs/mrun00000361/results/marketdata02?table=main&offset=100&limit=100"
}

An output result has the same shape, with output and description in place of dataset, dataset_name, version and table. Because the version is pinned, you can page through it at leisure; a later run does not change what this URL returns.

Errors

Answer Meaning
400 “Invalid run config:” An input failed validation, was supplied both directly and inside params, or the body was not a JSON object
400 “Integration is not live” The trigger is not Live. Open it and check its status
404 “Integration not found” Wrong URL, or the trigger was deleted
404 “Configured pipeline not found” The pipeline was deleted. Open the trigger and pick another
409 “Pipeline has no active revision” The pipeline has never been activated; finish its first build in Jsonify
429 “Pipeline has 4 outstanding runs; retry after one finishes” Four runs are already queued or running. Retry shortly
404 “Trigger run not found” The run was not started by this trigger, or the identifier is wrong
409 “Trigger run is not completed” Results were requested before the run finished
400 “offset and limit must be integers” A paging parameter was not a whole number

Every refused request is recorded on the trigger’s Activity tab as “Rejected a request”, with the reason.

Test a trigger from Jsonify

Test, in the trigger’s page header, opens the Test API request dialog. It sends real requests from your browser, so a test starts a real run that counts rows.

The Test API request dialog on its Start run tab with the pipeline's input fields, the Advanced section open showing Row limit and Pipeline version, and the request body preview
Start run. The body preview updates as you fill in the inputs.

The dialog has two tabs.

Start run:

  • The pipeline’s inputs. The same fields as the Run dialog, filled with each input’s default. Required inputs must have a value; “{input} is required.” otherwise.
  • Advanced. Collapsed. Row limit, default 0, “0 runs all rows”. Pipeline version, blank, placeholder “Latest”.
  • Request body. A read-only preview of the JSON that will be sent.
  • Send request. Posts it. The Response box shows the HTTP status and the answer. On success the dialog moves to Get result with the new run’s ID filled in.

Get result:

  • Run ID. The run to look up, with the status URL shown below it.
  • Fetch result. Reads the status. For a run that has not completed, it shows the status as it is. For a completed run it also follows the result URLs, up to 10 pages in all, and shows the rows; preview_truncated is true when there was more.

Close leaves the dialog. Every request also appears on the Activity tab.

Code samples

The Code tab holds three samples built from the trigger’s real URL and the pipeline’s current inputs. Each is a collapsible card with Copy; Python comes first and starts open, followed by cURL and JavaScript (Node.js).

The Code tab of a trigger with the Python sample expanded and collapsed cURL and JavaScript cards below it
The Code tab. Each sample starts a run, waits for it and reads every result page.

Every sample does the whole job:

  1. Sets your inputs as constants at the top, with each input’s default and, in Python, the other allowed values as a comment. ROW_LIMIT = 0 runs all rows; PIPELINE_VERSION is empty for the latest.
  2. Starts the run, and retries every two seconds while the pipeline is at its four-run limit (429).
  3. Polls the status URL every two seconds until the run completes, fails or is cancelled.
  4. Reads every result page, following next_url, and prints the rows.

The Python and JavaScript samples stop after five minutes, and raise an error if the run failed or produced more than 100 results. The cURL sample needs jq.

The essential Python flow is:

started = requests.post(TRIGGER_URL, json={**inputs, "row_limit": 0}, timeout=30)
# 429 means four runs are outstanding: wait and post again.
status = requests.get(started.json()["status_url"], timeout=30).json()
# ...poll until status["status"] == "completed", then page each result_url.

A deployment step posts to the trigger after each catalogue import, waits on the status URL, then pages the result into the search index. Two imports that land at once each get their own run and their own rows. The row cap, inputs and version are all in the request, so the step needs nothing from the Jsonify UI.

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.