# WebSocket API

The ForePaaS API provides a WebSocket interface for receiving real-time data updates. This is the recommended way to keep your application in sync with the latest market data without having to poll the REST API.

**WebSocket URL:** `wss://apidev.forepass.org`

{% hint style="info" %}
**Authentication:** WebSocket connections do not require authentication headers. You can connect and subscribe to public market streams without an API key.
{% endhint %}

> **Real-Time Benefits:** WebSockets eliminate polling overhead and provide instant updates, reducing latency from seconds to milliseconds for critical market data.

## Connection Examples

{% tabs %}
{% tab title="Node.js" %}

```javascript
const WebSocket = require('ws');

class ForegateWebSocket {
  constructor(baseUrl = 'wss://apidev.forepass.org') {
    this.baseUrl = baseUrl;
    this.connections = new Map();
  }

  connect(stream, marketId) {
    const url = `${this.baseUrl}/socket/${stream}?marketId=${marketId}`;
    const key = `${stream}-${marketId}`;
    
    return new Promise((resolve, reject) => {
      const ws = new WebSocket(url);
      this.connections.set(key, ws);

      ws.on('open', () => {
        console.log(`WebSocket connected to ${stream} for market ${marketId}`);
        resolve(ws);
      });

      ws.on('message', (data) => {
        const message = JSON.parse(data);
        console.log('Market update:', message);
      });

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

      ws.on('close', () => {
        console.log('WebSocket disconnected');
        this.connections.delete(key);
        // Implement reconnection logic here
        setTimeout(() => this.connect(stream, marketId), 5000);
      });
    });
  }

  disconnect(stream, marketId) {
    const key = `${stream}-${marketId}`;
    const ws = this.connections.get(key);
    if (ws) {
      ws.close();
      this.connections.delete(key);
    }
  }

  disconnectAll() {
    this.connections.forEach(ws => ws.close());
    this.connections.clear();
  }
}

// Usage
const ws = new ForegateWebSocket();

// Connect to market outcome stream for market 1744
const connection = await ws.connect('market-outcome', 1744);

// The WebSocket will automatically send updates via the 'message' event
// You can add custom message handlers as needed
```

{% endtab %}

{% tab title="Python" %}

```python
import asyncio
import json
import websockets
from typing import Dict, Callable, Any

class ForegateWebSocket:
    def __init__(self, base_url: str = 'wss://apidev.forepass.org'):
        self.base_url = base_url
        self.connections: Dict[str, Any] = {}
        self.running = False

    async def connect(self, stream: str, market_id: int):
        """Connect to WebSocket server for a specific stream and market"""
        url = f"{self.base_url}/socket/{stream}?marketId={market_id}"
        key = f"{stream}-{market_id}"
        
        try:
            ws = await websockets.connect(url)
            self.connections[key] = ws
            self.running = True
            print(f'WebSocket connected to {stream} for market {market_id}')
            
            # Start listening for messages
            asyncio.create_task(self._listen(ws, key, stream, market_id))
            
            return ws
            
        except Exception as e:
            print(f'WebSocket connection error: {e}')
            raise

    async def _listen(self, ws, key: str, stream: str, market_id: int):
        """Listen for incoming messages"""
        try:
            async for message in ws:
                data = json.loads(message)
                print(f'Market update for {market_id}:', data)
        except websockets.exceptions.ConnectionClosed:
            print(f'WebSocket disconnected: {stream}')
            del self.connections[key]
            if self.running:
                # Reconnect
                await asyncio.sleep(5)
                await self.connect(stream, market_id)

    async def disconnect(self, stream: str, market_id: int):
        """Disconnect from a specific stream"""
        key = f"{stream}-{market_id}"
        if key in self.connections:
            await self.connections[key].close()
            del self.connections[key]

    async def disconnect_all(self):
        """Disconnect all connections"""
        self.running = False
        for ws in self.connections.values():
            await ws.close()
        self.connections.clear()

# Usage
async def main():
    ws = ForegateWebSocket()
    
    # Connect to market outcome stream for market 1744
    await ws.connect('market-outcome', 1744)

    # Keep connection alive
    try:
        await asyncio.Future()  # Run forever
    except KeyboardInterrupt:
        await ws.disconnect_all()

# Run
asyncio.run(main())
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
**Best Practice:** Implement automatic reconnection with exponential backoff to handle temporary network issues gracefully.
{% endhint %}

## Connection URLs

WebSocket connections use query parameters to specify the market:

| Stream               | WebSocket URL Format                                                  |
| -------------------- | --------------------------------------------------------------------- |
| Market Outcome       | `wss://apidev.forepass.org/socket/market-outcome?marketId={marketId}` |
| Market Price History | `wss://apidev.forepass.org/socket/market-chance?marketId={marketId}`  |

> **Note:** Unlike REST APIs, WebSocket connections use query parameters in the URL itself, not through JSON messages.

***

### Market Outcome Stream

This stream provides real-time updates on the trading window information for a specific market, including the latest prices and volumes.

**WebSocket URL:** `wss://apidev.forepass.org/socket/market-outcome?marketId={marketId}`

**Connection Example:**

```javascript
const ws = new WebSocket('wss://apidev.forepass.org/socket/market-outcome?marketId=1745');

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

**Corresponding HTTP Endpoint:** `GET /api/market/openapi/{marketId}/outcome`

**Update Message Format:**

The WebSocket will automatically send updates with the same structure as the HTTP endpoint response.

***

### Market Price History Stream

This stream provides real-time updates on the historical price curve for a specific market.

**WebSocket URL:** `wss://apidev.forepass.org/socket/market-chance?marketId={marketId}`

**Connection Example:**

```javascript
const ws = new WebSocket('wss://apidev.forepass.org/socket/market-chance?marketId=1745');

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

**Update Message Format:**

The WebSocket sends price history data with timestamps and option chances for each option in the market.


---

# 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.forepaas.org/advanced/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.
