One test plan
const url = 'https://beta-api.plune.ai/v1/plans/example';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/plans/example \ --header 'Authorization: Bearer <token>'By id, from your projects only — another tenant’s reads as 404, never as 403. The plan itself, not what it collects: that is /cases.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Responses
Section titled “ Responses ”The plan
A titled collection of case filters. A plan is a query, not a list of ids: what it collects is resolved when asked (GET /v1/plans/{id}/cases), and a launch turns that into a run.
object
Unique within the project.
Up to 16 384 bytes.
Who executes it and which cases it may collect: manual takes manual cases, automated automated ones, mixed both. Evals belong to no plan.
The one exception to the strict mapping: a manual plan that also takes automated cases, to be walked by a person.
Each item is a case filter in its query-string form (suiteId=…&tag=…&priority=…&priorityMin=…&type=…&state=…&q=…, ADR 0001) — AND between its dimensions, OR within one, OR between collections. Written back canonical, so two spellings of one filter are one string. An empty string is every case.
Example
{ "id": "6f1c2b3a-0000-4000-8000-0000000000f3", "projectId": "u-shop::default", "title": "Release regression", "description": "Everything under checkout, plus every critical case wherever it lives.", "kind": "mixed", "asManual": false, "collections": [ "suiteId=6f1c2b3a-0000-4000-8000-0000000000a1", "priority=critical" ], "createdAt": "2026-09-16T09:12:04.151Z", "updatedAt": "2026-09-16T09:12:04.151Z"}No / invalid token or session
No such plan in your projects
object
Example generated
{ "error": "example"}