POST /api/v1/workflow runs ProductBrain’s planning methodology and hands the prompts to your model. ProductBrain supplies the project context, the prompt engineering and the structural validation; you supply the LLM. The result is a well-formed Goal → Need → Approach → Job change, applied for you, with no drafts to manage. It consumes no ProductBrain AI credits.
Flows
task-curate is human-in-the-loop by design. Your classification is a set of proposals. Present each promote or discard to the user first and submit only their confirmed choices; set the rest to skip. The catalog carries this as an advisory on the flow, and the start response for task-curate repeats it in _meta._tip.
Discover the contract
input and advance.response shape, and notes. Build against that, not against this prose.
The loop
Every call is aPOST with projectId and an action of start or advance. A request without action returns 400 { "error": "action must be 'start' or 'advance'" }.
- Send
promptto your own LLM. Parse its reply into a structured response:{ "message": "...", "signal": "classified|confirmed|draft_ready|needs_clarification", "context": {...}, "draftNodes": [...] }foradd, or with aphasesoractionsarray forphase-assignortask-curate.
signal is 400 { "error": "advance requires state and a structured response { signal, message, context, draftNodes }" }. On a 400 with retry: true, re-call advance with the same state and a corrected response; do not call start again. state is opaque to you; pass it back verbatim.
nextInput is the user’s next utterance for conversational steps in add. When you omit it the machine proceeds as if the user agreed.
The changeset
The terminal response’schangeset is { action, nodeId, type, before, after }[]: exactly what the apply did. focus is a node id to show the user, and _meta.viewCommand is ready to pass to POST /view-command. To revert, reconstruct the inverse through /mutate: add → delete, update → restore before, delete → re-add before. A task-curate run that changes nothing returns done: true with an empty changeset.
Retry safety
When a terminal apply fails, the500 tells you which of four situations you are in:
The workflow’s internal call to
/mutate carries an Idempotency-Key derived from your state and response. Retrying an advance whose response never reached you cannot double-write. It cannot replay the original changeset either, so you get alreadyApplied: true and read the tree for the ids.
Payload limits
Oversized requests are rejected with400 before anything is written: at most 50 draft nodes per add, 100 phases and 1000 job assignments per phase-assign, 200 actions (each creating at most 10 nodes) per task-curate. Only the most recent 100 turns of conversation history in state are fed to the prompt. These are blast-radius guards, not product limits; split a bigger job across several flows.
Phase names
Phase names must describe user value.Later, Backlog, Polish and Catch-all are rejected with { retry: true }. Generic milestone names such as “Sprint” or “Phase 2” are not rejected but defeat the purpose.
Who can call it
Any Builder license including the free Builder tier, and Team (or membership of a Team-owned project). An active Strategist key gets403 "REST API access requires Builder or Team tier". A member’s key on a project whose owner is not on Team gets 403 "Shared-project API access requires the project owner to be on the Team tier". Strategist users drive the same state machine through the app UI.
Over MCP
Therun_workflow tool takes the same body: { "action": "start", "flow": "add", "input": "..." } to start and { "action": "advance", "state": ..., "response": ... } to advance. See MCP server.
