ProductOS Platform

Unified Agents API

One sessionId, six agents — Ideation, Research, PRD, Design, Design-System, Code. Every call reads and writes the shared session state so each agent inherits full prior context (idea → opportunities → PRD → design → code). Design and Code terminal events always include a Blaxel sandbox URL.

SSE streamingBearer authShared session context

Base URL

https://platform.productos.dev/api/v1

Auth header

Authorization: Bearer <PRODUCTOS_API_KEY>

Quickstart

Create a session, then pipe it through as many agents as you need. Each call inherits the prior state — you never pass PRDs or opportunities back in manually.

bash
# 1. Create session
SESSION_ID=$(curl -s -X POST "https://platform.productos.dev/api/v1/sessions" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"idea":"AI-powered habit tracker for remote workers"}' \
  | jq -r .sessionId)

# 2. Run Ideation (SSE)
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/ideation-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"messages":[{"role":"user","content":"Help me shape this idea"}]}'

# 3. Research opportunities
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/research-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Accept: text/event-stream" \
  -d '{}'

# 4. Generate PRD → Design → Code
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/prd-agent"    -H "Authorization: Bearer $PRODUCTOS_API_KEY" -H "Accept: text/event-stream" -d '{"opportunityIndex":0}'
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/design-agent" -H "Authorization: Bearer $PRODUCTOS_API_KEY" -H "Accept: text/event-stream" -d '{}'
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/code-agent"   -H "Authorization: Bearer $PRODUCTOS_API_KEY" -H "Accept: text/event-stream" -d '{}'

Authentication

All requests require a Bearer token. You can use the shared PRODUCTOS_API_KEY or mint a per-user key from your dashboard.

http
Authorization: Bearer pos_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Server-Sent Events

Every agent endpoint streams text/event-stream. Each event has a monotonically-increasing cursor and a type discriminator. Every run ends with a terminal event (e.g. ideation_complete) followed by a done event.

javascript
const res = await fetch(`${BASE}/sessions/${sessionId}/ideation-agent`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
    Accept: 'text/event-stream',
  },
  body: JSON.stringify({ messages: [{ role: 'user', content: 'Help me shape this idea' }] }),
})

const reader = res.body!.getReader()
const decoder = new TextDecoder()
let buf = ''
while (true) {
  const { value, done } = await reader.read()
  if (done) break
  buf += decoder.decode(value, { stream: true })
  const lines = buf.split('\n\n')
  buf = lines.pop()!
  for (const line of lines) {
    if (!line.startsWith('data: ')) continue
    const event = JSON.parse(line.slice(6))
    if (event.type === 'text_delta') process.stdout.write(event.delta)
    if (event.type === 'ideation_complete') console.log('\n', event.ideaSummary)
    if (event.type === 'done') return
  }
}
Resumption. If the stream drops mid-run, call GET /sessions/{id}/events?since=<cursor> to replay everything after the last cursor you saw.

Sessions

Sessions are the thread of context every agent reads and writes. Create one, then reuse its id across agent calls.

Create session

Start a new session. Returns a sessionId every subsequent agent call inherits from.

POST/sessions

Creates a new ApiSession. Returns `{ sessionId, createdAt }`. The session becomes the thread of context every subsequent agent call reads from and writes to.

Request body

FieldTypeRequiredDescription
ideastringNoSeed idea summary. Optional — agents will also accept fresh input.
entrystringNoEntry phase hint — one of `ideation`, `discover`, `prd`, `design`, `design-system`, `code`.

Example body

json
{
  "idea": "AI-powered habit tracker for remote workers",
  "entry": "ideation"
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "idea": "AI-powered habit tracker for remote workers", "entry": "ideation" }'

Get session

Full session snapshot — ideaSummary, opportunities, PRD, sandbox URL, phase.

GET/sessions/{sessionId}

Returns the full session state: `ideaSummary`, `opportunities`, `prd`, `designSystemId`, `sandboxName`, `sandboxUrl`, `phase`. Use to hydrate your UI between agent calls or after an SSE disconnect.

cURL

bash
curl -N -X GET "https://platform.productos.dev/api/v1/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY"

Delete session

Permanently remove a session and its persisted events.

DELETE/sessions/{sessionId}

Deletes the ApiSession and all attached events. Irreversible — use when the session is no longer needed.

