Create a widget
const url = 'https://beta-api.plune.ai/v1/widgets';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"title":"Automated runs and failures","config":{"schemaVersion":1,"render":"line","bucket":"day","accumulated":false,"blocks":[{"entity":"run","metric":"count","filters":[{"property":"kind","values":["automated"]}]},{"entity":"run_result","metric":"count","filters":[{"property":"status","values":["failed","broken"]}]}],"segment":{"by":"label","values":["nightly"]}}}'};
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/widgets \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "title": "Automated runs and failures", "config": { "schemaVersion": 1, "render": "line", "bucket": "day", "accumulated": false, "blocks": [ { "entity": "run", "metric": "count", "filters": [ { "property": "kind", "values": [ "automated" ] } ] }, { "entity": "run_result", "metric": "count", "filters": [ { "property": "status", "values": [ "failed", "broken" ] } ] } ], "segment": { "by": "label", "values": [ "nightly" ] } } }'Saves a recipe in the project. The recipe is judged whole (400 with the field that is wrong) and its static cost against a 90-day reference (400 widget_too_expensive, with the numbers). At most 30 active widgets a project (409). Owner or member; a reader gets 403.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
The whole recipe of a widget; the server judges it on every write and every draft. Entities: case, run_result, run, requirement (a defect is not one yet). Properties come from a closed catalogue: a case has type, state, priority, suite, is_flaky, is_muted, tag; a result status, sub_status, source, muted, case_priority, environment, label; a run kind, environment, status_event, label; a requirement type, status, priority, category. A donut takes one block. A segment is cut across all blocks and only by a property they all have (label for runs and results; any groupable property for a single entity). Limits: 5 blocks, 10 segment values, 10 filters a block, 16 KiB.
object
Line only: the population at each moment. For run_result and run (they only arrive); a case, a requirement and a defect wait.
object
A duration only for run_result and run.
object
A groupable property of the entity. More than 20 groups: the rest is folded into «Other» with a true sum.
object
Example
{ "title": "Automated runs and failures", "config": { "schemaVersion": 1, "render": "line", "bucket": "day", "accumulated": false, "blocks": [ { "entity": "run", "metric": "count", "filters": [ { "property": "kind", "values": [ "automated" ] } ] }, { "entity": "run_result", "metric": "count", "filters": [ { "property": "status", "values": [ "failed", "broken" ] } ] } ], "segment": { "by": "label", "values": [ "nightly" ] } }}Responses
Section titled “ Responses ”Created
object
The whole recipe of a widget; the server judges it on every write and every draft. Entities: case, run_result, run, requirement (a defect is not one yet). Properties come from a closed catalogue: a case has type, state, priority, suite, is_flaky, is_muted, tag; a result status, sub_status, source, muted, case_priority, environment, label; a run kind, environment, status_event, label; a requirement type, status, priority, category. A donut takes one block. A segment is cut across all blocks and only by a property they all have (label for runs and results; any groupable property for a single entity). Limits: 5 blocks, 10 segment values, 10 filters a block, 16 KiB.
object
Line only: the population at each moment. For run_result and run (they only arrive); a case, a requirement and a defect wait.
object
A duration only for run_result and run.
object
A groupable property of the entity. More than 20 groups: the rest is folded into «Other» with a true sum.
object
The order on the dashboard.
Example
{ "id": "6f1c2b3a-0000-4000-8000-0000000000b4", "projectId": "u-shop::default", "title": "Automated runs and failures", "config": { "schemaVersion": 1, "render": "line", "bucket": "day", "accumulated": false, "blocks": [ { "entity": "run", "metric": "count", "filters": [ { "property": "kind", "values": [ "automated" ] } ] }, { "entity": "run_result", "metric": "count", "filters": [ { "property": "status", "values": [ "failed", "broken" ] } ] } ], "segment": { "by": "label", "values": [ "nightly" ] } }, "position": 0, "createdBy": "u-shop", "createdAt": "2026-09-16T09:12:04.151Z", "updatedAt": "2026-09-16T09:12:04.151Z"}Invalid recipe, or over the cost budget
object
Example generated
{ "error": "example"}No / invalid token or session
A read-only member
object
Example generated
{ "error": "example"}The project already has 30 active widgets
object
Example generated
{ "error": "example"}Rate-limited: the per-route throttle, or the per-minute request limit of the plan an API token counts by (#1442; the body names the plan, #2092). 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