> For the complete documentation index, see [llms.txt](https://docs.spaceoperator.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.spaceoperator.com/visual-builder/flows/websocket.md).

# WebSocket

Connect to `wss://dev-api.spaceoperator.com/ws` or `ws://localhost:8080/ws`

First, you must send authentication message and wait for the response:

```
{
  "Authenticate": {
    "token": "YOUR_API_KEY"
  }
}
```

`token` can be either API key or JWT token (without `Bearer` prefix). Success response with the user ID:

```
{
  "id": 0,
  "Ok": {
    "user_id": "3b93d859-b9d1-4230-ad4b-e498d7f1b796"
  }
}
```

After you post to `/flow/start/<flow-id>`, you will get a `flow_run_id`, use it so subscribe to events in Websocket.\
Send this text message to subscribe:

```
{
  "SubscribeFlowRunEvents": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c"
  }
}
```

Response:

```
{
  "id": 1,
  "Ok": {
    "subscription_id": 3
  }
}
```

After that, you will receive messages whenever there are new events. `sub_id` field will tell you which subscription the event belongs to.

```
{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.454924955Z",
    "content": {
      "NodeFinish": {
        "node_id": "fdf66b26-8cdf-44b3-b77b-452ac184d867",
        "times": 0
      }
    }
  }
}

{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.454975954Z",
    "content": {
      "NodeOutput": {
        "node_id": "fdf66b26-8cdf-44b3-b77b-452ac184d867",
        "times": 0,
        "output": {
          "M": {
            "balance": {
              "U": "12577139861"
            }
          }
        }
      }
    }
  }
}

{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.455002619Z",
    "content": {
      "NodeStart": {
        "node_id": "2f7fe126-1c42-4ad6-9162-f38e884c619a",
        "times": 0,
        "input": {
          "M": {
            "": {
              "U": "12577139861"
            }
          }
        }
      }
    }
  }
}

{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.455006837Z",
    "content": {
      "NodeFinish": {
        "node_id": "2f7fe126-1c42-4ad6-9162-f38e884c619a",
        "times": 0
      }
    }
  }
}

{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.455014395Z",
    "content": {
      "NodeOutput": {
        "node_id": "2f7fe126-1c42-4ad6-9162-f38e884c619a",
        "times": 0,
        "output": {
          "M": {
            "balance": {
              "U": "12577139861"
            }
          }
        }
      }
    }
  }
}

{
  "sub_id": 3,
  "event": {
    "flow_run_id": "b4e5edc0-6d59-4db2-9eb0-2380906e461c",
    "time": "2023-03-11T18:40:16.455018890Z",
    "content": {
      "FlowFinish": {
        "not_run": [],
        "output": {
          "M": {
            "balance": {
              "U": "12577139861"
            }
          }
        }
      }
    }
  }
}

{
  "sub_id": 3,
  "event": "Done"
}
```

When the stream ends, `"event": "Done"` is sent, you can keep the websocket connection to use again later.
