Create a test plan
const url = 'https://beta-api.plune.ai/v1/plans';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"title":"Release regression","description":"Everything under checkout, plus every critical case wherever it lives.","kind":"mixed","collections":["suiteId=6f1c2b3a-0000-4000-8000-0000000000a1","priority=critical"]}'};
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/plans \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "title": "Release regression", "description": "Everything under checkout, plus every critical case wherever it lives.", "kind": "mixed", "collections": [ "suiteId=6f1c2b3a-0000-4000-8000-0000000000a1", "priority=critical" ] }'A title, a kind and one to twenty collections. Each collection is a case filter as a query string; it is read through the filter contract, so an unknown priority or state is refused with the filter’s own sentence (400), and written back canonical. The title is unique within the project (409 otherwise).
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
Example
{ "title": "Release regression", "description": "Everything under checkout, plus every critical case wherever it lives.", "kind": "mixed", "collections": [ "suiteId=6f1c2b3a-0000-4000-8000-0000000000a1", "priority=critical" ]}Responses
Section titled “ Responses ”Created
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"}Invalid body — a missing title, no collections, or a filter value outside its vocabulary
object
Example
{ "error": "validation failed — collections.1: unknown priority \"urgent\" — priorities are low, normal, important, high, critical"}No / invalid token or session
A plan of that title exists
object
Example
{ "error": "a plan titled 'Release regression' already exists"}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