The public report of a run — no account
const url = 'https://beta-api.plune.ai/public/report/example';const options = {method: 'GET'};
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/public/report/exampleWhat anyone who holds the address sees of a run (#1263), with no credential and no cookie, set or read: its title, environment and labels, when it started and finished, the six counters (passed, failed, broken, blocked, skipped, muted), the sub-statuses its results carry, the time it took and what it cost (null for a run nobody timed or priced), and per test its title, status, sub-status and time — and, in a run with configurations, the label of its combination (#1251) — (at most 1000, then testsTruncated). Nothing else: no ids, no people, no CI address, branch or commit, no error text, no files — and the page has no write element. Off, revoked, never made, malformed and a run in the Bin are ONE answer, the same 404 with the same body. A link ends (#1264): after expiresAt it answers 410 with { error, code: "expired" }. A link may have a password, sent in the X-Report-Password header (never in the address, which is logged and shared; no cookie is set or read): none sent is 401 password_required, a wrong one 401 wrong_password. The password is checked before the date. A token nobody holds is 404 whatever is sent, with no derivation spent on it; the difference between 404 (no link), 401 (a password is set) and 200 or 410 (none is) is accepted, because the token is 256 random bits and only someone who already holds a valid one can tell them apart. Wrong passwords are counted per token (10 in 15 minutes, slots taken before the check so parallel requests cannot exceed it); past that every attempt, the right one too, is 429 until the window frees. A client may send 30 requests a minute with a password, and at most 2 derivations run at once in a process: another is 429 with Retry-After: 1. Sent with Cache-Control: no-store, X-Robots-Tag: noindex, nofollow and Referrer-Policy: no-referrer. 120 a minute for a client address.
Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”43 characters of base64url.
Header Parameters
Section titled “Header Parameters ”The report’s password, when it has one. Printable ASCII, at most 128 characters.
Responses
Section titled “ Responses ”The report
object
object
Every status is present, zero included.
object
object
object
The combination the test ran in (#1251), as its label: «Firefox · macOS». Only in a run launched with configurations.
Example generated
{ "run": { "title": "example", "kind": "example", "environment": "example", "labels": [ "example" ], "startedAt": "2026-04-15T12:00:00Z", "finishedAt": "2026-04-15T12:00:00Z", "running": true }, "counts": { "additionalProperty": 1 }, "subStatuses": [ { "status": "example", "name": "example", "count": 1 } ], "durationMs": 1, "costUsd": 1, "tests": [ { "title": "example", "status": "example", "subStatus": "example", "durationMs": 1, "configuration": "example" } ], "testsTruncated": true}A password is set and none was sent (code: password_required), or the one sent is wrong (code: wrong_password)
object
Example generated
{ "error": "example"}No such report, or it is off or revoked
object
Example generated
{ "error": "example"}The link has expired (code: expired)
object
Example generated
{ "error": "example"}Rate limit exceeded, or too many wrong passwords for this token