Skip to content

What a Markdown file holds, for the mapping step of an import

POST
/v1/projects/{id}/requirements/import/discover
curl --request POST \
--url https://beta-api.plune.ai/v1/projects/example/requirements/import/discover \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "markdown": "# Billing SRS\n\n## 3. Functional requirements\n\n| ID | Requirement | Priority |\n|----|-------------|----------|\n| REQ-FN-001 | The system **shall** let a user sign in with an e-mail link. | Critical |\n| REQ-FN-002 | The system shall export an invoice as a PDF file. | High |\n" }'

The first step of importing requirements from a .md file (#1605, epic #1594): the structure found, so a client can ask the person which table or section holds requirements. The frontmatter keys, every heading with its level and the number of list items under it, every table with its nearest heading, its header cells, its row count and its first three rows, and a guess (looksLikeRequirements) for the tables that look like requirements. Nothing is stored. An owner or a member of the project in the path (a reader gets 403); a bearer token only in the project it was minted in. A file over 1048576 bytes is a 413 naming the limit.

id
required
string

An id from GET /v1/projects

Media type application/json
object
markdown
required

The file’s text, at most 1048576 bytes (1 MiB): over it is a 413 that names the limit.

string
Example
{
"markdown": "# Billing SRS\n\n## 3. Functional requirements\n\n| ID | Requirement | Priority |\n|----|-------------|----------|\n| REQ-FN-001 | The system **shall** let a user sign in with an e-mail link. | Critical |\n| REQ-FN-002 | The system shall export an invoice as a PDF file. | High |\n"
}

What the file holds

Media type application/json
object
frontmatter
required
object
keys
required
Array<string>
title
required

The title scalar, read by a strict reader (no anchors, tags or nesting).

string
nullable
sections
required

Every heading, in file order; index is what the import’s section takes.

Array<object>
object
index
required
integer
heading
required
string
name
required

The heading as a name: no escapes, bold, leading numbering or trailing colon, lower case. section in the import matches it as well as the heading text.

string
level
required
integer
>= 1 <= 6
line
required

1-based.

integer
bulletCount
required

Top-level list items between this heading and the next of the same or a higher level.

integer
subheadingCount
required

Headings one level below it, in the same span.

integer
tables
required

Every pipe table, in file order; index is what the import’s table takes.

Array<object>
object
index
required
integer
line
required

1-based line of the header row.

integer
heading
required

The nearest heading above it.

string
nullable
headers
required

Empty for a table too wide to be read.

Array<string>
rowCount
required
integer
firstRows
required

The first three rows, cells flattened (<br> is a line break) and cut at 200 characters.

Array<Array<string>>
looksLikeRequirements
required

A guess: an id-like first column and a header naming a requirement, text, description or title. The person decides.

boolean
looksLikeCases
required

The headers include Given, When and Then (any case): the table can be offered as manual test cases, caseTables of the import (#1624).

boolean
unreadable

Present when the table cannot be imported (more than 200 columns).

string
truncated
required

The file had more headings, tables or list items than are kept.

boolean
limits
required

The import’s limits: markdownBytes, rows, columns, mapEntries.

object
key
additional properties
integer
Example
{
"frontmatter": {
"keys": [],
"title": null
},
"sections": [
{
"index": 0,
"heading": "Billing SRS",
"level": 1,
"line": 1,
"bulletCount": 0,
"subheadingCount": 1
},
{
"index": 1,
"heading": "3. Functional requirements",
"level": 2,
"line": 3,
"bulletCount": 0,
"subheadingCount": 0
}
],
"tables": [
{
"index": 0,
"line": 5,
"heading": "3. Functional requirements",
"headers": [
"ID",
"Requirement",
"Priority"
],
"rowCount": 2,
"firstRows": [
[
"REQ-FN-001",
"The system **shall** let a user sign in with an e-mail link.",
"Critical"
],
[
"REQ-FN-002",
"The system shall export an invoice as a PDF file.",
"High"
]
],
"looksLikeRequirements": true,
"looksLikeCases": false
}
],
"truncated": false,
"limits": {
"markdownBytes": 1048576,
"rows": 2000,
"columns": 200,
"mapEntries": 200
}
}

Invalid JSON or body

Media type application/json
object
error
required
string
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)

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}

The markdown is over 1 MiB

Media type application/json
object
error
required
string
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.

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}
Retry-After
integer

Seconds until the window rolls over