Offer tests this project has no case for
const url = 'https://beta-api.plune.ai/v1/review-items/discovered';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"runId":"4f1a7f6e-0000-4000-8000-0000000000aa","discovered":[{"keys":[{"kind":"playwright-id","value":"pw-cart"}],"title":"cart adds an item","source":"playwright","specRef":"e2e/checkout.spec.ts:12","rawStatus":"passed"}]}'};
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/review-items/discovered \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "runId": "4f1a7f6e-0000-4000-8000-0000000000aa", "discovered": [ { "keys": [ { "kind": "playwright-id", "value": "pw-cart" } ], "title": "cart adds an item", "source": "playwright", "specRef": "e2e/checkout.spec.ts:12", "rawStatus": "passed" } ] }'A runner reports the tests it ran that resolved to no case. Each becomes a queue entry of a third kind — one that testifies a case is missing rather than describing one — and a reviewer decides whether the project tracks it. Approving creates an automated case and attaches the keys, which is what makes the next run resolve instead of offering the same test again. Nothing is created here: the review queue remains the only way a case is born.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
A test the caller runs that this project has no case for. It carries NO steps and no expected result, and that is the shape rather than a gap: a reporter sees a test’ RESULT, never its source, so it testifies that a case is missing instead of describing one. Approving the entry creates an automated case pointing at specRef and attaches every key, so the next run resolves instead of discovering the same test again.
object
The identity. Order does not matter — the server ranks them and the highest-ranked kind is what deduplication reads, so two adapters sending the same keys in a different order do not produce two entries about one test.
An identifier another tool already uses for this test, so a report can find its case without anyone typing a Plune id. The order of kind is load-bearing: it is the ranking that decides which key wins when several match different cases.
object
The reporter that found it, e.g. playwright.
Where the test lives, e.g. e2e/checkout.spec.ts:12. Required while everything descriptive is optional: an approved discovery becomes an automated case, and that shape needs a spec to point at.
What it did on this run, in the reporter’ own word.
The run that turned it up, once stored.
The run that turned these up. Checked against the caller’ own runs.
Examples
One test a Playwright suite ran and Plune has no case for
{ "runId": "4f1a7f6e-0000-4000-8000-0000000000aa", "discovered": [ { "keys": [ { "kind": "playwright-id", "value": "pw-cart" } ], "title": "cart adds an item", "source": "playwright", "specRef": "e2e/checkout.spec.ts:12", "rawStatus": "passed" } ]}Responses
Section titled “ Responses ”The batch was read. Read the verdicts, not only the status — 200 does NOT mean every test was queued, and a caller that assumes it will re-offer refused tests for ever or go quiet about a real gap.
object
What became of ONE offered test. Read it per test: most of a repeated batch is already known or already refused, and a status line cannot say which.
object
The key the server identified this test by — its highest-ranked kind.
object
queued — a new entry is waiting for a reviewer. duplicate — an entry about this test already exists. refused — a reviewer has already declined it, and the answer outlives the run that provoked it. known — a case already holds this key, so nothing should have been offered; resolve before discovering. created — the project trusts this source, so the case was made without asking; count these, because they are the ones a reporter would otherwise report as nothing happening.
The queue entry, when there is one.
The case a trusted source produced. Only on created.
Example
{ "results": [ { "key": { "kind": "playwright-id" }, "outcome": "queued" } ]}Nothing was stored. Either the list is missing or exceeds the ceiling, or a test carries a field this kind of entry does not have — steps and an expected result are REFUSED by name rather than dropped, because a client that sent them believes they were stored.
object
Example generated
{ "error": "example"}No / invalid token or session
The runId is not one of the caller’ runs. Nothing is stored — answering 201 to a partly wrong request would leave rows missing the one field nobody would think to look for again.
object
Example generated
{ "error": "example"}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