Streaming SSE — Server-Sent Events¶
Real-time event streaming during skill execution.
Endpoint¶
POST /v1/skills/{skill_id}/execute/stream
Same request body as /execute. Response is a Server-Sent Events stream.
Request¶
curl -N -X POST http://localhost:8080/v1/skills/my.skill/execute/stream \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_KEY" \
-d '{"inputs": {"text": "Hello world"}}'
Response Headers¶
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Event Format¶
Each engine event is emitted as an SSE event:
event: step_start
data: {"type":"step_start","message":"Starting step 'analyze'.","timestamp":"2026-03-25T12:00:00Z","step_id":"analyze","trace_id":"abc-123","data":null}
event: step_completed
data: {"type":"step_completed","message":"Step 'analyze' completed.","timestamp":"2026-03-25T12:00:01Z","step_id":"analyze","trace_id":"abc-123","data":{"produced_output":{"summary":"..."}}}
event: done
data: {"skill_id":"my.skill","status":"completed","outputs":{"result":"..."},"trace_id":"abc-123"}
Event Types¶
| Event | Description |
|---|---|
skill_start |
Skill execution begins |
step_start |
A step starts executing |
step_completed |
A step finished successfully |
step_skipped |
A step was skipped (condition false) |
step_degraded |
A step was degraded (safety gate) |
step_failed |
A step failed |
skill_completed |
Skill execution finished |
done |
Final event — contains the result |
Client Integration¶
JavaScript (EventSource not applicable for POST — use fetch)¶
const response = await fetch('/v1/skills/my.skill/execute/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': 'KEY' },
body: JSON.stringify({ inputs: { text: 'hello' } }),
});
const reader = response.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 });
const lines = buffer.split('\n');
buffer = lines.pop();
for (const line of lines) {
if (line.startsWith('data: ')) {
const event = JSON.parse(line.slice(6));
console.log(event.type, event.message);
}
}
}
Python¶
import requests
with requests.post(
'http://localhost:8080/v1/skills/my.skill/execute/stream',
json={'inputs': {'text': 'hello'}},
headers={'x-api-key': 'KEY'},
stream=True,
) as resp:
for line in resp.iter_lines(decode_unicode=True):
if line.startswith('data: '):
import json
event = json.loads(line[6:])
print(event['type'], event.get('message', ''))
Notes¶
- The connection stays open until
event: doneis emitted. - On error, the engine still emits
step_failedevents beforedone. - The
doneevent always contains the final result (same shape as/executeresponse). - Auth and rate limiting apply the same as for
/execute. execution_channelis automatically set to"http-stream".