PromptFloe Developer Docs
Build

Streaming events

All streaming endpoints emit newline-delimited JSON (NDJSON) over HTTP. The SDKs parse this for you; the wire format is documented here for raw HTTP clients.

#Wire format

Streaming endpoints respond with Content-Type: application/x-ndjson and a chunked transfer. Each line is a self-contained JSON object terminated by \n:

Response body
{"type":"plan","summary":"Landing page + pricing + footer"}
{"type":"file","path":"src/App.tsx","contents":"..."}
{"type":"file","path":"src/components/Hero.tsx","contents":"..."}
{"type":"review","notes":"Looks good — minor a11y nits patched."}
{"type":"ready","appId":"app_abc","previewUrl":"https://..."}

#Event types

Every event has a type discriminator. The full set across endpoints:

FieldTypeDescription
planbuildPlanner agent finished. summary + manifest of files.
filebuildA code agent committed a file to the workspace.
reviewbuildReviewer ran. notes + list of files patched.
augmenterbuildLifecycle event for a queued augmenter (started, applied, failed).
readybuildBuild finished. previewUrl + appId.
chunkskillToken delta from a streaming skill. Append delta to your buffer.
insightskillStructured insight chip extracted from the run.
file_writtenskillAugmenter wrote a file. Includes path and status.
progressskillSub-stage update for long-running skills.
doneskillRun finished cleanly. tokensUsed + durationMs.
erroranyTerminal error. Stream closes after this.

#Parsing without the SDK

If you're calling the API directly, parse the body line by line:

const res = await fetch('https://api.promptfloe.com/v1/apps/generate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + apiKey,
    'Content-Type': 'application/json',
    'Accept': 'application/x-ndjson',
  },
  body: JSON.stringify({ prompt: 'pricing page' }),
});

const reader = res.body!.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });

  let newline;
  while ((newline = buffer.indexOf('\n')) !== -1) {
    const line = buffer.slice(0, newline);
    buffer = buffer.slice(newline + 1);
    if (line.trim()) {
      const event = JSON.parse(line);
      handleEvent(event);
    }
  }
}

#Reconnection

Streams are stateful — a dropped connection mid-build is not automatically resumed. To recover:

  1. The server keeps the run alive for 5 minutes after disconnect.
  2. Re-attach to it via GET /v1/runs/:runId/events?cursor=<last_event_id>.
  3. The endpoint replays missed events from the cursor and continues streaming.

#Cancellation

See Cancellation for aborting a stream cleanly.

#Where to go next

PromptFloe developer docs