cURL

bash
curl -N -X DELETE "https://platform.productos.dev/api/v1/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY"

Replay events

Replays persisted SSE events after a cursor. Use to resume a dropped stream.

GET/sessions/{sessionId}/events?since=0

Returns all persisted SSE events after the given cursor. Use this to resume after a disconnected stream without losing state.

Parameters

FieldTypeRequiredDescription
sincenumber (query)NoCursor to resume from. Defaults to `0` (replay everything).

cURL

bash
curl -N -X GET "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/events?since=0" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY"

Agents

All agent endpoints are SSE streams. Bodies are minimal — the gateway derives the rest from the session. Each agent writes its output back to the session for the next agent to pick up.

Ideation Agent

Streams the Ideation agent. Turns vague input into a sharp idea summary.

POST/sessions/{sessionId}/ideation-agent

Streams the Ideation agent as Server-Sent Events. The agent analyses the conversation, pressure-tests the concept, and writes `ideaSummary` to the session.

Request body

FieldTypeRequiredDescription
messagesMessage[]YesChat-style history. Each message has `role` and `content`.
phasestringNo`conversation` for multi-turn ideation, or omit for a single-shot.

Example body

json
{
  "messages": [
    { "role": "user", "content": "I want to build something that helps remote workers keep healthy habits." }
  ],
  "phase": "conversation"
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/ideation-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "messages": [ { "role": "user", "content": "I want to build something that helps remote workers keep healthy habits." } ], "phase": "conversation" }'

SSE events

EventDescription
phaseSignals the agent has entered the ideation phase.
build_session_createdA BuildSession record has been created for this run.
text_deltaIncremental token stream — concatenate `delta` values to render the reply.
ideation_completeTerminal payload: `{ ideaSummary }`. Written to the session.
doneStream finished — close the connection.

Side effects

  • Writes `ideaSummary` to the session
  • Creates a `BuildSession` record

Research Agent

Multi-source research → synthesis → ranked opportunities with validation.

POST/sessions/{sessionId}/research-agent

Chat-style input (same shape as Ideation). The gateway concatenates user messages into the research `freeformContext` and auto-fills the rest of the exploration context from `session.ideaSummary` / `session.prd`. Writes `opportunities` to the session.

Request body

FieldTypeRequiredDescription
messagesMessage[]YesChat history. Minimum acceptable body is `{}` — the gateway derives everything from the session.
contextobjectNoEscape hatch to pin fields: `techStack[]`, `industries[]`, `searchDepth`, `enableValidation`.

Example body

json
{
  "messages": [
    { "role": "user", "content": "Focus on remote workers in wellness — validate against competitors and surface weekly-cohort opportunities." }
  ]
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/research-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "messages": [ { "role": "user", "content": "Focus on remote workers in wellness — validate against competitors and surface weekly-cohort opportunities." } ] }'

SSE events

EventDescription
phase`researching` → `synthesizing` → `validating` → `bias_check`.
statusPer-source progress (Perplexity, Reddit, etc.).
research_complete`{ totalSignals, sourcesSearched[] }`.
research_resultsRaw signals — `{ results: Signal[] }`.
opportunities3–4 ranked opportunities with scorecards and risks.
validation_progressPer-opportunity scoring updates.
discover_completeTerminal payload: `{ opportunities }`. Written to the session.
doneStream finished.

Side effects

  • Writes `opportunities` to the session

PRD Agent

Generates a PRD for the selected opportunity. Creates a Project record.

POST/sessions/{sessionId}/prd-agent

Generates a PRD for the selected opportunity and attaches it to the session. Writes `prd` + `projectId` to the session.

Request body

FieldTypeRequiredDescription
opportunityIndexnumberNoIndex of the opportunity to turn into a PRD. Defaults to `0` (the top-ranked).

Example body

json
{
  "opportunityIndex": 0
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/prd-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "opportunityIndex": 0 }'

SSE events

EventDescription
phase`{ phase: "prd" }`.
status`Writing PRD for...`.
prd_complete_finalTerminal payload: `{ prd, projectId }`.
doneStream finished.

Side effects

  • Writes `prd` and `selectedOpportunityIndex` to the session
  • Creates a `Project` record (`projectId`)

Design Agent

