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.
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.
# 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.
Authorization: Bearer pos_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxServer-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.
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
}
}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.
/sessionsCreates a new ApiSession. Returns `{ sessionId, createdAt }`. The session becomes the thread of context every subsequent agent call reads from and writes to.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| idea | string | No | Seed idea summary. Optional — agents will also accept fresh input. |
| entry | string | No | Entry phase hint — one of `ideation`, `discover`, `prd`, `design`, `design-system`, `code`. |
Example body
{
"idea": "AI-powered habit tracker for remote workers",
"entry": "ideation"
}cURL
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.
/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
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.
/sessions/{sessionId}Deletes the ApiSession and all attached events. Irreversible — use when the session is no longer needed.
cURL
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.
/sessions/{sessionId}/events?since=0Returns all persisted SSE events after the given cursor. Use this to resume after a disconnected stream without losing state.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| since | number (query) | No | Cursor to resume from. Defaults to `0` (replay everything). |
cURL
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.
/sessions/{sessionId}/ideation-agentStreams the Ideation agent as Server-Sent Events. The agent analyses the conversation, pressure-tests the concept, and writes `ideaSummary` to the session.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Yes | Chat-style history. Each message has `role` and `content`. |
| phase | string | No | `conversation` for multi-turn ideation, or omit for a single-shot. |
Example body
{
"messages": [
{ "role": "user", "content": "I want to build something that helps remote workers keep healthy habits." }
],
"phase": "conversation"
}cURL
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
| Event | Description |
|---|---|
| phase | Signals the agent has entered the ideation phase. |
| build_session_created | A BuildSession record has been created for this run. |
| text_delta | Incremental token stream — concatenate `delta` values to render the reply. |
| ideation_complete | Terminal payload: `{ ideaSummary }`. Written to the session. |
| done | Stream 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.
/sessions/{sessionId}/research-agentChat-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
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Yes | Chat history. Minimum acceptable body is `{}` — the gateway derives everything from the session. |
| context | object | No | Escape hatch to pin fields: `techStack[]`, `industries[]`, `searchDepth`, `enableValidation`. |
Example body
{
"messages": [
{ "role": "user", "content": "Focus on remote workers in wellness — validate against competitors and surface weekly-cohort opportunities." }
]
}cURL
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
| Event | Description |
|---|---|
| phase | `researching` → `synthesizing` → `validating` → `bias_check`. |
| status | Per-source progress (Perplexity, Reddit, etc.). |
| research_complete | `{ totalSignals, sourcesSearched[] }`. |
| research_results | Raw signals — `{ results: Signal[] }`. |
| opportunities | 3–4 ranked opportunities with scorecards and risks. |
| validation_progress | Per-opportunity scoring updates. |
| discover_complete | Terminal payload: `{ opportunities }`. Written to the session. |
| done | Stream finished. |
Side effects
- Writes `opportunities` to the session
PRD Agent
Generates a PRD for the selected opportunity. Creates a Project record.
/sessions/{sessionId}/prd-agentGenerates a PRD for the selected opportunity and attaches it to the session. Writes `prd` + `projectId` to the session.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| opportunityIndex | number | No | Index of the opportunity to turn into a PRD. Defaults to `0` (the top-ranked). |
Example body
{
"opportunityIndex": 0
}cURL
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
| Event | Description |
|---|---|
| phase | `{ phase: "prd" }`. |
| status | `Writing PRD for...`. |
| prd_complete_final | Terminal payload: `{ prd, projectId }`. |
| done | Stream 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.
/sessions/{sessionId}/design-agentChat-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
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Yes | Chat history. The last user message becomes the screen description. |
| brand | object | No | Override brand — `{ mood, colors: { primary } }`. |
| targetScreen | object | No | Override target screen — `{ id, name, description, type }`. |
| modelId | string | No | Override the underlying model (e.g. `anthropic/claude-sonnet-4-6`). |
Example body
{
"messages": [
{ "role": "user", "content": "Design the landing page. Hero with bold value prop, three feature cards, pricing tiers, footer. Modern minimal aesthetic." }
]
}cURL
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
| Event | Description |
|---|---|
| phase | `{ phase: "design" }`. |
| status | Design agent progress updates. |
| design_complete | Terminal payload: `{ sandboxUrl, sandboxName, designProjectId }`. |
| done | Stream 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.
/sessions/{sessionId}/design-system-agentDirectly invokes the DESIGN.md agent. Produces a complete design system document and renders it with light/dark preview URLs.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Yes | Design-system brief as a chat message. |
| dsName | string | No | Human-readable name for the generated design system. |
Example body
{
"messages": [
{ "role": "user", "content": "Generate a warm, minimal, accessible design system for a habit tracker." }
],
"dsName": "Habit Tracker DS"
}cURL
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
| Event | Description |
|---|---|
| phase | `{ phase: "design-system" }`. |
| status | Generation progress. |
| design_system_complete | Terminal payload: `{ designSystemId, designMd, previewUrlLight, previewUrlDark }`. |
| done | Stream finished. |
Side effects
- Writes `designSystemId` to the session
Code Agent
Builds or extends a full Next.js app inside a Blaxel sandbox.
/sessions/{sessionId}/code-agentIf 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
| Field | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Yes | Chat history. Each message can include `sandboxUrl` for targeted edits. |
Example body
{
"messages": [
{ "role": "user", "content": "Fix the tailwind css build error", "sandboxUrl": "https://xxxxx.sandbox.blaxel.ai" }
]
}cURL
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
| Event | Description |
|---|---|
| phase | `{ phase: "coding" }`. |
| status | Code agent progress updates. |
| code_complete | Terminal payload: `{ sandboxUrl, sandboxName, codeProjectId }`. |
| done | Stream finished. |
Side effects
- Writes `sandboxUrl`, `sandboxName`, `codeProjectId` to the session
Errors & Recovery
| Status | Meaning | What to do |
|---|---|---|
| 401 | Missing or invalid bearer token | Check `Authorization` header and key scope. |
| 404 | Session not found | Create a new session via `POST /sessions`. |
| 429 | Rate limit hit | Back off per `Retry-After`, then retry. |
| stream dropped | SSE disconnected before terminal event | Replay via `GET /sessions/{id}/events?since=<cursor>`. |
Ready to ship?
Grab an API key from the dashboard and start piping ideas through the stack.