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

# Node.js

> Connect to Anthid's Streaming API using Node.js and gRPC.

Anthid provides Protocol Buffer definitions that can be used to generate Node.js clients for the Streaming API.

This guide demonstrates connecting to the Streaming API and receiving real-time broker order and position updates.

## Prerequisites

Install the required dependencies.

```bash theme={null}
npm install @grpc/grpc-js @grpc/proto-loader
```

## Download the Protobuf Definitions

```bash theme={null}
git clone https://github.com/anthid-labs/proto.git
```

## Load the Proto Definitions

```javascript theme={null}
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");

const packageDefinition =
    protoLoader.loadSync(
        "trading.proto",
        {
            keepCase: false,
            longs: String,
            enums: String,
            defaults: true,
            oneofs: true,
        },
    );

const proto =
    grpc.loadPackageDefinition(
        packageDefinition,
    );

const trading = proto.trading;
```

## Authentication

Streaming requests are authenticated using the `x-api-key` metadata header.

```javascript theme={null}
const metadata = new grpc.Metadata();

metadata.add(
    "x-api-key",
    "YOUR_API_KEY",
);
```

## Subscribe to Events

The `SubscribeEvents` endpoint provides a server-streaming interface suitable for most applications.

```javascript theme={null}
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");

const packageDefinition =
    protoLoader.loadSync(
        "trading.proto",
    );

const proto =
    grpc.loadPackageDefinition(
        packageDefinition,
    );

const client =
    new proto.trading.TradingService(
        "stream.anthid.com:443",
        grpc.credentials.createSsl(),
    );

const metadata =
    new grpc.Metadata();

metadata.add(
    "x-api-key",
    "YOUR_API_KEY",
);

const stream =
    client.SubscribeEvents(
        {
            trading_account_id:
                "YOUR_TRADING_ACCOUNT_ID",
            subscriptions: [
                "EVENT_TYPE_BROKER_ORDER",
                "EVENT_TYPE_BROKER_POSITION",
            ],
        },
        metadata,
    );

stream.on("data", (event) => {
    if (event.heartbeat) {
        console.log("heartbeat");
    } else if (event.status) {
        console.log(
            "status:",
            event.status.message,
        );
    } else if (event.error) {
        console.log(
            "error:",
            event.error.message,
        );
    } else if (event.brokerOrder) {
        console.log(
            "order:",
            event.brokerOrder,
        );
    } else if (event.brokerPosition) {
        console.log(
            "position:",
            event.brokerPosition,
        );
    }
});

stream.on("error", (error) => {
    console.error(error);
});

stream.on("end", () => {
    console.log(
        "stream disconnected",
    );
});
```

## Bidirectional Streaming

Backend and long-running services can use `StreamEvents` to dynamically subscribe and unsubscribe from accounts over an existing connection.

```javascript theme={null}
const stream =
    client.StreamEvents(
        metadata,
    );

stream.write({
    subscribe: {
        trading_account_id:
            "YOUR_TRADING_ACCOUNT_ID",
        subscriptions: [
            "EVENT_TYPE_BROKER_ORDER",
            "EVENT_TYPE_BROKER_POSITION",
        ],
    },
});

stream.on("data", (event) => {
    console.log(event);
});
```

## Unsubscribe

To stop receiving events for an account, send an unsubscribe request on the same stream.

```javascript theme={null}
stream.write({
    unsubscribe: {
        trading_account_id:
            "YOUR_TRADING_ACCOUNT_ID",
    },
});
```

## Handling Disconnects

Applications should automatically reconnect when a stream closes unexpectedly.

After reconnecting:

1. Create a new stream.
2. Authenticate using the API key.
3. Re-subscribe to required trading accounts.
4. Resume event processing.

## TypeScript

The same approach works in TypeScript.

Many teams choose to generate strongly typed TypeScript definitions from the Anthid protobuf files during their build process rather than loading protobuf definitions dynamically at runtime.

## Related Resources

* Streaming Overview
* Python Guide
* Rust Guide
* Trading Accounts
* Orders
* Positions
* Ledger
* Intents
