# WebSocket API

Stream real-time trading data, price feeds, and market events via high-performance WebSocket connections.

## Overview

**WebSocket URL**: `wss://theros.pro/api/data`

**Connection Limits**:

* Standard: 5 concurrent connections, 50 messages/second
* Premium: 20 concurrent connections, 200 messages/second

## Connecting

### JavaScript/TypeScript

```javascript
const ws = new WebSocket('wss://theros.pro/api/data');

ws.onopen = () => {
  console.log('Connected to Theros WebSocket');

  // Subscribe to trades
  ws.send(JSON.stringify({
    method: 'subscribe',
    keys: ['trades']
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = (event) => {
  console.log('Connection closed:', event.code, event.reason);
};
```

### Python

```python
import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    print('Received:', data)

def on_error(ws, error):
    print('Error:', error)

def on_close(ws, close_status_code, close_msg):
    print('Connection closed')

def on_open(ws):
    print('Connected to Theros WebSocket')

    # Subscribe to trades
    ws.send(json.dumps({
        'method': 'subscribe',
        'keys': ['trades']
    }))

ws = websocket.WebSocketApp(
    'wss://theros.pro/api/data',
    on_open=on_open,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close
)

ws.run_forever()
```

## Authentication

For WebSocket connections, include your API key in the initial connection message:

```javascript
ws.onopen = () => {
  // Authenticate
  ws.send(JSON.stringify({
    method: 'authenticate',
    apiKey: 'YOUR_API_KEY'
  }));
};
```

You'll receive a confirmation:

```json
{
  "type": "authenticated",
  "userId": "user_123",
  "plan": "premium"
}
```

## Subscription Methods

### Subscribe to Channels

```javascript
ws.send(JSON.stringify({
  method: 'subscribe',
  keys: ['trades', 'newTokens']
}));
```

**Available Channels**:

* `trades` - All token trades across the platform
* `newTokens` - Newly created tokens
* `priceUpdates` - Real-time price updates
* `{MINT_ADDRESS}` - Events for a specific token

**Success Response**:

```json
{
  "type": "subscribed",
  "keys": ["trades", "newTokens"],
  "timestamp": 1697234567890
}
```

### Subscribe to Specific Token

```javascript
ws.send(JSON.stringify({
  method: 'subscribe',
  keys: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v']
}));
```

### Unsubscribe

```javascript
ws.send(JSON.stringify({
  method: 'unsubscribe',
  keys: ['trades']
}));
```

## Event Types

### Trade Event

Emitted when a token trade occurs.

```json
{
  "type": "trade",
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "signature": "5j7sK8K2YaFvS2hE3YgY4zRtV3pGq1Y7zxP8c9X3Qa6",
  "trader": "7BgBvyjrZX8YTqjkKrfbSx9X8QP4NDaP1hj4VKMjqA5s",
  "amount": 0.01,
  "tokensTraded": 1000000,
  "price": 0.00001,
  "marketCap": 1250000,
  "timestamp": 1697234567890,
  "side": "buy",
  "slippage": 2.3,
  "priorityFee": 0.0001
}
```

### New Token Event

Emitted when a new token is created.

```json
{
  "type": "newToken",
  "mint": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
  "symbol": "NEWCOIN",
  "name": "New Coin",
  "creator": "7BgBvyjrZX8YTqjkKrfbSx9X8QP4NDaP1hj4VKMjqA5s",
  "initialLiquidity": 5.0,
  "marketCap": 50000,
  "timestamp": 1697234567890,
  "metadata": {
    "description": "A revolutionary new token",
    "image": "https://...",
    "website": "https://...",
    "twitter": "@newcoin"
  }
}
```

### Price Update Event

Emitted when token price changes significantly.

```json
{
  "type": "priceUpdate",
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "price": 0.00001,
  "priceChange": 5.2,
  "priceChange24h": -2.1,
  "marketCap": 1250000,
  "volume24h": 50000,
  "liquidityUsd": 125000,
  "timestamp": 1697234567890
}
```

### Error Event

```json
{
  "type": "error",
  "code": "SUBSCRIPTION_FAILED",
  "message": "Invalid subscription key",
  "timestamp": 1697234567890
}
```

## Advanced Usage

### Reconnection Logic

