# Websocket V1

### **Overview**

This API allows clients to subscribe/unsubscribe to real-time market feeds over Socket.IO.Supported feed types:

* Crypto tickers via `subscribe_ticker / unsubscribe_ticker`
* Equities via `subscribe_equity / unsubscribe_equity`

Updates are currently emitted every 1 second for subscribed feeds. Each emitted record includes sentTimestampMs (server send timestamp in milliseconds).

### Authentication

A valid API key is required at connection time. Use either:

* auth.apiKey (recommended)
* x-api-key handshake header

If key is missing/invalid, connection is rejected with connect\_error (e.g. Missing or invalid API key.).

### WebSocket endpoint <a href="#websocket-endpoint" id="websocket-endpoint"></a>

WebSocket communication is implemented using a `socket.io` server, providing built-in support for automatic message compression and automatic reconnections, making client integration simpler and more reliable.

To connect, use the following WebSocket endpoint:

* **Server URL:** `https://pricing.aleno.ai`
* **Socket.IO path:** `/v1/socket`

Javascript Example (using `socket.io-client`):

```typescript
import { io } from 'socket.io-client';

const socket = io('https://pricing.aleno.ai', {
  path: '/v1/socket',
  auth: { apiKey: 'YOUR_API_KEY' },
  extraHeaders: { 'x-api-key': 'YOUR_API_KEY' }, // optional fallback
});
```

### Events

**Client -> Server**

* subscribe\_ticker (string\[], ack)
* unsubscribe\_ticker (string\[], ack)
* subscribe\_equity (string\[], ack)
* unsubscribe\_equity (string\[], ack)

**Server -> Client**

* new\_token\_states (crypto updates)
* new\_equity\_states (equities updates)

## Subscription behavior

* Symbols are normalized server-side (trim + uppercase).
* Unsupported symbols are rejected.
* Subscription acknowledgements can be:
* ok (all accepted),
* partial (some accepted, some rejected),
* error (request rejected, e.g. per-key feed limit exceeded).

### Acknowledgement payload

```json
{
  "status": "ok | partial | error",
  "involvedSubscriptions": ["AAPL", "MSFT"],
  "subscriptionsAfterUpdate": ["AAPL", "MSFT"],
  "rejectedSubscriptions": ["INVALID_SYMBOL"],
  "error": "Subscription limit reached. Contact us to increase limits."
}
```

Fields:

* status: operation result
* involvedSubscriptions: accepted symbols involved in the request
* subscriptionsAfterUpdate: current active subscriptions after processing
* rejectedSubscriptions (optional): unsupported/denied symbols
* error (optional): human-readable error for rejected operation

### Example: subscribe to crypto + equities

```typescript
import { io } from 'socket.io-client';

const socket = io('https://pricing.aleno.ai', {
  path: '/v1/socket',
  auth: { apiKey: 'YOUR_API_KEY' },
});

socket.on('connect', () => {
  socket.emit('subscribe_ticker', ['BTC/USD', 'ETH/USD'], (ack) => {
    console.log('ticker ack', ack);
  });

  socket.emit('subscribe_equity', ['AAPL', 'MSFT'], (ack) => {
    console.log('equity ack', ack);
  });
});

socket.on('new_token_states', (data) => {
  console.log('crypto updates', data);
});

socket.on('new_equity_states', (data) => {
  console.log('equity updates', data);
});

socket.on('connect_error', (err) => {
  console.error('Connection error:', err.message);
});
```

***

#### Unsubscribe example

```typescript
socket.emit('unsubscribe_ticker', ['BTC/USD'], (ack) => {
  console.log('unsubscribe ticker ack', ack);
});

socket.emit('unsubscribe_equity', ['MSFT'], (ack) => {
  console.log('unsubscribe equity ack', ack);
});
```

***

#### Payload notes

**`new_token_states`**

Array of crypto ticker state objects (existing ticker schema) with additional:

* sentTimestampMs: number

**`new_equity_states`**

Array of objects:

* sentTimestampMs: number
* symbol: string
* price: number

***

#### Limits

Per API key limits are enforced server-side (customer-specific configuration), including feed subscription limits.If a subscription exceeds your allowed limit, the server returns:

* `status: "error"`
* `error: "Subscription limit reached. Contact us to increase limits."`

***

#### Reconnection & resubscription

Socket.IO handles transport reconnection automatically, but clients should always reissue subscriptions on reconnect to guarantee continuity after disconnect/server restarts.socket.on('connect', () => {  // re-subscribe all required feeds here});

```typescript
socket.on('connect', () => {
  // re-subscribe all required feeds here
});
```
