> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://partner.ninjatrader.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://partner.ninjatrader.com/_mcp/server.

# User Synchronization

Use `user/syncrequest` to maintain real-time synchronization of user and account data. This is essential for accurate user and account updates, position and ordertracking, risk management, and auto liquidation/admin alerts.

### Signature and Overview

The JSON body for <code>user/syncrequest</code> looks like this:

```json
{
  "splitResponses": "boolean",
  "users": "number[]",
  "accounts": "number[]",
  "shardingExpression": {
    "divisor": "number",
    "remainder": "number",
    "expressionType": "modAccountId" | "modUserId"
  },
  "entityTypes": "string[]"
}
```

### Parameters

* **`splitResponses`** (boolean, required) - Mandatory. Should be `true` for any B2B vendor.
* **`users`** (number\[], optional) - Optional. Do not use if using `shardingExpression` or `entityTypes`.
* **`accounts`** (number\[], optional) - Optional. Do not use if using [Socket Sharding](https://partner.tradovate.com/overview/core-concepts/web-sockets/user-syncrequest#sharding).
* **`shardingExpression`** (object, optional) - Controls sharding behavior.
  * **`divisor`** (number) - Total number of socket shards desired.
  * **`remainder`** (number) - If userId or accountId divided by divisor has a remainder of 1, they will come to the socket with remainder: 1.
  * **`expressionType`** (string) - Either `"modAccountId"` or `"modUserId"`. Determines which entity type's IDs are used for the modulus operation.
* **`entityTypes`** (string\[], optional) - List of entity types you wish to receive.

**Important:** You must specify `entityTypes` now; the default is an empty array! Pass strings such as `"user"`, `"account"`, `"fill"`, `"fillPair"`, `"order"`, etc. These control which updates you receive.

You will receive system events for users based on the `expressionType` in sharding config, but `entityTypes` will not filter them out. You'll still receive signature events even if you aren't telling `entityTypes` to watch for them.

## Filter by Entity Type

To filter WebSocket updates by entity type, pass an `entityTypes` string array as described above.

This affects both the initial incoming dataset and the types of updates you receive over the socket's lifetime.

If omitted, the default is an empty array. This means you will not get updates for most entity types, except some special system events.

## Sharding

### What is Socket Sharding?

Sharding splits a workload among multiple instances to reduce load on any single actor. For our sockets, this means that if an actor fails, only a subset of users are affected.

### Sharding Behavior

1. An entity change occurs.
2. The server looks at the entity ID and considers the `expressionType` config option passed to `syncRequest`.
3. The entity ID is divided by `divisor`—the remainder controls which socket the event is published to.
4. Create or Update "props" event is fired.
5. The vendor socket application processes the event.
6. Only the socket with the correct remainder receives the event.

For example, socket A with `divisor = 3`, `remainder = 1` only receives updates when `entityId % divisor == 1`.

### Implementation Example

Set up sharded socket instances by determining the total number of desired shards and configuring that many sockets with corresponding remainders.

```typescript
// This function assumes you've created a class called Socket that wraps the actual WebSocket instance.
// This pseudo-version calls user/syncRequest as part of its startup routine, but you can configure
// the timing for the API command any sensible way you like.
function createSocketShard(
    accessToken: string, 
    divisor: number, 
    remainder: number
): Socket {
    return new Socket({
        url: 'https://demo-api.staging.ninjatrader.dev/v1/websocket',
        accessToken: accessToken,
        // The types filter used in syncRequest
        entityTypes: [
            'user',
            'account',
            'accountRiskStatus',
            'cashBalance',
            'fill',
            'accountRiskStatus'
        ],
        // The sharding expression used in syncRequest
        shardingExpression: {
            divisor,
            remainder,
            expressionType: 'modAccountId'
        }
    });
}

// Usage
const main = async () => {
  // You'll need to have acquired an access token,
  // here's a made-up function to grab one using the REST API
  const { accessToken } = await getAccessToken();

  // The shard function passes 3 as the divisor for each socket,
  // then we can set up the remainders configuratively.
  const socketA = createSocketShard(accessToken, 3, 0);
  const socketB = createSocketShard(accessToken, 3, 1);
  const socketC = createSocketShard(accessToken, 3, 2);

  // Subscribe to 'message' events on each socket instance.
  socketA.on('message', x => console.log('A', JSON.stringify(x)));
  socketB.on('message', x => console.log('B', JSON.stringify(x)));
  socketC.on('message', x => console.log('C', JSON.stringify(x)));

  // user/syncRequest is called as part of the connect routine
  await socketA.connect();
  await socketB.connect();
  await socketC.connect();
}

// Entry
main();
```