docs
API

Knowledge graph API

Ask the knowledge graph over HTTP and read its markdown or agent-mode JSON answer line by line.

On for every workspace. GET /v1/knowledge-graph/ask needs the knowledge:read scope and no plan feature. A workspace connected yesterday has an almost empty graph, so early answers are thin.

nima keeps one knowledge graph per workspace. Its entities are the things a product is made of, its relationships connect them, and each entity carries sourced facts. This page is the reference for the one graph route a personal API key or OAuth token can call. For what the graph is and how it learns, see How nima knows your product. The same call is the ask_knowledge_graph MCP tool, documented on Knowledge tools.

The graph has 12 entity types: feature, user_need, technical_decision, constraint, requirement, discovered_concept, person, customer, product, goal, signal and organization. It has 17 relationship types: implements, depends_on, requested, owns, part_of, prioritized_by, signals, contacted_about, decided_by, constrained_by, specified_by, contradicts, supersedes, relates_to, blocks, enables and serves. Every fact names its source with one of 13 labels: SPEC, PR, COMMIT, SIGNAL, SLACK, PR_REVIEW, QA_RESPONSE, CODE_INDEX, PM_INPUT, MARKETING_PAGE, INFERRED, WEB_RESEARCH and CRM_RECORD.

Knowledge graph API operations at a glance

MethodPathScopeMCP tool
GET/v1/knowledge-graph/askknowledge:readask_knowledge_graph

Ask the knowledge graph over REST (GET /v1/knowledge-graph/ask)

GET/v1/knowledge-graph/ask
scopeknowledge:readMCP toolask_knowledge_graph

GET /v1/knowledge-graph/ask answers a natural-language question about your product, customers and past decisions from the workspace's knowledge graph. There is no workspace parameter: the answer covers the one workspace your token belongs to. By default the response is text/markdown; charset=utf-8, not JSON. With mode=agent it is compact JSON.

The route sits on the soft rate-limit tier, 300 requests per 10 seconds. The path is relative to https://api.getnima.io, and the call carries Authorization: Bearer <your key>. See Authentication and Scopes and permissions.

The markdown answer has no schema. It is a rendering: lines can be added and their wording can change without a version bump, so parse it defensively, or ask for mode=agent when the caller is a program.

Query parameters for the knowledge graph ask route

qstringrequired
The question. 2 to 500 characters. Plain language, not a keyword query. A question in a non-Latin script (Hebrew, Arabic, Russian, Chinese) is translated to English before searching; a Latin-script question in another language is not. If the translation does not come back in time, the question is searched as typed and the answer has no Searched in English line.
limitinteger
How many entities to return. 1 to 20, 8 by default. It counts entities, not facts.
modestring
Only agent is accepted. It returns compact JSON instead of markdown: no prose, no stale-summary line, no cap on facts or relations. Any other value is a 400.

The workspace is always the caller's own. A token with no workspace gets 403 INSUFFICIENT_PERMISSIONS with the message Must belong to an organization.

Errors from the knowledge graph ask route

StatuserrorWhen
400Bad Requestq missing, under 2 or over 500 characters; limit outside 1 to 20 or not a whole number; mode anything but agent.
401TOKEN_INVALIDNo token, or one that is malformed, expired or revoked.
403INSUFFICIENT_PERMISSIONSThe token does not carry knowledge:read, or the token has no workspace.
429RATE_LIMITEDOver 300 requests in 10 seconds. The response carries Retry-After.
503SERVICE_UNAVAILABLESomething nima depends on failed. Retry.

Errors has the envelope and what is worth retrying; Rate limits has the bucket rules.

Knowledge graph markdown answer format

The default answer is markdown, and every line in it is one of the shapes below. They appear in this order for each entity, and only the lines that apply are printed.

The first lines describe the whole answer.

