List your runs (newest first)
const url = 'https://beta-api.plune.ai/v1/runs?limit=50&offset=0';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://beta-api.plune.ai/v1/runs?limit=50&offset=0' \ --header 'Authorization: Bearer <token>'The Runs screen (api.ts → listRuns) and the first call to make with a fresh token. Summaries, not full runs: identity, the headline counts, cost and duration, the eval score with its movement against the previous finished run of the same environment. Offset paging — a run list is short enough for it; the audit feed, which is not, pages by cursor.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Only runs that declared this environment. Blank or absent means every run — a caller building the query from an unset CI variable asks for everything, not for the empty string.
Only runs launched from this plan (meta.planId, D33) — the «Runs of this plan» list. Blank or absent means every run.
Only runs whose title contains this text, in any case — the search palette (#866). Text, not a pattern: % and _ match themselves, as in the cases list. A run without a title is not found by one. Blank or absent means every run.
Only the run that carries this externalKey, whole — the key a reporter joins by (PLUNE_RUN=<key>), so plune run grep <key> finds its run (plune-ai/cli#85). At most one: a key belongs to one live run of the project. Blank or absent means every run.
<fieldId>:<value> (#1766, ADR 0048): only the runs whose custom field holds the value — the text of a string field, the option id of a list (a multiple list matches when it holds it), the number of a number field. Repeat for one field to OR its values; different fields are AND-ed. A field or a value nobody holds matches nothing; a pair without a field or a value is a 400 that names the form.
Responses
Section titled “ Responses ”Your runs
object
A run as it appears in the list — identity + the headline numbers, derived from the run.
object
What kind of run this is. eval for a plune sync upload, automated for a CI report or a Cairn ingest, otherwise whatever the lifecycle start declared.
What the run is called, or null while nobody has said.
Where it ran, or null while nobody has said.
How the run is marked. Empty when unmarked.
Where the run came from. cairn is an INGEST rather than an eval run: it groups the Results a Cairn run produced. total/passed/failed are counted from those Results and are real numbers. costUsd and durationMs are always 0 and mean “not applicable”: Cairn neither prices a run nor times one. cli covers BOTH a run uploaded by plune sync and one started through the run lifecycle — read measured to tell those apart, since only the first carries a cost and a duration.
Results whose status is failed — by name, not total − passed: a skipped test is not a failure. For an eval run, the summary’s own failed, less the failed rows of muted cases (muted).
Results whose status is broken. Always 0 for an eval run.
Results whose status is blocked. Always 0 for an eval run.
Results whose status is skipped. Always 0 for an eval run.
Failures of muted cases, out of failed and broken and still in total. A failed or broken result of a muted case is counted as muted, not as a failure; a finished run never changes (#1247). For an eval run, in the summary’s rows: the failed and errored rows of a muted case’s eval.
Whether costUsd and durationMs are measurements or absences — otherwise both are the same 0. Do NOT re-derive this from source: a run started through the run lifecycle (POST /v1/runs with schemaVersion: 2) reports cli, because it did come from a client, and carries neither. Only a run uploaded by plune sync does.
Whether the run is under way — true while the status is launched or rerun, false once it is finished or terminated, and for a scheduled run that waits for Launch (#1233). Read this rather than deriving a verdict from the counts: a run that has just started has failed: 0 like a run that passed, and the two mean opposite things. A plune sync upload and a Cairn ingest both record a run that has already ended, so both are always false.
An eval run’s one number: passed / total in whole points out of 100. Null for every other kind, and for an eval run that ran nothing — a score of nothing is absent, not 0.
How many cases a scheduled run will expect (#1233) — the list’s «scheduled · 12 cases», since nothing has run. null for every other run.
score minus the score of the previous finished eval run in the same environment (a null environment compares with null), or null when there is none. Null means “no comparison”, not “no change”. Same environment rather than same externalKey: the key would compare a nightly against a pull request, and an eval run has none.
How many runs the same filters match in all — not the page, and not what is in the Bin. What «Select all N runs» says (#1100).
Example
{ "runs": [ { "id": "6f1c2b3a-0000-4000-8000-0000000000d1", "createdAt": "2026-09-16T09:12:04.151Z", "kind": "automated", "source": "cli", "title": "plune · 2026-09-16 09:12 · ci", "environment": "staging", "labels": [ "plune", "vitest", "ci" ], "total": 2, "passed": 1, "failed": 1, "broken": 0, "blocked": 0, "skipped": 0, "muted": 0, "score": null, "scoreDelta": null, "costUsd": 0, "durationMs": 4931, "measured": false, "running": false } ], "total": 1}No / invalid token or session