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

# TCP and OSC

> Call the Core API over a plain TCP line protocol or OSC over UDP, for tools that cannot speak HTTP.

Besides HTTP, the Core can answer the same API over two extra transports. Both are **off by default**. Switch them on per studio under **Settings > Studio > Core API > TCP and OSC**.

Both transports use the same features, permissions, read and control access, station guard and request log as HTTP. The settings apply without a restart. If a port cannot be bound, the Core logs an error and keeps the other transports running.

| Transport | Setting | Default port |
| - | - | - |
| TCP line protocol | `tcp_port` | `3003` |
| OSC over UDP | `osc_port` | `3004` |

Ports must be between 1024 and 65535. The TCP port cannot be the HTTP API port.

## TCP line protocol

The protocol is UTF-8 text, one request per line. A line ends with `\n` or `\r\n` and is at most 4096 bytes. Requests on one connection are answered in order, one reply line each.

A request is a Core API v2 route as in the HTTP API, without `/api/v2`:

```text theme={null}
studio/onair
cameras/2/cut
signals/audio-director/toggle
outputs/main/rundown/take?item=3
variables/title/set?value=Hello%20world
```

A leading `/`, `api/v2/`, `plain/` and a `GET ` or `POST ` verb are accepted and ignored. Path segments and query values may be percent-encoded.

### Replies

The reply is the [plain-text](/develop-with-vra/core-control-api/plain-text-routes) presentation of the route:

| Call | Reply |
| - | - |
| An action | `OK` |
| A read | The value, like `onair` or `1` |
| A failure | `ERR <code>` |

The codes are the same as over HTTP: `invalid_args`, `unauthorized`, `forbidden`, `feature_disabled`, `read_only`, `not_found`, `not_active`, `station_mismatch`, `station_changing`, `signal_disabled`, `not_ready`, `timeout` and `error`. See [Errors and status codes](/develop-with-vra/core-control-api/errors-and-status-codes).

Prefix a route with `JSON ` to get the JSON body on one line instead:

```text theme={null}
JSON studio/status
```

### Commands

| Line | Reply |
| - | - |
| `AUTH vra_<token>` | `OK`, or `ERR unauthorized` |
| `PING` | `PONG` |

`AUTH` authenticates the connection with a device token. Without it, the caller's IP address is judged by the LAN access setting (Off, Listed devices or Whole LAN), exactly as for HTTP. See [Authentication and LAN access](/develop-with-vra/core-control-api/authentication-and-lan-access). Legacy (EXTERNAL\_APP) authorization is not accepted: only v2.

### Example

```bash theme={null}
printf 'AUTH vra_...\nstudio/status\nstudio/onair\n' | nc core-pc 3003
```

## OSC

The Core listens for OSC 1.0 messages on the UDP port `osc_port`. Bundles are unpacked and their messages handled in order.

### Address

The address is `/vra/` plus the route:

```text theme={null}
/vra/studio/onair
/vra/cameras/2/cut
/vra/macros/Morning%20show/trigger
```

The `/vra` prefix is optional. OSC wildcards (`*`, `?`, `[` and `{`) are not supported and answer `ERR invalid_args`.

### Arguments

* A string `vra_<token>` is the device token.
* A string `name=value` sets that query parameter, like `wait=0` or `station=Radio 1`.
* A string `name=value` is the only way to set `scene`, `station`, `timeout` and `wait`.
* Every other argument (int, float, string, true or false) fills the route's other query parameters in declared order. For `/vra/signals/count/set ,i 5` that is `value`. For `/vra/outputs/main/rundown/take ,s "2.3"` that is `item`.
* Numbers without a fraction are sent as integers, so `1.0` becomes `1`. True and false become `1` and `0`.

### Buttons

Many OSC controllers, like TouchOSC, send `1` when a button is pressed and `0` when it is released. On a route that takes no value, a message whose only argument is `0` or false is treated as a release and ignored. A toggle button therefore fires once per press, and gets no reply for the release.

### Reply

The Core answers with one UDP datagram to the sender's IP. It goes to `osc_reply_port`, or to the sender's source port when that is empty.

* Address: `/vra/reply` plus the route, like `/vra/reply/studio/status`.
* Arguments: `i` the HTTP status, and `s` the plain reply.

For example `200 "onair"` or `409 "ERR not_active"`.

## Security

UDP sender addresses can be forged on the local network. Prefer a device token, or a device with a fixed address, and keep LAN access at **Listed devices**.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.