> 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/devices/instinct.md).

# Anthriq Instinct

A motorised EXG headset. Electrodes are positioned by onboard motors, so the SDK can seat them, measure contact, and stream without anyone touching the hardware.

|             |                              |
| ----------- | ---------------------------- |
| Device type | `anthriq-instinct`           |
| Transport   | WebSocket, default port 9250 |
| Electrodes  | 15, built-in and motorised   |

## What it supports

| Feature     | Use it for                                | Page                                                                                 |
| ----------- | ----------------------------------------- | ------------------------------------------------------------------------------------ |
| `registers` | Gain, filtering, routing, channel mapping | [Configure channels](/bxi-studio/developer/overview/features/channels.md)            |
| `motors`    | Seating electrodes against the scalp      | [Position the headset](/bxi-studio/developer/overview/devices/instinct/motors.md)    |
| `impedance` | Confirming electrode contact              | [Measure contact impedance](/bxi-studio/developer/overview/features/impedance.md)    |
| `eeg`       | Streaming live samples                    | [Stream EXG](/bxi-studio/developer/overview/features/exg.md)                         |
| `firmware`  | Over-the-air updates                      | [Update firmware](/bxi-studio/developer/overview/features/firmware.md)               |
| `system`    | Capabilities and connection state         | [Read device information](/bxi-studio/developer/overview/get-started/device-info.md) |

`motors` is what separates Instinct from [xSys](/bxi-studio/developer/overview/devices/xsys.md), which uses the same device type but has no motorised electrodes.

## Run a session

The order matters: position before measuring contact, measure contact before recording.

1. [Install and connect](/bxi-studio/developer/overview/get-started/connect.md) with device type `anthriq-instinct`.
2. [Configure channels](/bxi-studio/developer/overview/features/channels.md) for gain and filtering.
3. [Position the headset](/bxi-studio/developer/overview/devices/instinct/motors.md).
4. [Measure contact impedance](/bxi-studio/developer/overview/features/impedance.md) and re-seat anything reading poorly.
5. [Stream EXG](/bxi-studio/developer/overview/features/exg.md), or [run parallel streams](/bxi-studio/developer/overview/features/parallel.md) to watch contact while recording.

## Set up

Motorised headset. The full sequence: connect, confirm health, configure a channel, **seat the electrodes**, check contact, stream, tear down.

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

```typescript
import { BxiClient, GainStage1, LpfSetting, MotorStatus } from "@anthriq_dev/bxi-interface";

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

// 1. Reach the bridge, then the device. Both calls, in order.
await client.initialize("localhost");
await client.connect();

// 2. Confirm the feature set before assuming anything exists.
const capabilities = client.getCachedCapabilities();
console.log(Object.keys(capabilities.features));

// 3. Configure a channel. Writes are partial: send only what changes.
await client.features.executeOperation("registers", "write", {
  type: "synap",
  synap_id: 0,
  fields: { enabled: 1, gain_stage_1: GainStage1.Gain20G, lpf_setting: LpfSetting.Hz300 },
});

// 4. Seat the electrode. Instinct only — xSys electrodes are wired by hand.
const move = await client.features.executeOperation("motors", "move", {
  motor_id: 0,
  displacement: 5,
  operation: "forward",
});
if (move.data.status & MotorStatus.Stall) {
  await client.features.executeOperation("motors", "stop", { motor_id: 0 });
  throw new Error("Motor stalled while seating the electrode");
}

// 5. Stream. Check contact impedance before recording for real.
const streamId = 20;

await client.features.executeOperation("eeg", "add_stream", {
  stream: {
    stream_id: streamId,
    protocol: "websocket",
    host: "127.0.0.1",
    port: 9020,
    elements_before_flush: 80,
  },
});
await new Promise((r) => setTimeout(r, 1000));

const subscription = await client.features.subscribeToOperation(
  "eeg",
  "stream",
  (update) => {
    if (!update.success) return;
    for (const frame of update.data.details.payload.frames ?? []) {
      for (const channel of frame.channels ?? []) {
        process(channel.channel_id, channel.adc_data);
      }
    }
  },
  { stream_id: streamId }
);
await new Promise((r) => setTimeout(r, 2000));

await client.features.executeOperation("eeg", "start_stream", { stream_id: streamId });
await new Promise((r) => setTimeout(r, 10000));

// 6. Tear down in reverse, or the device keeps sending after you exit.
await client.features.executeOperation("eeg", "stop_stream", { stream_id: streamId });
await new Promise((r) => setTimeout(r, 1500));
await client.features.unsubscribeFromOperation("eeg", "stream", {
  subscriptionId: subscription.data.subscriptionId,
});
await client.features.executeOperation("eeg", "remove_stream", { stream_id: streamId });

await client.shutdown();
```

