# 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
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aleno.ai/apis/websocket-v1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
