Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.alterscope.org/llms.txt

Use this file to discover all available pages before exploring further.

You run a model that takes Alterscope factors as inputs. Polling the REST endpoint every minute wastes quota and lags reality. The WebSocket factor stream pushes a row every time a factor changes for the opportunities you subscribe to.

What you build

A long-lived WebSocket consumer that keeps your in-memory factor cache fresh.

1. Open the connection

import asyncio
import websockets
import json
import os

async def consume():
    # Subscription is set via query params on connect: opportunities to watch,
    # categories to filter by, an optional alert_threshold, and details=true.
    url = (
        "wss://api.alterscope.org/v2/ws/factors"
        "?opportunities=hyperliquid-btc-basis,aave-usdc-lending"
        "&categories=liquidity,oracle"
        "&details=true"
    )
    headers = {"Authorization": f"Bearer {os.environ['ALTERSCOPE_API_KEY']}"}
    async with websockets.connect(url, additional_headers=headers) as ws:
        async for raw in ws:
            event = json.loads(raw)
            apply_factor_update(event)

asyncio.run(consume())

2. Sample message

{
  "type": "factor.changed",
  "opportunity_id": "hyperliquid-btc-basis",
  "factor": "dynamic_stability_ratio",
  "previous": 0.74,
  "current": 0.61,
  "as_of_block": 22341488,
  "as_of": "2026-04-27T08:34:02Z"
}

3. Reconnect logic

The server pings every 30 seconds. If you miss two pings, reconnect with exponential backoff (start at 1s, cap at 30s). Re-open the connection with the same query params on each reconnect — the subscription lives in the URL. The server does not replay messages on reconnect; if you need gap-fill, run a single REST query for the affected opportunities right after reconnect.

4. Tier requirements

WebSocket streaming requires the Analyst tier or higher. The Free tier has no live stream.

5. Troubleshooting

  • 403 on connect: verify the key has read:yield:detail scope and your org is on the Analyst tier or higher.
  • No messages: the stream is event-driven. Quiet markets produce quiet streams. Narrow or widen your categories filter (liquidity, oracle, governance, economic) if you expected traffic and saw none.