Import a traceability matrix as links (a dry run by default)
const url = 'https://beta-api.plune.ai/v1/projects/example/requirements/import/links';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"markdown":"# Traceability\n\n| Requirement | Test |\n|---|---|\n| REQ-FN-001 | Sign in with an e-mail link |\n| REQ-FN-002, REQ-FN-003 | Export an invoice as PDF |\n","table":0,"requirementColumn":"Requirement","testColumn":"Test","requirementSeparator":","}'};
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/projects/example/requirements/import/links \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "markdown": "# Traceability\n\n| Requirement | Test |\n|---|---|\n| REQ-FN-001 | Sign in with an e-mail link |\n| REQ-FN-002, REQ-FN-003 | Export an invoice as PDF |\n", "table": 0, "requirementColumn": "Requirement", "testColumn": "Test", "requirementSeparator": "," }'A table of a Markdown file with a column of requirement keys and a column of tests (#1608, epic #1594). A requirement is matched by its key (any case); a test by the exact title of a live case of the project or, for an automated case, by its specRef path. A row that matches nothing, or more than one case, is listed as unmatched with the reason: nothing is guessed. A pair already linked is unchanged, so a second import changes nothing. A requirement cell may hold several keys, split by requirementSeparator (default ,). dryRun is true unless the body says false: a dry run writes nothing; dryRun: false adds the new links in ONE transaction and answers the same report with applied: true. Links never override the computed coverage: it still comes from each case’s last result. An applied import is ONE audit entry with the counts. An owner or a member (a reader gets 403); a bearer token only in the project it was minted in. A file over 1 MiB, or a table over 2000 rows, or a report over 2000 rows once the cells are split, is a 413; an unknown table or column is a 400 naming the headers.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”An id from GET /v1/projects
Request Body required
Section titled “Request Body required ”object
The file’s text, at most 1048576 bytes (1 MiB).
Default true: nothing is written. false adds the new links in one transaction.
The matrix: its index from the discover call.
The header of the column with requirement keys.
The header of the column with test names or source paths (one per line, <br> between them). It is never split by requirementSeparator.
Splits a requirement cell into several keys (REQ-12, REQ-13); each part is trimmed, an empty part is dropped, a repeated key in one cell counts once, and each key is its own row of the report (same line). Only this text splits a cell: nothing else (;, a new line) is guessed.
Example
{ "markdown": "# Traceability\n\n| Requirement | Test |\n|---|---|\n| REQ-FN-001 | Sign in with an e-mail link |\n| REQ-FN-002, REQ-FN-003 | Export an invoice as PDF |\n", "table": 0, "requirementColumn": "Requirement", "testColumn": "Test", "requirementSeparator": ","}Responses
Section titled “ Responses ”The report - the same for a dry run and for an applied import
object
true once written; a dry run is false.
object
One per requirement-test pair of the table, in file order. unmatched rows say why: no requirement with that key, an archived requirement, no case with that exact title or path, or more than one.
object
1-based line of the row.
Example
{ "dryRun": true, "applied": false, "summary": { "link": 1, "unchanged": 0, "unmatched": 1 }, "items": [ { "line": 5, "action": "link", "key": "REQ-FN-001", "test": "Sign in with an e-mail link", "reason": "new", "requirementId": "req_1", "caseId": "case_1" }, { "line": 6, "action": "unmatched", "key": "REQ-FN-002", "test": "Export an invoice as PDF", "reason": "no case with this exact title or source path", "requirementId": "req_2" } ]}Invalid JSON or body; an unknown column (the message lists the headers) or table
object
Example generated
{ "error": "example"}No / invalid token or session
You are in the project as a reader
No such project among yours (or a token of another project)
object
Example generated
{ "error": "example"}The markdown is over 1 MiB, or the table has more than 2000 rows
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