# WebSocket API

Source: https://mimolive.com/user-manual/remote-control-automation/http-api/websocket-api/  
Last updated: 2026-10-25  
Section: Remote Control & Automation › HTTP API  

Besides the request-based [HTTP API](https://mimolive.com/user-manual/remote-control-automation/http-api/), mimoLive pushes notifications about changes over a WebSocket. A remote control, a dashboard or an integration can keep its view of mimoLive up to date this way without polling the [Endpoints](https://mimolive.com/user-manual/remote-control-automation/http-api/endpoints/).

### Connecting

The WebSocket is served by the same built-in web server as the HTTP API, so the HTTP API must be enabled in mimoLive’s preferences. Connect to:

```
ws://localhost:8989/api/v1/socket
```

- Replace “localhost” with the name or IP address of the Mac running mimoLive. If port 8989 is in use, mimoLive uses another port and advertises it over Bonjour as “\_http.\_tcp”.
- Use the URL exactly as shown: **no trailing slash and no query parameters**. Any other path, including one with “?…”, is answered with “404 Not Found”.
- The connection is unencrypted (“ws://”, not “wss://”).
- Don’t request a subprotocol. mimoLive doesn’t answer with one, so browsers reject the connection if you ask for one.
- Turning off the HTTP API in mimoLive closes all WebSocket connections.

> **Important:** The WebSocket doesn’t use the HTTP API password
>
> The password you set for the HTTP API protects the HTTP endpoints, but not the WebSocket. Anyone who can reach the port receives every event, including layer values and Data Store contents. Only enable the HTTP API on networks you trust, and check the password with an HTTP request before you rely on it.

### Messages You Can Send

The WebSocket is mainly one-way: mimoLive sends events, and every connected client receives all events of all open documents. There are no subscriptions or filters. The only message mimoLive answers is a ping:

```
{"event":"ping"}
```

mimoLive replies to that client only with:

```
{"event":"pong"}
```

Use this to check that the connection is still alive. mimoLive ignores all other messages.

> **Important:** Don’t use WebSocket protocol pings
>
> mimoLive closes the connection when it receives a protocol-level ping frame. Some WebSocket libraries send these automatically (for example Python’s “websockets” package every 20 seconds), so turn that feature off and use the JSON ping above instead. Always send “event” as a string, only send text frames, and keep messages below 64 KB.

### Event Messages

Each event is a single JSON object in one text frame. The order of the keys can vary.

| Key | Meaning |
| --- | --- |
| type | The kind of object that changed: “documents”, “layers”, “variants”, “sources”, “filters”, “layer-sets”, “output-destinations”, “render-pipelines” or “datastores”. |
| event | What happened: “added”, “changed”, “removed” or “values-changed”. For documents also “didFinishLoading”. |
| id | The ID of the object, the same ID the HTTP API uses. |
| data | The object as the HTTP API returns it in the “data” member of a GET request (with “type”, “id”, “attributes”, “relationships” and “links”). Missing for “removed”. For “values-changed” it contains only the changed values, for “datastores” it is the stored content encoded as Base64. |
| document-id | The ID of the document the object belongs to. Present for all types except “documents”. |
| layer-id | The ID of the layer. Only for “variants”. |
| source-id | The ID of the source. Only for “filters”. Note that this is the plain source ID without the “(DocumentID)-” prefix the source has in the HTTP API. |
| content-type | The content type of the stored data. Only for “datastores” added and changed. |
| ts | When the message was created, in milliseconds since January 1, 1970 (Unix time). |

See the [Data Types](https://mimolive.com/user-manual/remote-control-automation/http-api/data-types/) for the objects in “data”.

#### Event Types

| type | Events | Sent When |
| --- | --- | --- |
| documents | added, didFinishLoading, changed, removed | A document is opened, has finished opening, changes (title, show state, size, frame rate, recording/streaming state and more) or is closed. |
| layers | added, changed, removed, values-changed | Layers of the Layer Stack. “changed” is sent for name, live state, live or selected variant, volume and position changes. |
| variants | added, changed, removed, values-changed | Layer Variants. “changed” is sent when the name, the live state or a parameter value changes. |
| sources | added, changed, removed | Sources in the Sources Repository. “changed” is sent for name, tally state, gain and device changes. |
| filters | added, changed, removed | Filters of a source. |
| layer-sets | added, changed, removed | Layer Sets, including their active state. |
| output-destinations | added, changed, removed | Output destinations, including their live state and video and audio selection. |
| render-pipelines | added, changed, removed | Additional [program outputs](https://mimolive.com/user-manual/using-mimolive/multiple-program-outputs/) (mimoLive 7.0b1 and newer): added, renamed, resized or removed. The main program output has no events of its own; its size changes arrive as a “documents” change. |
| datastores | added, changed, removed | A Data Store was written or deleted with the HTTP API. |

#### Timing

- **added and removed** are sent immediately.
- **changed** events are combined per object: the first change is sent immediately, further changes within 0.3 seconds are sent once at the end of that period with the latest state. An event whose data is identical to the previous one for the same object is not sent again.
- **values-changed** carries live values five times per second: audio levels in “input-values” and remaining times (keys ending in “TimeRemaining”) in “output-values”. Only values that changed are included. Layers send them while they are live, variants for the variant currently shown in the layer preview.

### Keeping Your Client in Sync

- **Load the current state with HTTP requests.** Connecting doesn’t send a snapshot of the current state (except the first set of “values-changed” events). Open the WebSocket first, then read the documents, layers and so on through the [Endpoints](https://mimolive.com/user-manual/remote-control-automation/http-api/endpoints/).
- **Reconnect and reload.** mimoLive doesn’t keep events for disconnected clients. After a reconnect, load the state again with HTTP requests.
- **Clean up removed objects yourself.** When a document or layer is removed, mimoLive doesn’t send separate “removed” events for the objects it contains, such as its layers, sources or variants.
- **Filter by document.** Events of all open documents arrive on the same connection. Use “document-id” (or “id” for documents) to pick the ones you need.
- **Only the main program output’s layers are reported.** Values you unlock for an additional program output don’t create WebSocket events. Use the render pipeline endpoints to read them.

### Examples

Connecting from JavaScript:

```
const socket = new WebSocket("ws://localhost:8989/api/v1/socket");

socket.addEventListener("message", (message) => {
  const update = JSON.parse(message.data);
  if (update.event === "pong") return;
  console.log(update.type, update.event, update.id);
});

// check the connection every 30 seconds
setInterval(() => socket.send(JSON.stringify({ event: "ping" })), 30000);
```

A layer that was switched off:

```
{
  "type": "layers",
  "event": "changed",
  "id": "BA868701-8131-49CB-8EDD-8C7E6E7CD60B",
  "document-id": "378606417",
  "ts": 1792946240221,
  "data": {
    "type": "layers",
    "id": "BA868701-8131-49CB-8EDD-8C7E6E7CD60B",
    "attributes": { "name": "Placer", "live-state": "off", … },
    "relationships": { … },
    "links": { … }
  }
}
```

Live values of a layer:

```
{
  "type": "layers",
  "event": "values-changed",
  "id": "BA868701-8131-49CB-8EDD-8C7E6E7CD60B",
  "document-id": "378606417",
  "ts": 1792946224421,
  "data": {
    "output-values": { "tvOut_TimeRemaining": 12.5 }
  }
}
```

A program output was removed:

```
{
  "type": "render-pipelines",
  "event": "removed",
  "id": "6D1E2F40-58B3-4C8E-9A51-0F3B7C2D1E9A",
  "document-id": "378606417",
  "ts": 1792946300000
}
```