{% endtab %}

{% tab title="Python" %}

```python
import asyncio
from anthriq_bxi_interface import BxiClient, GainStage1, LpfSetting, MotorStatus

client = BxiClient(device_type="anthriq-instinct")

# 1. Reach the bridge, then the device. Both calls, in order.
await client.initialize("localhost")
await client.connect()

# 2. Confirm the feature set before assuming anything exists.
capabilities = client.get_cached_capabilities()
print(list(capabilities.features))

# 3. Configure a channel. Writes are partial: send only what changes.
await client.execute_operation("registers", "write", {
    "type": "synap",
    "synap_id": 0,
    "fields": {"enabled": 1, "gain_stage_1": GainStage1.GAIN_20G,
               "lpf_setting": LpfSetting.HZ_300},
})

# 4. Seat the electrode. Instinct only — xSys electrodes are wired by hand.
move = await client.execute_operation("motors", "move", {
    "motor_id": 0, "displacement": 5, "operation": "forward",
})
if move.data["status"] & MotorStatus.STALL:
    await client.execute_operation("motors", "stop", {"motor_id": 0})
    raise RuntimeError("Motor stalled while seating the electrode")

# 5. Stream. Check contact impedance before recording for real.
stream_id = 20

await client.execute_operation("eeg", "add_stream", {
    "stream": {
        "stream_id": stream_id,
        "protocol": "websocket",
        "host": "127.0.0.1",
        "port": 9020,
        "elements_before_flush": 80,
    },
})
await asyncio.sleep(1)

def on_frame(update):
    if not update.success:
        return
    for frame in update.data["details"]["payload"].get("frames", []):
        for channel in frame.get("channels", []):
            process(channel["channel_id"], channel["adc_data"])

subscription = await client.subscribe_to_operation(
    "eeg", "stream", on_frame, {"stream_id": stream_id}
)
await asyncio.sleep(2)

await client.execute_operation("eeg", "start_stream", {"stream_id": stream_id})
await asyncio.sleep(10)

# 6. Tear down in reverse, or the device keeps sending after you exit.
await client.execute_operation("eeg", "stop_stream", {"stream_id": stream_id})
await asyncio.sleep(1.5)
await client.unsubscribe_from_operation(
    "eeg", "stream", {"subscriptionId": subscription.subscription_id}
)
await client.execute_operation("eeg", "remove_stream", {"stream_id": stream_id})

await client.shutdown()
```

{% endtab %}
{% endtabs %}

Each step in depth: [Configure channels](/bxi-studio/developer/overview/features/channels.md), [Position the headset](/bxi-studio/developer/overview/devices/instinct/motors.md), [Measure contact impedance](/bxi-studio/developer/overview/features/impedance.md), [Stream EXG](/bxi-studio/developer/overview/features/exg.md).

> **Note:** Confirm `motors` is present in the capabilities response before calling it. Instinct and [xSys](/bxi-studio/developer/overview/devices/xsys.md) share the device type `anthriq-instinct`, so the type alone does not say which is attached.
