> For the complete documentation index, see [llms.txt](https://docs.hyperlink.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hyperlink.xyz/api/websocket.md).

# WebSocket API

HyperLink's WebSocket API delivers real-time order, fill, and account updates and accepts signed trading actions over one persistent connection. It mirrors Hyperliquid's WebSocket protocol, so existing Hyperliquid tooling works against the HyperLink base URL. Only **private user-state** channels are streamed; there are no public market-data feeds.

Use WebSocket for live updates or low-latency order entry; use [Exchange Methods](/api/exchange-methods.md) (`POST /exchange`) for one-off requests.

## Connect

Open an HTTP upgrade to `/ws` at `wss://api.hyperlink.xyz/ws`. All messages are JSON text frames; the maximum message size is 1 MiB.

```bash
websocat wss://api.hyperlink.xyz/ws
```

Keep the connection alive with a ping; the server replies on the `pong` channel:

```json
{ "method": "ping" }
```

## Send signed actions: the `post` channel

The `post` channel runs the same signed payload as `POST /exchange`. Wrap the full `/exchange` envelope as `request.payload`. Only `type: "action"` is supported.

| Field             | Required | Notes                                                                                                     |
| ----------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `method`          | Yes      | Must be `"post"`.                                                                                         |
| `id`              | Yes      | Client-chosen `u64`, echoed back to correlate the response.                                               |
| `request.type`    | Yes      | Must be `"action"`.                                                                                       |
| `request.payload` | Yes      | The full `/exchange` envelope (`action`, `signature`, `nonce`, optional `expiresAfter` / `vaultAddress`). |

**Send** a GTC limit buy of `0.1` of asset index `0`:

```json
{
  "method": "post",
  "id": 1,
  "request": {
    "type": "action",
    "payload": {
      "action": {
        "type": "order",
        "orders": [
          { "a": 0, "b": true, "p": "50000", "s": "0.1", "r": false, "t": { "limit": { "tif": "Gtc" } }, "c": "0x1234567890abcdef1234567890abcdef" }
        ],
        "grouping": "na"
      },
      "signature": { "r": "0x...", "s": "0x...", "v": 27 },
      "nonce": 1712140800000
    }
  }
}
```

**Receive** on the `post` channel with the matching `id`; the inner `payload` mirrors the HTTP `/exchange` response:

```json
{
  "channel": "post",
  "data": {
    "id": 1,
    "response": {
      "type": "action",
      "payload": { "status": "ok", "response": { "type": "order", "data": { "statuses": [ { "resting": { "oid": 77738308 } } ] } } }
    }
  }
}
```

On a rejected request, `response.type` is `"error"`. Read queries (for example `openOrders`) also work over `post`.

## Subscriptions

Subscribe to stream updates for one account. Each subscribe message is signed with the **Agent** EIP-712 domain, the same signing used for queries (see [Authentication & Keys](/api/api-keys.md)); an SDK builds this for you.

| Field               | Required    | Notes                                                  |
| ------------------- | ----------- | ------------------------------------------------------ |
| `method`            | Yes         | `"subscribe"` or `"unsubscribe"`.                      |
| `subscription.type` | Yes         | One of the types below.                                |
| `subscription.user` | Yes         | Master account address to stream.                      |
| `subscription.coin` | Conditional | Required for `activeAssetData`; ignored otherwise.     |
| `subscription.dex`  | No          | For `openOrders` only; omit or set `"ALL_DEXS"`.       |
| `signature`         | Yes         | Agent-domain signature over the `subscription` object. |
| `nonce`             | Yes         | Unix time in milliseconds, single-use per signer.      |

**Send:**

```json
{
  "method": "subscribe",
  "subscription": { "type": "orderUpdates", "user": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1" },
  "signature": { "r": "0x...", "s": "0x...", "v": 27 },
  "nonce": 1712140800000
}
```

The server acknowledges on `subscriptionResponse`, then pushes updates on a channel named after the subscription type:

```json
{
  "channel": "orderUpdates",
  "data": [
    { "order": { "coin": "ETH", "side": "B", "limitPx": "50000", "sz": "0.1", "oid": 77738308, "timestamp": 1712140800123 }, "status": "open", "statusTimestamp": 1712140800123 }
  ]
}
```

### Subscription types

| Type                          | Streams                                                   |
| ----------------------------- | --------------------------------------------------------- |
| `orderUpdates`                | Order status changes (open, filled, canceled, rejected).  |
| `openOrders`                  | Current open orders across all DEXs.                      |
| `userFills`                   | Real-time fills.                                          |
| `spotState`                   | Spot token balances.                                      |
| `allDexsClearinghouseState`   | Perp positions and margin summary across all DEXs.        |
| `activeAssetData`             | Per-asset leverage and margin context. Requires a `coin`. |
| `userHistoricalOrders`        | Historical order status changes.                          |
| `userFundings`                | Funding payments.                                         |
| `userNonFundingLedgerUpdates` | Deposits, withdrawals, transfers.                         |

To stop, send the same `subscription` object with `method: "unsubscribe"` (no signature or nonce needed).

## Errors

Subscription and frame-level errors return on the `error` channel; errors tied to a `post` request return on the `post` channel with the request's `id` and `response.type: "error"`.

```json
{ "channel": "error", "data": { "message": "Invalid signature" } }
```

Common errors: `Invalid signature`, `Invalid nonce: <reason>`, `Unknown subscription type: <type>`, `Invalid user address`, `activeAssetData subscription requires non-empty coin`, `No matching subscription found`, and `Too many pending requests`. Malformed frames with no `id` are dropped silently.

## Rate limits

The connection enforces per-IP limits on connections, subscriptions, message rate, and in-flight `post` requests. Exceeding the message rate or connection cap closes the connection; exceeding the in-flight `post` cap returns `"Too many pending requests"`.

## Next steps

* [Exchange Methods](/api/exchange-methods.md): the `/exchange` envelope shared by the `post` channel.
* [Authentication & Keys](/api/api-keys.md): EIP-712 domains for actions and subscriptions.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.hyperlink.xyz/api/websocket.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