Searched in English: "…" (translated from …)preamble
Printed first when nima translated a non-Latin-script question before searching. It names the English text that was searched and the source language. The answer content stays English.
Knowledge graph results for: "…"title
The question as you sent it.
⚠ No entity in the graph is named "x". Everything below is a semantic neighbour…warning
Printed once, above every entity, when the question named a literal (a file path, a symbol, a SCREAMING_SNAKE constant, a snake_case key, a ticket key such as BCN-23, "PR #80", or anything in quotes) and no returned entity carries it. The entities that follow are look-alikes, not the thing named.

Then one block per entity.

### Name (type) [modality] (match tag) · id: uuidheader
One matching entity. type is one of the 12 entity types. The bracketed modality is one word and is left out when nima cannot judge: implemented or fixed means the graph has evidence the thing is in the code, proposal means it was asked for or specced and never confirmed built, problem means a report that something is wrong. The match tag is (exact), (exact: fact <key>) (for example (exact: fact owner)) when a fact carries the literal you named, (mentioned in fact <key>) when only a hyphenated lowercase word such as code-intel appears in a fact, (no exact match) when you named a literal and this entity is not it, and nothing for a question that named no literal. After the dot comes the entity's own uuid.
References: N | Similarity: 0.NNNentity
How many times nima has matched this entity while reading your sources, and its cosine similarity to your question to three decimals. 0.000 means the entity was found by literal text and has no embedding score.
⚠ Superseded by names — the facts below describe how this used to work…banner
Printed before the summary and facts when a newer entity replaced this one. Read the entity it names for the current state.
⚠ NOT SHIPPED: this pull request was closed without merging…banner
Printed when the entity is itself a pull request that was closed unmerged. An open one reads ⚠ NOT SHIPPED YET: this pull request is still open…. A merged pull request prints nothing.
Summary: …entity
nima's summary of the entity. Absent when it has none yet.
⚠ Summary is stale since timestamp; verify against the source facts.warning
Facts changed after the summary was written. Trust the facts under it.
Facts:section
Header for the fact lines. At most 5 facts print per entity, and the rest collapse into … N more facts omitted. Facts carrying a literal you named come first. On customer and organization entities the account facts follow them, in this order: lifecycle, arr, plan, renewal_date, account_owner, segment. Bookkeeping facts from the code index (fileCount, cohesionScore, detectionMethod) are hidden.
- key: value (source: …, learned YYYY-MM-DD)fact
One fact. The source renders as TYPE https://… when the source has a single URL, as bare CODE_INDEX for code-index facts, and otherwise as TYPE:id.
[customer] · [external] · [internal] · [internal channel]origin tag
Appended inside the parentheses after the source of a SIGNAL fact, and after the quoted evidence of a relation a signal asserted: who the signal came from. internal channel is a Slack signal nobody classified, which says where it was posted, not who wrote it.
⚠ ASSUMED — the source hedged this; not confirmed by a humanfact suffix
The source said "assumed", "proposed" or "tentative". Do not treat the fact as a settled decision. A fact confirmed by a person ends with (confirmed) instead. A fact with neither has no suffix.
— "…"fact suffix
The sentence the fact was read from, cut to 120 characters followed by ….
⚠ contradicted: key "A" (source) vs "B" (source), YYYY-MM-DDwarning
Two sources still disagree on that key and neither value has been retired. At most 5 print, then … N more unresolved conflicts omitted., flush left.
Relations:section
Header for the relationship lines. At most 5 print, then … N more relations omitted.
- relation → Name (type) — "evidence"outgoing relation
This entity is the subject: it has that relationship to the named entity. The quoted sentence is the evidence.
- ← Name (type) relation this — "evidence"incoming relation
The named entity is the subject and this entity is the object. ← Streaming importer (feature) supersedes this reads "Streaming importer supersedes this entity". Always read the arrow together with the words around it.
⚠ NOT SHIPPED / NOT SHIPPED YET: asserted by a pull request…relation suffix
Appended to a relation whose evidence is a pull request that was closed without merging, or is still open. Do not treat that change as applied.

Knowledge graph agent-mode JSON

