Spec sections
Read one heading of a spec, search inside it, list its acceptance criteria, and what the questions route does.
The /prd paths read a spec one piece at a time, for an agent
that wants a heading or the acceptance criteria rather than the whole body. They
work off the document's markdown, computed on each request from the blocks the
document is stored as, so they always reflect the body as it is right now.
On for every workspace. These paths carry no version segment, and they are /prd, not /documents.
The id in the path is still a document id, the same UUID the
spec list returns.
Spec section operations
| Method | Path | Scope | MCP tool |
|---|---|---|---|
GET | /prd/{documentId}/sections/{heading} | prd:read | none |
GET | /prd/{documentId}/search | prd:read | none |
GET | /prd/{documentId}/criteria | prd:read | none |
POST | /prd/{documentId}/questions | prd:write | none |
Paths are relative to https://api.getnima.io, and every call carries
Authorization: Bearer <your key>. Both scopes are open to any member and can be granted to an API key. See
Scopes and permissions. No MCP tool wraps these routes; over MCP, read the whole spec as markdown with the spec tools in Pipeline tools.
None of these bind themselves to the workspace your credential belongs to. They check only that you own the document or belong to the workspace holding it, so a credential whose owner is a member of two workspaces reads in both.
Read one section of a spec
/prd/{documentId}/sections/{heading}prd:readOne section of the body, as markdown. The heading is a path segment, so URL
encode it: Acceptance Criteria becomes Acceptance%20Criteria. Encode a
slash in the heading as %2F (encodeURIComponent does this for you): Build / Deploy
becomes Build%20%2F%20Deploy.
The match is case insensitive against the heading text at any level, and the
section runs to the next heading at the same or a higher level. The heading line
itself is not part of content.
Headings are matched as the markdown spells them, so a heading with bold or code
formatting keeps its ** or backticks. A line inside a code block that starts
with # also counts as a heading.
Response fields
headingstringcontentstringblockIdsstring[]Errors
| Status | error | When |
|---|---|---|
403 | Forbidden | Not a member of the workspace holding the document |
404 | Not Found | No such document, or no heading matches. The message reads Section "…" not found for the second. |
Search inside a spec
/prd/{documentId}/searchprd:readOne result per matching section, most relevant first, as a bare JSON array with no pagination.
Search splits the body at every heading, whatever its level, so a result for a ##
heading covers only the text before its first ###. That is narrower than a
section read, which includes subsections.
relevance is a raw count: matches in the heading counted twice, plus matches in
the body. It is not normalised, so it is comparable between sections of one
document and meaningless between documents. The snippet is roughly 60 characters
either side of the first match. When q matches only the heading, snippet is the
first 120 characters of the section body instead. Text above the first heading
belongs to no section and is not searched.
qstringAlways send q. Omitting it matches every section with a relevance proportional
to the section's length, which reads like a ranking and is not one.
Response fields
headingstringsnippetstringrelevanceintegerErrors
| Status | error | When |
|---|---|---|
403 | Forbidden | Not a member of the workspace holding the document |
404 | Not Found | No such document |
List the acceptance criteria
/prd/{documentId}/criteriaprd:readReads one section, the one headed Acceptance Criteria, and returns its checkbox
lines as a bare JSON array.
A ticked box is met, an empty box is pending. Only top-level checkbox lines
count: - [x] or - [X] is met, - [ ] is pending. Indented (nested)
checkboxes and any other lines are skipped. The heading match is case insensitive,
and a document without that heading returns an empty array
rather than an error, which is the same answer as a spec whose criteria are all
prose.
Response fields
criterionstringsectionstringAcceptance Criteria, since that is the only section read.statusenummet or pending. The shape also allows unmet; nothing produces it today.Errors
| Status | error | When |
|---|---|---|
403 | Forbidden | Not a member of the workspace holding the document |
404 | Not Found | No such document |
Raise a question on a spec
/prd/{documentId}/questionsprd:writeThis endpoint records nothing. It echoes your question back with a generated
id and threadId, never looks at documentId, and nothing appears in nima.
It answers 201 for a document that does not exist and for one you are not
allowed to read. Do not build on it. Not available yet as a real feature.
It is written up here because a key with prd:write reaches it and gets a
success back, which is worth knowing before you treat that success as a record.
The shape is not promised: it is a placeholder for the comment integration.
sectionstringrequiredquestionstringrequiredseverityenumrequiredblocking, clarification or suggestion.Response fields
idstringsectionstringsection, unchanged.questionstringquestion, unchanged.severityenumseverity, unchanged.createdAtISO 8601threadIdstringid. It leads to no thread.Errors
| Status | error | When |
|---|---|---|
400 | Bad Request | A missing field, or a severity outside the three values |
403 | INSUFFICIENT_PERMISSIONS | Missing prd:write scope, a role without the permission, or a plan without prd_generation |
There is no 403 Forbidden and no 404 for the document, whatever id you put in
the path; a missing prd:write scope still answers 403 INSUFFICIENT_PERMISSIONS.
The spec section object
The spec section object is what a section read returns.
headingstringcontentstringblockIdsstring[]The spec search result object
headingstringsnippetstringrelevanceintegerThe acceptance criterion object
criterionstringsectionstringAcceptance Criteria.statusenummet for a ticked box, pending for an empty one.The spec question object
idstringsectionstringquestionstringseverityenumcreatedAtISO 8601threadIdstringPlan feature for the spec section routes
The four spec section routes are declared under the plan feature prd_generation, separate from the documents feature the rest of the spec surface uses. A workspace whose plan lacks prd_generation can get a 403 with error set to INSUFFICIENT_PERMISSIONS and details.feature set to prd_generation. Handle that response; do not assume a scope alone is enough. Nobody is billed today.
Errors from the spec section routes
Errors from the spec section routes use nima's standard envelope, described in
API errors. As on the
specs routes,
the error field is not dependable: branch on statusCode, and on details when
it is there.
| Status | error | When |
|---|---|---|
400 | Bad Request | A field failed validation on the questions route. message reads Bad Request Exception and names nothing. |
403 | Forbidden | The document belongs to a workspace you are not a member of |
401 | TOKEN_INVALID | Missing, expired or revoked bearer |
403 | INSUFFICIENT_PERMISSIONS | Wrong scope, a role without the permission, or a plan without prd_generation (details.feature) |
404 | Not Found | No such document, or no heading matches |
429 | RATE_LIMITED | Over the limit. See Rate limits. |
500 | INTERNAL_SERVER_ERROR | On the three reads, a document id that is not a UUID reaches the database as it is, so it answers 500 rather than 404. Validate before you send. |
There is no RESOURCE_NOT_FOUND on this page: because these reads are not bound
to your credential's workspace, a document you cannot reach is a 403 rather
than a 404 in disguise.