Ingest a Cairn run
const url = 'https://beta-api.plune.ai/v1/ingest/cairn';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"schemaVersion":1,"run":{"runId":"cairn-2026-08-30-0001","mode":"api","target":"https://shop.example/api"},"cases":[{"stableId":"9f2a4c1e","title":"health check answers 200","execution":"auto","steps":["GET /health"],"expected":"HTTP 200","verdict":"passed","technique":"happy-path"},{"stableId":"3b7d0e55","title":"order with a negative quantity is refused","execution":"auto","steps":["POST /orders"],"expected":"HTTP 422"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://beta-api.plune.ai/v1/ingest/cairn \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "schemaVersion": 1, "run": { "runId": "cairn-2026-08-30-0001", "mode": "api", "target": "https://shop.example/api" }, "cases": [ { "stableId": "9f2a4c1e", "title": "health check answers 200", "execution": "auto", "steps": [ "GET /health" ], "expected": "HTTP 200", "verdict": "passed", "technique": "happy-path" }, { "stableId": "3b7d0e55", "title": "order with a negative quantity is refused", "execution": "auto", "steps": [ "POST /orders" ], "expected": "HTTP 422" } ] }'Where plune ingest <dir> sends a Cairn run after reading it off disk (ADR-CI-01) — the client is @plune-ai/cli, and the dashboard never calls this surface. Generated cases NEVER become test cases here — they are queued as proposals for a human (ADR-CI-03), so ADR 0010 holds. Idempotent per project on run.runId: a repeat writes nothing and replays the same counters.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
object
Idempotency key — the same run ingested twice changes nothing.
Page URL or API base URL that was tested.
object
object
Cairn’s content-derived identity — the dedup key.
Automatable, or a person runs it.
ABSENT means the run never executed this case (a design run writes cases and runs nothing) — not “no result yet”. Only an executed case can become a Result.
object
Why the agent thinks this case is worth having. Read by opening an item: at 400 characters it does not fit a queue row.
Identifiers this test already has elsewhere, so the queue can say which existing case a proposal looks like. An unknown kind refuses the WHOLE ingest and names the accepted ones: a partial acceptance would leave the agent believing it had sent something matchable, and the only symptom would be an entry with no comparison — indistinguishable from a case that genuinely is new.
An identifier another tool already uses for this test, so a report can find its case without anyone typing a Plune id. The order of kind is load-bearing: it is the ranking that decides which key wins when several match different cases.
object
Example
{ "schemaVersion": 1, "run": { "runId": "cairn-2026-08-30-0001", "mode": "api", "target": "https://shop.example/api" }, "cases": [ { "stableId": "9f2a4c1e", "title": "health check answers 200", "execution": "auto", "steps": [ "GET /health" ], "expected": "HTTP 200", "verdict": "passed", "technique": "happy-path" }, { "stableId": "3b7d0e55", "title": "order with a negative quantity is refused", "execution": "auto", "steps": [ "POST /orders" ], "expected": "HTTP 422" } ]}Responses
Section titled “ Responses ”Already recorded — the same answer as the first time
The three counters always add up to the number of cases sent, so a caller can see nothing was dropped.
object
The run row this ingest recorded.
Verdicts attached to cases the project already has.
Cases queued for a human to approve — none were created.
Already queued, already rejected, repeated, or never executed.
Example generated
{ "runId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "linked": 1, "proposed": 1, "skipped": 1}Recorded
The three counters always add up to the number of cases sent, so a caller can see nothing was dropped.
object
The run row this ingest recorded.
Verdicts attached to cases the project already has.
Cases queued for a human to approve — none were created.
Already queued, already rejected, repeated, or never executed.
Example generated
{ "runId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "linked": 1, "proposed": 1, "skipped": 1}Unreadable body, or a payload version this server does not know
object
Example generated
{ "error": "example"}No / invalid token or session
Rate-limited: either the per-route throttle or a tenant quota. Retry-After carries the seconds until the window rolls over.
object
Example generated
{ "error": "example"}Headers
Section titled “Headers ”Seconds until the window rolls over