> For the complete documentation index, see [llms.txt](https://docs.anthriq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.anthriq.com/bxi-studio/developer/overview/get-started/connect.md).

# Install and connect

`BxiClient` is the entry point. It spawns or attaches to the C++ bridge, opens the transport, queries device capabilities, and exposes operations through its `features` member.

## Install

{% tabs %}
{% tab title="Node.js" %}

```bash
npm install @anthriq_dev/bxi-interface
```

{% endtab %}

{% tab title="Python" %}

```bash
pip install anthriq-bxi-interface
```

{% endtab %}
{% endtabs %}

## Connect to a device

Connecting is two calls, in order. `initialize()` reaches the bridge; `connect()` reaches the device through it.

The only difference between devices is the device type string:

| Your hardware                    | Device type        |
| -------------------------------- | ------------------ |
| Instinct headset, xSys amplifier | `anthriq-instinct` |
| xBud                             | `ni-usb-daq`       |

{% tabs %}
{% tab title="Node.js" %}

```typescript
import { BxiClient } from "@anthriq_dev/bxi-interface";

const client = new BxiClient<"anthriq-instinct">({
  deviceType: "anthriq-instinct",
  timeout: 30000,
});

await client.initialize("localhost");
await client.connect();
```

{% endtab %}

{% tab title="Python" %}

```python
from anthriq_bxi_interface import BxiClient

client = BxiClient(device_type="anthriq-instinct", timeout=30000)

await client.initialize("localhost")
await client.connect()
```

{% endtab %}
{% endtabs %}

Operations issued between the two calls fail with a device-not-connected error: the bridge is reachable, the device is not.

## Address the device

`initialize()` accepts a bare host or a full WebSocket URL.

| `host` value                | Resulting URL             |
| --------------------------- | ------------------------- |
| `"localhost"`               | `ws://localhost:9250`     |
| `"192.168.1.100"`           | `ws://192.168.1.100:9250` |
| `"ws://localhost:9250"`     | Used verbatim             |
| `"wss://device.local:9250"` | Used verbatim             |

A bare host is expanded using the plugin's connection defaults, which are port 9250 for `anthriq-instinct`. Pass a full URL to reach an emulator or a non-standard port.

Devices announce themselves over mDNS with a hostname carrying the hardware variant, such as `anthriq-instinct-xsys-v1-4FFD98.local`. That name is a valid host:

{% tabs %}
{% tab title="Node.js" %}

```typescript
await client.initialize("ws://anthriq-instinct-xsys-v1-4FFD98.local:3333/ws");
await client.connect();
```

{% endtab %}

{% tab title="Python" %}

```python
await client.initialize("ws://anthriq-instinct-xsys-v1-4FFD98.local:3333/ws")
await client.connect()
```

{% endtab %}
{% endtabs %}

> **Note:** `initialize()` attaches to a running bridge daemon when it serves the same URL and respawns it when the URL differs. [How the SDK talks to a device](/bxi-studio/developer/overview/concepts/architecture.md) explains why that check exists.

## Connect to several devices at once

Clients of the same device type share one daemon by default. Set `instanceId` to key the daemon per device, so each client gets its own process, PID file, and socket. This is what makes several xBud units work at once.

{% tabs %}
{% tab title="Node.js" %}

```typescript
const xbud1 = new BxiClient<"ni-usb-daq">({
  deviceType: "ni-usb-daq",
  instanceId: "dev1",
  bridgeEnv: { NI_DEVICE_NAME: "Dev1" },
});

const xbud2 = new BxiClient<"ni-usb-daq">({
  deviceType: "ni-usb-daq",
  instanceId: "dev2",
  bridgeEnv: { NI_DEVICE_NAME: "Dev2" },
});
```

{% endtab %}

{% tab title="Python" %}

```python
xbud1 = BxiClient(
    device_type="ni-usb-daq",
    instance_id="dev1",
    bridge_env={"NI_DEVICE_NAME": "Dev1"},
)

xbud2 = BxiClient(
    device_type="ni-usb-daq",
    instance_id="dev2",
    bridge_env={"NI_DEVICE_NAME": "Dev2"},
)
```

{% endtab %}
{% endtabs %}

> **Warning:** Use `bridgeEnv` rather than setting process environment variables. The process environment is shared, so on concurrent connects the second write reaches the bridge already spawned for the first client, and both end up pointed at one device.

`bridgeEnv` applies only when the client spawns a new bridge. Attaching to an existing daemon leaves its environment untouched.

## Check the connection

Two flags distinguish the two hops. `isInitialized()` means the bridge answered and capabilities are known; `isConnected()` means the device link is open. A client can be initialized but not connected, which is exactly the window where operations fail with a device-not-connected error.

{% tabs %}
{% tab title="Node.js" %}

```typescript
client.isInitialized();   // bridge reached, capabilities known
client.isConnected();     // device link open

const state = await client.features.executeOperation("system", "get_state", {});
console.log(state.data.statusMessage);
```

{% endtab %}

{% tab title="Python" %}

```python
client.is_initialized()   # bridge reached, capabilities known
client.is_connected()     # device link open

state = await client.execute_operation("system", "get_state", {})
print(state.data["statusMessage"])
```

{% endtab %}
{% endtabs %}

See [Read device information](/bxi-studio/developer/overview/get-started/device-info.md).

## Shut down

Disconnect from the device, then shut down. `shutdown()` disconnects first when the link is still open, so it is safe on its own.

{% tabs %}
{% tab title="Node.js" %}

```typescript
try {
  // Use the client.
} finally {
  if (client.isConnected()) {
    await client.disconnect();
  }
  await client.shutdown();
}
```

{% endtab %}

{% tab title="Python" %}

```python
try:
    ...  # Use the client.
finally:
    await client.shutdown()
```

{% endtab %}
{% endtabs %}

`shutdown()` detaches from the bridge daemon rather than stopping it, since other clients may be attached. See [How the SDK talks to a device](/bxi-studio/developer/overview/concepts/architecture.md).

> **Warning:** Remove every stream before shutting down. A stream left registered keeps the device transmitting after the process exits. See [Stream lifecycle](/bxi-studio/developer/overview/concepts/streams.md).

## Next steps

* [Configure the client](/bxi-studio/developer/overview/get-started/configuration.md)
* [Read device information](/bxi-studio/developer/overview/get-started/device-info.md)
