List nodes
Parameters
Passing
q or search returns 400 with a pointer to /api/v1/search. This endpoint does not search.
Example
externalSystem and externalKey match exactly and are case-sensitive. More than one node can carry the same key, so the result is a list.
Response
createdAt is an ISO-8601 timestamp of when the node entered the plan. It is also returned on Search results and Tree nodes.
_meta.currentIteration is the first active phase by sort order, including the system Later phase, so it can be "Later" when no other phase is active. For the current phase as ProductBrain defines it (the first active non-system phase), use GET /iterations?current=true.
When an unfiltered read returns more than 50 nodes, _meta._tip reminds you to use search for lookups.
If you are looking for a specific node by concept, use Search instead of pulling all nodes and filtering. Search uses semantic matching and returns ranked results with ancestor paths.
Node structure
Every node has:Data fields by type
Setting a type-specific field on the wrong node type is rejected with
400.
External references
externalRefs records where a node lives in another tool: a Jira key, a roadmap-tool id. Up to 50 entries. One system may appear several times (a goal behind two roadmap objectives), but the same system and key only once.
No other fields are accepted. On update, send the whole list: it replaces the old one.
[] or null clears it.
A reference is a label. ProductBrain never infers hierarchy, sync or a relationship from it. Two nodes may carry the same key. When you write one, the response’s _meta._tip names the other nodes that already have it. Keys are not part of semantic search: look a key up with the externalSystem and externalKey filters above. Public share links never show externalRefs.
A bet that serves more than one need
A bet has exactly one parent: the need it is placed under and scoped against. Its Kano, size and measure refer to that need. When one build also helps other needs (an automation engine, an export layer), list them inserves instead of splitting the build into one bet per need:
- Bets only. Each id must be an existing need in the project, and not the bet’s own parent. Needs under another goal are allowed.
- At most 5, no repeats. On update, send the whole list: it replaces the old one.
[]ornullclears it. - Moving a bet under a need it already serves makes that need the parent, and the same write removes it from
serves. - When a write leaves a bet serving 3 or more extra needs, the response carries
_meta.advisorywithtype: "approach_serves_many". It usually means the bet is infrastructure whose own need is missing, or the needs overlap and should merge. - If a served need is deleted, its id stays in the list and is ignored on read.
serves is not blockedBy. blockedBy is a delivery dependency between bets: one can’t start until another lands. Read the other direction with the serves filter above, or with Tree direction=context on the need, which returns alsoServedBy. Public share links never show serves.
Demand: evidence on a need
demand records who feels a need, what’s behind them, and when it was observed. Up to 25 entries, needs only.
No other fields are accepted. On update, send the whole list: it replaces the old one.
[] or null clears it.
It’s evidence, never a ranking. The date belongs to the entry, not the need, and nothing ages, schedules, ranks or sorts a need by it. No endpoint filters or sorts by demand, and there’s no total. Public share links never show it, and search doesn’t index it.
Status
status tracks whether a job or task is live. The rule: done means in production.
- Absent: not started or in progress. Work merged only to staging is not done.
"done": live in production."open": send this on an update to reopen a closed job or task. It is stored asnullandcompletedAtis cleared. An explicitnullmeans the same thing."delivered": deprecated. Still accepted for old integrations, but treat it as “not done yet” and do not set it for new work.
approach) carry approachStatus instead, and goals carry goalStatus. Other node types have no status.
