Change a manual mark
const url = 'https://beta-api.plune.ai/v1/results/example';const options = { method: 'PATCH', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"status":"passed","errorContext":null,"steps":[{"index":0,"status":"passed"},{"index":1,"status":"passed"},{"index":2,"status":"passed"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url https://beta-api.plune.ai/v1/results/example \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "status": "passed", "errorContext": null, "steps": [ { "index": 0, "status": "passed" }, { "index": 1, "status": "passed" }, { "index": 2, "status": "passed" } ] }'The «To run» section of the run page (D34, api.ts → patchResult): a person who marked a case changes the mark — its status, its message, its steps — in place, while the run is open. Only a result with source: manual answers: a reporter’s result is evidence, and a run of 40 cases must not count 41 because one mark was corrected. Audited under the run. A patch never sets or changes failure; the message is sanitized like a submission’s.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body required
Section titled “Request Body required ”At least one key. Only a result with source: manual in an open run takes a patch — a reporter’s result is evidence and stands (404), and a closed run keeps its marks (409). outcome is recomputed from the new status.
object
null clears the message; redacted and truncated like a submission’s.
object
The step’s position in the case’s steps, from 0.
Example
{ "status": "passed", "errorContext": null, "steps": [ { "index": 0, "status": "passed" }, { "index": 1, "status": "passed" }, { "index": 2, "status": "passed" } ]}Responses
Section titled “ Responses ”The result as it is now
One stored result, as every reader returns it — a run’s results, a test’s history, a corrected mark.
object
Returned sanitized — no colour codes, no credentials — whether it was stored before the rules existed or after.
What the platform removed before storing — written whenever something was, even without text; null when nothing ever was.
object
Values replaced by a marker, in the text and in every string of failure, each once. The headline counts only when there is no text — otherwise it repeats a line of it.
Whether the TEXT was cut to 256 KB. A shortened field of failure carries its own ….
What the reporter said about the failed attempt, or null.
object
How many steps between the outer and the inner ones were left out. Absent when none were.
object
From the repository root in posix form, the way a case’s specRef names it. A path of the machine is refused: absolute, with a drive or a scheme, from a home (~), or climbing out with ...
object
As the runner named it — screenshot, trace, error-context.
How many artifacts past the listed ones there are — all reachable through ciUrl.
Files uploaded to this result — screenshots, and text (JSON, plain text, logs) — oldest first (ADR 0040) — present on a run’s results list, and only when there is one. The bytes are GET /v1/files/{id}.
A file of a result, everything but its bytes (ADR 0040).
object
The last segment of the name it was uploaded with, cleaned of credentials as a text is.
A log is text/plain.
Bytes as kept: a picture at most 2 MiB; a text at most 512 KiB, and counted after its credentials are cleaned, so it can differ from what was sent.
Example
{ "id": "6f1c2b3a-0000-4000-8000-0000000000e1", "runId": "6f1c2b3a-0000-4000-8000-0000000000d1", "testCaseId": "6f1c2b3a-0000-4000-8000-0000000000c1", "resultKey": "manual:6f1c2b3a-0000-4000-8000-0000000000c1", "signature": "7f974c61f8f10065cd8ae6993cc069e4f85b1db1ed008b965885fb6f945a28c9", "status": "passed", "rawStatus": null, "source": "manual", "expectedStatus": "passed", "outcome": "expected", "execution": null, "durationMs": null, "caseVersion": 1, "errorContext": null, "errorContextMeta": null, "assertions": [], "steps": [ { "index": 0, "status": "passed" }, { "index": 1, "status": "passed" }, { "index": 2, "status": "passed" } ], "failure": null, "executedBy": null, "createdAt": "2026-09-16T09:12:04.151Z"}Invalid body, or nothing to change
object
Example generated
{ "error": "example"}No / invalid token or session
No such manual result in your projects — a reporter’s result reads as not found
object
Example generated
{ "error": "example"}The run is closed
object
Example
{ "error": "the run is closed — its results stand"}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