Runs
GET /v1/runs: list, fetch and cancel runs; every attempt and charge on record.
Run history and control. Every run, from any key in your organization, is on record with its attempts, charges and routing reason.
List runs
GET /v1/runs
curl "https://api.jell.run/v1/runs?status=succeeded&capability=contact.find&limit=50" \
-H "Authorization: Bearer $JELL_API_KEY"
| Query param | Notes |
|---|---|
status |
filter by lifecycle status (succeeded, failed, no_match, ...) |
capability |
filter by capability slug |
provider |
filter by the provider that served the run |
endpoint |
filter raw endpoint runs by endpoint path |
limit |
default 50, max 200; newest first |
Returns {"items": [run, ...]} where each run has the same shape as the run response minus result: a listing is the receipts (status, provider, charge, timing, attempts), and the payload of any one run comes from its poll_url (GET /v1/runs/{run_id}). That keeps a 200-row page small whatever the runs returned.
Get one run
GET /v1/runs/{run_id}
Poll this for runs that returned 202; add ?wait=60 (max 120) to long-poll until the run finishes. POST /v1/runs/{run_id}/cancel stops a run that is still queued (stoppable: true); a run already at the provider cannot be stopped. A run that does not exist (or belongs to another organization) returns invalid_request.
Cancel a run
POST /v1/runs/{run_id}/cancel
Only runs that have not started executing (created, reserved, queued) can be cancelled. A run already running or finished returns invalid_request with the current status.
History for a subject
GET /v1/history?q=<subject>
Everything your organization has already done to one subject through Jell, derived from the run log: no second store, nothing to write. Pass an email, a domain, a LinkedIn URL, any URL, a social handle, a phone number or a name. The kind is detected from the value; force it with kind (email, domain, linkedin, url, handle, phone, text). Free.
curl "https://api.jell.run/v1/[email protected]" \
-H "Authorization: Bearer $JELL_API_KEY"
A run matches when the subject appears in its input or its result: the contact.find that produced the email, the contact.verify that checked it, the email.send that wrote to it. A domain query also matches emails at that domain and URLs on it; a LinkedIn query matches on the profile slug, whatever the URL's form.
| Field | Notes |
|---|---|
subject |
query, the detected kind, and the normalized form that was matched |
items |
matching runs, newest first: status, capability or raw endpoint, provider, charge, the run's input, and matched (where the subject was found: in input or result, the JSON path, exact when the value names the subject itself) |
touches |
the outbound runs among them (email.send, linkedin.invite, linkedin.message) with their channel; last_touch is the latest one that succeeded |
reusable |
successful paid lookups whose input named the subject: read their result with GET /v1/runs/{id} instead of buying it again |
by_status, by_capability, charged, first_seen, last_seen |
the summary |
hints |
what an agent should conclude: already contacted, a result to reuse, nothing on record |
limit (default 50, max 200) caps items; truncated: true says there were more. Only calls made through Jell by your organization are on record; anything done elsewhere is invisible here.
Many subjects at once
POST /v1/history
curl -X POST https://api.jell.run/v1/history \
-H "Authorization: Bearer $JELL_API_KEY" -H "Content-Type: application/json" \
-d '{"subjects": ["[email protected]", "[email protected]"], "kind": "email"}'
The dedupe pass before a batch: for 1 to 200 subjects, one compact row each (seen, count, last_seen, contacted, last_touch, the first reusable result) plus seen, unseen and contacted totals. A subject that does not read as the given kind gets an error row instead of failing the batch.
Reading this as an agent? This page as markdown: /docs/api/runs.md · every page: /docs/llms.txt