Renders UI screens inside a Blaxel sandbox. Returns a live preview URL.

POST/sessions/{sessionId}/design-agent

Chat-style input. The latest user message becomes the screen description; the gateway auto-fills `targetScreen` (id/name/type) and pulls brand/PRD from the session. Writes `sandboxName` / `sandboxUrl` to the session so the Code agent can attach to the SAME sandbox.

Request body

FieldTypeRequiredDescription
messagesMessage[]YesChat history. The last user message becomes the screen description.
brandobjectNoOverride brand — `{ mood, colors: { primary } }`.
targetScreenobjectNoOverride target screen — `{ id, name, description, type }`.
modelIdstringNoOverride the underlying model (e.g. `anthropic/claude-sonnet-4-6`).

Example body

json
{
  "messages": [
    { "role": "user", "content": "Design the landing page. Hero with bold value prop, three feature cards, pricing tiers, footer. Modern minimal aesthetic." }
  ]
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/design-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "messages": [ { "role": "user", "content": "Design the landing page. Hero with bold value prop, three feature cards, pricing tiers, footer. Modern minimal aesthetic." } ] }'

SSE events

EventDescription
phase`{ phase: "design" }`.
statusDesign agent progress updates.
design_completeTerminal payload: `{ sandboxUrl, sandboxName, designProjectId }`.
doneStream finished.

Side effects

  • Writes `sandboxName`, `sandboxUrl`, `designProjectId` to the session

Design-System Agent

Generates a full DESIGN.md design system with light/dark preview URLs.

POST/sessions/{sessionId}/design-system-agent

Directly invokes the DESIGN.md agent. Produces a complete design system document and renders it with light/dark preview URLs.

Request body

FieldTypeRequiredDescription
messagesMessage[]YesDesign-system brief as a chat message.
dsNamestringNoHuman-readable name for the generated design system.

Example body

json
{
  "messages": [
    { "role": "user", "content": "Generate a warm, minimal, accessible design system for a habit tracker." }
  ],
  "dsName": "Habit Tracker DS"
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/design-system-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "messages": [ { "role": "user", "content": "Generate a warm, minimal, accessible design system for a habit tracker." } ], "dsName": "Habit Tracker DS" }'

SSE events

EventDescription
phase`{ phase: "design-system" }`.
statusGeneration progress.
design_system_completeTerminal payload: `{ designSystemId, designMd, previewUrlLight, previewUrlDark }`.
doneStream finished.

Side effects

  • Writes `designSystemId` to the session

Code Agent

Builds or extends a full Next.js app inside a Blaxel sandbox.

POST/sessions/{sessionId}/code-agent

If the session has `sandboxName` (from a prior Design call), Code attaches to the SAME Blaxel sandbox and extends the code there. If not (direct entry), a fresh sandbox is provisioned. The Blaxel preview URL is in every terminal payload.

Request body

FieldTypeRequiredDescription
messagesMessage[]YesChat history. Each message can include `sandboxUrl` for targeted edits.

Example body

json
{
  "messages": [
    { "role": "user", "content": "Fix the tailwind css build error", "sandboxUrl": "https://xxxxx.sandbox.blaxel.ai" }
  ]
}

cURL

bash
curl -N -X POST "https://platform.productos.dev/api/v1/sessions/$SESSION_ID/code-agent" \
  -H "Authorization: Bearer $PRODUCTOS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "messages": [ { "role": "user", "content": "Fix the tailwind css build error", "sandboxUrl": "https://xxxxx.sandbox.blaxel.ai" } ] }'

SSE events

EventDescription
phase`{ phase: "coding" }`.
statusCode agent progress updates.
code_completeTerminal payload: `{ sandboxUrl, sandboxName, codeProjectId }`.
doneStream finished.

Side effects

  • Writes `sandboxUrl`, `sandboxName`, `codeProjectId` to the session

Errors & Recovery

StatusMeaningWhat to do
401Missing or invalid bearer tokenCheck `Authorization` header and key scope.
404Session not foundCreate a new session via `POST /sessions`.
429Rate limit hitBack off per `Retry-After`, then retry.
stream droppedSSE disconnected before terminal eventReplay via `GET /sessions/{id}/events?since=<cursor>`.

Ready to ship?

Grab an API key from the dashboard and start piping ideas through the stack.