```javascript
class TherosWebSocket {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.ws = null;
    this.reconnectDelay = 1000;
    this.maxReconnectDelay = 30000;
    this.subscriptions = new Set();
  }

  connect() {
    this.ws = new WebSocket('wss://theros.pro/api/data');

    this.ws.onopen = () => {
      console.log('Connected');
      this.reconnectDelay = 1000;

      // Authenticate
      this.send({
        method: 'authenticate',
        apiKey: this.apiKey
      });

      // Resubscribe to previous subscriptions
      if (this.subscriptions.size > 0) {
        this.send({
          method: 'subscribe',
          keys: Array.from(this.subscriptions)
        });
      }
    };

    this.ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      this.handleMessage(data);
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };

    this.ws.onclose = () => {
      console.log('Connection closed, reconnecting...');
      setTimeout(() => {
        this.reconnectDelay = Math.min(
          this.reconnectDelay * 2,
          this.maxReconnectDelay
        );
        this.connect();
      }, this.reconnectDelay);
    };
  }

  subscribe(keys) {
    keys.forEach(key => this.subscriptions.add(key));

    if (this.ws?.readyState === WebSocket.OPEN) {
      this.send({
        method: 'subscribe',
        keys
      });
    }
  }

  unsubscribe(keys) {
    keys.forEach(key => this.subscriptions.delete(key));

    if (this.ws?.readyState === WebSocket.OPEN) {
      this.send({
        method: 'unsubscribe',
        keys
      });
    }
  }

  send(data) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    }
  }

  handleMessage(data) {
    switch (data.type) {
      case 'trade':
        this.onTrade(data);
        break;
      case 'newToken':
        this.onNewToken(data);
        break;
      case 'priceUpdate':
        this.onPriceUpdate(data);
        break;
      case 'error':
        this.onError(data);
        break;
    }
  }

  onTrade(data) {
    // Override this method
    console.log('Trade:', data);
  }

  onNewToken(data) {
    // Override this method
    console.log('New token:', data);
  }

  onPriceUpdate(data) {
    // Override this method
    console.log('Price update:', data);
  }

  onError(data) {
    // Override this method
    console.error('Error:', data);
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }
}

// Usage
const ws = new TherosWebSocket('YOUR_API_KEY');
ws.connect();
ws.subscribe(['trades', 'newTokens']);

ws.onTrade = (data) => {
  console.log('Trade detected:', data);
};
```

### React Hook Example

```typescript
import { useEffect, useRef, useState } from 'react';

interface Trade {
  type: 'trade';
  mint: string;
  signature: string;
  trader: string;
  amount: number;
  tokensTraded: number;
  price: number;
  marketCap: number;
  timestamp: number;
  side: 'buy' | 'sell';
}

export function useTherosWebSocket(apiKey: string) {
  const ws = useRef<WebSocket | null>(null);
  const [trades, setTrades] = useState<Trade[]>([]);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    ws.current = new WebSocket('wss://theros.pro/api/data');

    ws.current.onopen = () => {
      setConnected(true);

      ws.current?.send(JSON.stringify({
        method: 'authenticate',
        apiKey
      }));

      ws.current?.send(JSON.stringify({
        method: 'subscribe',
        keys: ['trades']
      }));
    };

    ws.current.onmessage = (event) => {
      const data = JSON.parse(event.data);

      if (data.type === 'trade') {
        setTrades(prev => [data, ...prev].slice(0, 100));
      }
    };

    ws.current.onclose = () => {
      setConnected(false);
    };

    return () => {
      ws.current?.close();
    };
  }, [apiKey]);

  const subscribe = (keys: string[]) => {
    if (ws.current?.readyState === WebSocket.OPEN) {
      ws.current.send(JSON.stringify({
        method: 'subscribe',
        keys
      }));
    }
  };

  return { trades, connected, subscribe };
}
```

## Best Practices

1. **Implement Reconnection**: Handle connection drops gracefully
2. **Authenticate Early**: Send authentication immediately after connecting
3. **Manage Subscriptions**: Track subscriptions for reconnection
4. **Handle Errors**: Monitor error events and log them
5. **Rate Limiting**: Respect message rate limits
6. **Heartbeat**: Implement ping/pong for connection health
7. **Clean Disconnection**: Close connections properly when done

## Heartbeat/Ping-Pong

Keep the connection alive with periodic pings:

```javascript
let pingInterval;

ws.onopen = () => {
  // Send ping every 30 seconds
  pingInterval = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ method: 'ping' }));
    }
  }, 30000);
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  if (data.type === 'pong') {
    console.log('Pong received');
  }
};

ws.onclose = () => {
  clearInterval(pingInterval);
};
```

## Error Codes

| Code                    | Description                     |
| ----------------------- | ------------------------------- |
| `AUTHENTICATION_FAILED` | Invalid API key                 |
| `SUBSCRIPTION_FAILED`   | Invalid subscription key        |
| `RATE_LIMIT_EXCEEDED`   | Too many messages               |
| `CONNECTION_LIMIT`      | Too many concurrent connections |

## Next Steps

* View [Cloud API](https://docs.theros.pro/api-reference/lightning-api) for trading endpoints
* Check [Examples](https://docs.theros.pro/examples/examples) for complete implementations
* Learn about [Error Handling](https://docs.theros.pro/error-handling)


---

# 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.theros.pro/api-reference/websocket-api.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.