mode=agent returns one JSON object. Its fields are the same information as the markdown, without prose, without the five-line caps, and without raw source ids.

querystring
The question as sent.
queryTranslationobject
Present only when the question was translated: original, english, translated (boolean) and sourceLanguage (string or null).
identifiersstring[]
The literals the question named. A non-empty list with no entity whose match is exact means the graph does not hold the thing named.
entitiesobject[]
The matching entities, each with the fields below.
entities[].id, name, entityType, similarityfields
The entity's uuid, name, one of the 12 types, and cosine similarity.
entities[].summarystring | null
The summary, or null.
entities[].modalitystring
implemented, fixed, proposal, problem or unknown.
entities[].matchstring
exact, semantic (the question named no literal, or only hyphenated lowercase words such as code-intel) or none (the question named a literal such as a path, symbol, constant, ticket key or quoted text, and this entity carries none of them). matchedFactKey names the fact that carried it, and matchVia: "fact_mention" marks a hyphenated lowercase word found only in a fact.
entities[].supersededBystring[]
Names of the entities that replaced this one. Non-empty means every fact is historical.
entities[].prLifecyclestring | null
merged, closed_unmerged or open when the entity is itself a pull request, otherwise null.
entities[].factsobject[]
Each has key, value, confidence, sourceType, sourceUrl (or null), sourceExcerpt (or null), learnedAt (YYYY-MM-DD), confirmationState (assumed, confirmed or null) and, for a SIGNAL source, origin (customer, external, internal or internal_channel).
entities[].relationsobject[]
Each has relationType, targetName, targetType, targetEntityId (or null), evidence, direction (out when this entity is the subject, in when it is the object), prLifecycle (merged, closed_unmerged, open or null), prMergeSha (or null) and optionally origin.
entities[].conflictsobject[]
Each has key, valueA, valueB and detectedAt.

If the question could not be embedded, agent mode answers 200 with {"query": "…", "entities": [], "identifiers": []}.

Knowledge graph ranking and empty answers

Entities do not come back in strict order of similarity, and an empty answer is a 200, not an error. Nima ranks by cosine similarity between your question and each entity's summary, then adjusts.

  • An entity whose name or alias appears in the question gets a large boost, and a near-miss spelling gets a smaller one.
  • An entity whose facts all came from the code index is ranked lower, and so is an entity a newer one supersedes.
  • When the question names a literal, every entity that carries it is returned first.
  • Vector matches must reach a similarity of 0.6. Name and alias matches and exact-literal carriers skip that floor, and a literal-text fallback can return entities with Similarity: 0.000. So a 0.000 hit is found by wording, not by meaning.

When nothing qualifies, the status is 200, the type is text/markdown, and the body is:

No product entities found for: "why did we drop the legacy importer". The knowledge graph may not have information about this area yet.

If the question could not be turned into a vector, the status is also 200 and the body is:

Could not generate an embedding for: "why did we drop the legacy importer". No knowledge graph results.

Neither case is an error, so a client that only checks the status treats both as an answer. Test for a line that starts with one of these two sentences (a translated question puts a Searched in English: line above it), or for the absence of a ### line. Nothing coming back is not proof that nothing is there: the graph holds only what your connected tools have told nima, and a proposal modality must not be read as shipped.

Knowledge graph routes not reachable with a key

GET /v1/knowledge-graph/ask is the only knowledge graph route an API key or OAuth token can use. The other graph routes take a signed-in browser session only: a bearer token gets 403 INSUFFICIENT_PERMISSIONS with the message This endpoint does not accept OAuth access tokens, whatever scopes it carries. That covers drawing the graph, opening a single entity, searching entities by name, and the change journal with its undo, which is limited to workspace owners and admins. No route creates or edits a fact directly, and the web app has no graph page. Ask the nima team if you need one of these.

The knowledge:read scope also opens code search, blast radius and data model lookups under /v1/code-intel/. They answer JSON and are documented on Code intelligence API.