> ## Documentation Index
> Fetch the complete documentation index at: https://docs.splox.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Listen to Workflow Execution (SSE)

> Streams real-time execution updates via Server-Sent Events as the workflow runs. First sends all existing node executions, then streams updates in real-time via Redis PubSub.

Streams real-time execution updates via Server-Sent Events (SSE) as the workflow runs.

## Usage

<CodeGroup>
  ```bash cURL theme={null}
  curl -N -H "Authorization: Bearer YOUR_TOKEN" \
    https://app.splox.io/api/v1/workflow-requests/{workflow_request_id}/listen
  ```

  ```python Python theme={null}
  from splox import SploxClient

  client = SploxClient(api_key="YOUR_API_KEY")

  for event in client.workflows.listen("WORKFLOW_REQUEST_ID"):
      if event.is_keepalive:
          continue
      if event.node_execution:
          ne = event.node_execution
          print(f"[{ne.status}] Node {ne.node_id}")
      if event.workflow_request:
          wr = event.workflow_request
          if wr.status in ("completed", "failed", "stopped"):
              print(f"Workflow {wr.status}")
              break
  ```

  ```typescript Node.js theme={null}
  import Splox from "splox";

  const client = new Splox("YOUR_API_KEY");

  const stream = await client.workflows.listen("WORKFLOW_REQUEST_ID");
  for await (const event of stream) {
    if (event.isKeepalive) continue;
    if (event.node_execution) {
      console.log(`[${event.node_execution.status}] Node ${event.node_execution.node_id}`);
    }
    if (event.workflow_request) {
      const status = event.workflow_request.status;
      if (["completed", "failed", "stopped"].includes(status)) {
        console.log(`Workflow ${status}`);
        break;
      }
    }
  }
  ```

  ```go Go theme={null}
  client := splox.NewClient("YOUR_API_KEY")

  iter, err := client.Workflows.Listen(ctx, "WORKFLOW_REQUEST_ID")
  if err != nil {
      log.Fatal(err)
  }
  defer iter.Close()

  for iter.Next() {
      ev := iter.Event()
      if ev.IsKeepalive {
          continue
      }
      if ev.NodeExecution != nil {
          fmt.Printf("[%s] Node %s\n", ev.NodeExecution.Status, ev.NodeExecution.NodeID)
      }
      if ev.WorkflowRequest != nil {
          switch ev.WorkflowRequest.Status {
          case "completed", "failed", "stopped":
              fmt.Printf("Workflow %s\n", ev.WorkflowRequest.Status)
              return
          }
      }
  }
  ```
</CodeGroup>

## How It Works

1. On connection, all existing node executions are sent immediately
2. Then the stream subscribes to real-time updates via Redis PubSub
3. Each event contains a `workflow_request` and/or `node_execution` update
4. Keepalive messages (`data: keepalive`) are sent every 3 seconds
5. The stream closes when the workflow completes, fails, or stops

## Response Format

Standard SSE format — each event is a `data:` line followed by two newlines:

```
data: {"workflow_request":{...},"node_execution":{...}}

data: keepalive

data: {"workflow_request":{"id":"...","status":"completed",...}}
```

Each event payload contains:

```json theme={null}
{
  "workflow_request": {
    "id": "0199f123-d60e-7ffd-9131-4cc5ab040ee8",
    "status": "in_progress",
    "workflow_version_id": "0199e001-a23b-7c8d-1234-567890abcdef"
  },
  "node_execution": {
    "id": "0199f124-e70f-8gge-2242-5dd6bc151ff9",
    "node_id": "0199e002-b34c-8d9e-2345-678901bcdef0",
    "status": "completed",
    "output_data": { "text": "Here is the result..." }
  }
}
```

## Status Values

**Workflow Request:**

* `pending` — Request received, waiting to start
* `in_progress` — Currently executing
* `waiting` — Paused, waiting for input (e.g., tool approval)
* `completed` — Finished successfully
* `failed` — Execution failed
* `stopped` — Manually stopped

**Node Execution:**

* `pending` — Queued
* `in_progress` — Currently executing
* `completed` — Finished successfully
* `failed` — Execution failed
* `blocked` — Waiting for dependencies
* `skipped` — Skipped (conditional branch not taken)
* `stopped` — Manually stopped
* `waiting` — Paused, waiting for input

