> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sx.bet/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Different operations on SX Bet require different levels of authentication. Here's what you need and why.

## Authentication overview

Not everything requires authentication. SX Bet has three tiers:

| Operation                                              | Auth required         |
| ------------------------------------------------------ | --------------------- |
| Fetch markets, odds, trades, orders                    | None                  |
| Subscribe to WebSocket channels / register a heartbeat | API key               |
| Post, fill, or cancel orders                           | Private key signature |

<Tabs>
  <Tab title="No Auth — Reading data">
    All REST API endpoints are public. You can fetch markets, orderbooks, trades, fixtures, and more without any credentials. A base rate limit applies to all requests.

    ```bash theme={null}
    # No API key required
    curl https://api.sx.bet/markets/active
    ```
  </Tab>

  <Tab title="API Key — WebSocket & Heartbeat">
    To subscribe to real-time WebSocket channels (live odds updates, order book changes, trade events) or to register and cancel a heartbeat, you need an API key.

    You can generate an API key from your account settings on [sx.bet](https://sx.bet).

    SX Bet uses [Centrifugo](https://centrifugal.dev/) for WebSocket connections. Pass your API key to the `/user/realtime-token/api-key` endpoint to get a connection token, then supply it via the `getToken` callback:

    <CodeGroup>
      ```javascript JavaScript theme={null}
      import { Centrifuge } from "centrifuge";

      const RELAYER_URL = "https://api.sx.bet"; // Mainnet — use https://api.toronto.sx.bet for testnet
      const WS_URL = "wss://realtime.sx.bet/connection/websocket"; // Mainnet — use wss://realtime.toronto.sx.bet/connection/websocket for testnet

      async function fetchToken() {
        const res = await fetch(`${RELAYER_URL}/user/realtime-token/api-key`, {
          headers: { "x-api-key": process.env.SX_API_KEY },
        });
        if (!res.ok) throw new Error(`Token endpoint returned ${res.status}`);
        const { token } = await res.json();
        return token;
      }

      const client = new Centrifuge(WS_URL, {
        getToken: fetchToken,
      });

      client.connect();
      ```

      ```python Python theme={null}
      import asyncio
      import os
      import requests
      from centrifuge import Client

      RELAYER_URL = "https://api.sx.bet"  # Mainnet — use https://api.toronto.sx.bet for testnet
      WS_URL = "wss://realtime.sx.bet/connection/websocket"  # Mainnet — use wss://realtime.toronto.sx.bet/connection/websocket for testnet

      def fetch_token():
          res = requests.get(
              f"{RELAYER_URL}/user/realtime-token/api-key",
              headers={"x-api-key": os.environ["SX_API_KEY"]},
          )
          if not res.ok:
              raise Exception(f"Token endpoint returned {res.status_code}")
          return res.json()["token"]

      async def main():
          client = Client(WS_URL, get_token=fetch_token)
          await client.connect()
          await asyncio.Future()  # keep running

      asyncio.run(main())
      ```
    </CodeGroup>

    The `getToken` function is called automatically on initial connect and whenever the token needs to be refreshed — no manual token management is needed.

    See the [WebSocket Channels](/api-reference/centrifugo-overview) overview and [Real-time Data](/developers/real-time) for full channel documentation.
  </Tab>

  <Tab title="Private Key — Orders">
    Any action that moves funds or modifies your orders requires a **cryptographic signature** from your wallet's private key — proof that you — and only you — authorized that specific action. This includes:

    * **Filling orders** — taking a position on a market
    * **Posting orders** — placing a maker order on the book
    * **Cancelling orders** — removing your open orders

    <Warning>
      Never expose your private key. Store it in a `.env` file, never commit it to version control, and never share it. Anyone with your private key has full control of your wallet.
    </Warning>

    For implementation details, see [Filling Orders](/developers/filling-orders) and [Posting Orders](/developers/posting-orders).
  </Tab>
</Tabs>

<CardGroup cols={2}>
  <Card title="Filling Orders" icon="hand-pointer" href="/developers/filling-orders">
    Sign and submit taker fills against open maker orders.
  </Card>

  <Card title="Real-time Data" icon="wave-pulse" href="/developers/real-time">
    Subscribe to live order book and trade updates via WebSocket.
  </Card>
</CardGroup>
