Stream Run
Stream real-time ActionFlows run updates over the REST API using Server-Sent Events (SSE). Includes connection details and event payload formats.
Stream Run
Stream real-time updates for a running flow execution using Server-Sent Events (SSE).
Endpoint
GET /api/runs/{runId}/streamTry it
Live requests run from your browser. Open the API Explorer to try every operation from one screen.
/api/runs/{runId}/streamStream run updates
Requests go to the live API from your browser. The docs server never sees this key.
curl -X GET 'https://api.actionflows.ai/api/runs/{runId}/stream' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Accept: application/json'Response
Send a request to see the response.
Authentication
Required. See API Reference for authentication details.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
runId | string | Yes | The unique identifier of the run (must start with run_) |
Response
This endpoint returns a Server-Sent Events (SSE) stream. The response is a continuous stream of events.
Event Types
Connected Event
Sent immediately when the connection is established:
data: {"type":"connected","runId":"run_123"}
Update Event
Sent whenever the run status or data changes:
data: {"type":"update","data":{"id":"run_123","status":"EXECUTING",...}}
Completed Event
Sent when the run finishes (completed, failed, canceled, or similar):
data: {"type":"completed","status":"COMPLETED"}
Error Event
Sent if an error occurs while streaming:
data: {"type":"error","error":"Error message"}
Example Requests
JavaScript (EventSource)
const runId = 'run_123';
// Create EventSource for SSE
const eventSource = new EventSource(
`https://api.actionflows.ai/api/runs/${runId}/stream`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
}
);
// Handle connection
eventSource.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.type === 'connected') {
console.log('Connected to stream for run:', data.runId);
} else if (data.type === 'update') {
console.log('Run update:', data.data);
console.log('Status:', data.data.status);
} else if (data.type === 'completed') {
console.log('Run completed with status:', data.status);
eventSource.close();
} else if (data.type === 'error') {
console.error('Stream error:', data.error);
eventSource.close();
}
});
// Handle errors
eventSource.onerror = (error) => {
console.error('EventSource error:', error);
eventSource.close();
};JavaScript (Fetch with ReadableStream)
const runId = 'run_123';
async function streamRun(runId) {
const response = await fetch(
`https://api.actionflows.ai/api/runs/${runId}/stream`,
{
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Stream failed');
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
if (data.type === 'connected') {
console.log('Connected to stream');
} else if (data.type === 'update') {
console.log('Update:', data.data);
} else if (data.type === 'completed') {
console.log('Completed:', data.status);
return;
} else if (data.type === 'error') {
console.error('Error:', data.error);
return;
}
}
}
}
}
// Use it
streamRun(runId).catch(console.error);Python
import requests
import json
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
}
run_id = 'run_123'
response = requests.get(
f'https://api.actionflows.ai/api/runs/{run_id}/stream',
headers=headers,
stream=True
)
if response.status_code != 200:
error = response.json()
raise Exception(error.get('error', 'Stream failed'))
for line in response.iter_lines():
if line:
decoded_line = line.decode('utf-8')
if decoded_line.startswith('data: '):
data = json.loads(decoded_line[6:])
if data['type'] == 'connected':
print(f"Connected to stream for run: {data['runId']}")
elif data['type'] == 'update':
print(f"Update: {data['data']}")
print(f"Status: {data['data']['status']}")
elif data['type'] == 'completed':
print(f"Completed with status: {data['status']}")
break
elif data['type'] == 'error':
print(f"Error: {data['error']}")
breakcURL
curl -N -H "Authorization: Bearer YOUR_API_KEY" \
https://api.actionflows.ai/api/runs/run_123/streamThe -N flag disables buffering for real-time streaming.
Event Data Structure
Connected Event
{
"type": "connected",
"runId": "run_123"
}Update Event
{
"type": "update",
"data": {
"id": "run_123",
"status": "EXECUTING",
"taskIdentifier": "run-flow",
"payload": {
"organizationId": "org_123",
"actionFlowId": "flow_123"
},
"updatedAt": "2024-01-01T00:01:00.000Z"
}
}Completed Event
{
"type": "completed",
"status": "COMPLETED"
}Possible status values: COMPLETED, FAILED, CANCELED, CRASHED, TIMED_OUT
Error Event
{
"type": "error",
"error": "Error message"
}Error Responses
If the stream fails to start, you'll receive a JSON error response:
400 Bad Request
{
"success": false,
"error": "Invalid run ID"
}401 Unauthorized
{
"success": false,
"error": "Unauthorized",
"message": "Authentication required"
}429 Too Many Requests
{
"success": false,
"error": "Too many requests"
}Notes
- The stream polls for updates every second
- The stream automatically closes when the run completes, fails, or is canceled
- You can manually close the connection by closing the EventSource or canceling the fetch request
- The stream will send updates whenever the run status or data changes
- Use this endpoint for real-time monitoring of long-running flows
- This endpoint is rate-limited per user
- The connection may timeout after extended periods of inactivity
Use Cases
- Real-time progress monitoring
- Live dashboards showing flow execution
- Immediate notification when flows complete
- Debugging long-running flows
- Building interactive UIs that show flow progress
Browser Compatibility
For browser usage, EventSource is the recommended approach as it handles reconnection automatically. For Node.js or more control, use fetch with ReadableStream.