## Notes

<Info>
  **Authentication required:** Include Bearer token in Authorization header.
</Info>

<Warning>
  **Connection timeout:** SSE connections timeout after 30 minutes. Reconnect if needed.
</Warning>


## OpenAPI

````yaml GET /workflow-requests/{id}/listen
openapi: 3.1.0
info:
  title: Splox API
  description: >-
    Run workflows, manage chats, receive events, and monitor execution via the
    Splox API
  version: 1.0.0
  contact:
    name: Splox Support
    email: support@splox.io
    url: https://community.splox.io
servers:
  - url: https://app.splox.io/api/v1
    description: Production API
security: []
tags:
  - name: MCP
    description: Discover MCP servers, manage connections, and execute MCP tools
  - name: Workflows
    description: List, get, and inspect workflows, versions, and nodes
  - name: Workflow Requests
    description: Run workflows, monitor execution, and retrieve results
  - name: Events
    description: Receive external events via Event Hub webhooks
  - name: Chats
    description: Manage chat sessions for workflow interactions
paths:
  /workflow-requests/{id}/listen:
    get:
      tags:
        - Workflow Requests
      summary: Listen to Workflow Execution (SSE)
      description: >-
        Streams real-time execution updates via Server-Sent Events as the
        workflow runs. First sends all existing node executions, then streams
        updates in real-time via Redis PubSub.
      operationId: listenWorkflowExecution
      parameters:
        - name: id
          in: path
          required: true
          description: Workflow request ID
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: >-
            SSE stream of execution events. Each event contains a
            workflow_request and/or node_execution update. Keepalive messages
            sent every 3 seconds. Connection times out after 30 minutes.
          content:
            text/event-stream:
              schema:
                type: object
                properties:
                  workflow_request:
                    $ref: '#/components/schemas/WorkflowRequest'
                  node_execution:
                    $ref: '#/components/schemas/NodeExecution'
      security:
        - bearerAuth: []
components:
  schemas:
    WorkflowRequest:
      type: object
      description: Represents a workflow execution request
      properties:
        id:
          type: string
          format: uuid
          description: Unique workflow request identifier
        workflow_version_id:
          type: string
          format: uuid
          description: ID of the workflow version being executed
        entry_node_ids:
          type: array
          items:
            type: string
            format: uuid
          description: IDs of the entry nodes execution began at
        user_id:
          type: string
          format: uuid
          description: ID of the user who owns the workflow
        billing_user_id:
          type: string
          format: uuid
          nullable: true
          description: ID of the user being billed for this execution
        parent_node_execution_id:
          type: string
          format: uuid
          nullable: true
          description: ID of parent node execution (for child agent invocations)
        parent_workflow_request_id:
          type: string
          format: uuid
          description: ID of parent workflow request (same as id for root requests)
        chat_id:
          type: string
          nullable: true
          description: Chat session ID associated with this execution
        status:
          type: string
          enum:
            - pending
            - in_progress
            - waiting
            - completed
            - failed
            - stopped
          description: Current execution status
        payload:
          type: object
          additionalProperties: true
          description: Input payload passed to the entry node
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: Additional metadata
        started_at:
          type: string
          format: date-time
          nullable: true
          description: When execution started
        completed_at:
          type: string
          format: date-time
          nullable: true
          description: When execution completed
        created_at:
          type: string
          format: date-time
          description: When the request was created
      required:
        - id
        - workflow_version_id
        - entry_node_ids
        - status
        - created_at
    NodeExecution:
      type: object
      description: Represents the execution state of a single node
      properties:
        id:
          type: string
          format: uuid
        workflow_request_id:
          type: string
          format: uuid
        node_id:
          type: string
          format: uuid
        workflow_version_id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - in_progress
            - completed
            - failed
            - blocked
            - skipped
            - stopped
            - waiting
        input_data:
          type: object
          nullable: true
        output_data:
          type: object
          nullable: true
        attempt_count:
          type: integer
        created_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true
        failed_at:
          type: string
          format: date-time
          nullable: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API token generated from your Splox account settings. Create tokens at
        https://app.splox.io/account?tab=settings

````