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

# allFills

{% hint style="info" %}
💧New endpoint - this endpoint is not a part of original Hyperliquid API and is added by us for builder convenience.
{% endhint %}

Per-coin `allFills` is included in every tier (5/25/100 coins for starter/growth/scale). Streaming **all** coins with no `coin`/`coins` filter is an add-on and requires the `ws:allFills` permission.

### Subscribe

```
{
    "type": "subscribe",
    "subscription": {
        "type": "allFills",
        "dex": "dex_name",                   // optional, filter by DEX (default: all)
        "coin": "xyz:SP500",                 // optional, single-coin filter (legacy)
        "coins": ["xyz:SP500", "xyz:NDX"],   // optional, multi-coin filter
        "outcomeMarkets": "exclude",         // optional, "exclude" or "only"
        "aggregateByTime": true              // optional
    }
}
```

### Filters

| Parameter         | Type      | Description                                                                                                                                                               |
| ----------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dex`             | string    | Filter by DEX. Use `"main"` for Hyperliquid perps, or the dex name (e.g. `"vntls"`) for dex-specific fills. Omit to receive fills from all DEXes.                         |
| `coin`            | string    | Single-coin filter (case-sensitive). Use the full coin string including any prefix, e.g. `"BTC"`, `"ETH"`, `"xyz:SP500"`, `"#90"`, `"@107"` / `"PURR/USDC"` (spot).       |
| `coins`           | string\[] | Multi-coin filter (case-sensitive, up to the tier's `max_coins`: 5/25/100). Same coin format as `coin`.                                                                   |
| `outcomeMarkets`  | string    | Filter outcome/prediction market fills (coins starting with `#`). Set to `"exclude"` to drop them, or `"only"` to receive only outcome market fills. Omit to include all. |
| `aggregateByTime` | boolean   | When `true`, fills with the same timestamp are aggregated into a single fill.                                                                                             |

`coin` and `coins` may be used together — their union is the effective coin set. Omitting both (no coin filter) makes this the all-coins firehose and requires the `ws:allFills` add-on permission.

{% hint style="warning" %}
**One allFills subscription per connection.** All `allFills` messages share a single `allFills` channel with no per-subscription identity, so the client cannot tell two allFills streams apart. A connection may hold at most one allFills subscription (per-coin **or** firehose). To watch several coins, list them all in one subscription's `coins` array rather than opening multiple subscriptions. A second, distinct allFills subscribe on the same connection is rejected with an error; unsubscribe first to switch between a per-coin filter and the firehose. Re-sending the identical subscription is a no-op. Separate connections each get their own allFills subscription.
{% endhint %}

{% hint style="warning" %}
Outcome markets are currently only available on testnet. The `outcomeMarkets` filter will have no effect on mainnet until outcome markets launch there.
{% endhint %}

All filters are optional and can be combined. For example, to stream only main-dex fills excluding outcome markets:

```json
{
    "type": "subscribe",
    "subscription": {
        "type": "allFills",
        "dex": "main",
        "outcomeMarkets": "exclude"
    }
}
```

### Unsubscribe

```
{
    "type": "unsubscribe",
    "subscription": {
        "type": "allFills"
    }
}
```

### Fill data format

Each fill contains an address and fill details. Fills are batched per block.

{% hint style="info" %}
**Reconnection Note:** When reconnecting with a session, replay and live events may overlap. Deduplicate using `(time, txIndex)` - skip fills where this tuple is at or before your last processed fill. See [Session Management](/readme/websocket/session-management-and-reconnection.md#deduplication) for details.
{% endhint %}

```json
{
  "type": "allFills",
  "seq": 1,
  "cursor": "500:1704067200000:3",
  "fills": [
    [
      "0x742d35cc6634c0532925a3b844bc9e7595f7f2e2",
      {
        "coin": "ETH",
        "px": "2150.50",              // price
        "sz": "1.5",                  // size
        "side": "B",                  // B=buy, A=sell
        "time": 1704067200000,        // timestamp (ms)
        "startPosition": "1.5",       // position before fill
        "dir": "Open Long",           // direction
        "closedPnl": "125.50",        // realized PnL
        "hash": "0xabc...def",        // fill hash
        "oid": 12345678,              // order ID
        "crossed": false,             // was crossed
        "fee": "2.50",                // fee amount
        "tid": 87654321,              // trade ID
        "cloid": "client-123",        // client order ID (optional)
        "builderFee": "0.10",         // builder fee (optional)
        "deployerFee": "0.05",        // deployer fee (optional, HIP-3 only)
        "priorityGas": null,          // priority gas fee in HYPE (optional)
        "feeToken": "USDC",           // fee token
        "builder": "0x..",            // builder
        "twapId": 913412,             // null if not a twap
        "txIndex": 3                  // transaction index within block
      }
    ]
  ]
}
```

### Examples

{% tabs %}
{% tab title="Javascript" %}

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

const ws = new WebSocket(`wss://api.hydromancer.xyz/ws?token=${process.env.HYDROMANCER_API_KEY}`);

ws.on('message', (data) => {
    const msg = JSON.parse(data);

    if (msg.type === 'connected') {
        // Subscribe to fills
        ws.send(JSON.stringify({
            type: 'subscribe',
            subscription: {
                type: 'allFills'
            }
        }));
    } else if (msg.type === 'ping') {
        ws.send(JSON.stringify({ type: 'pong' }));
    } else if (msg.type === 'allFills') {
        console.log(`Received ${msg.fills.length} fills`);
    }
});
```

{% endtab %}

{% tab title="Python" %}

```python
import websocket
import json
import os

def on_message(ws, message):
    msg = json.loads(message)

    if msg['type'] == 'connected':
        ws.send(json.dumps({
            "type": "subscribe",
            "subscription": {
                "type": "allFills"
            }
        }))
    elif msg['type'] == 'ping':
        print("Received ping, sending pong")
        ws.send(json.dumps({'type': 'pong'}))
    elif msg['type'] == 'allFills':
        print(f"Received {len(msg['fills'])} fills")
    elif msg['type'] == 'subscriptionUpdate':
        print(f"Subscription update: {msg}")
    elif msg['type'] == 'error':
        print(f"Error: {msg}")
    else:
        print(f"Unknown message type: {msg}")

ws = websocket.WebSocketApp(
    f"wss://api.hydromancer.xyz/ws?token={os.environ.get('HYDROMANCER_API_KEY')}",
    on_message=on_message
)
ws.run_forever()
```

{% endtab %}
{% endtabs %}

#### Error messages:

```
{
    "type": "error",
    "message": "Invalid API key"
}
```

#### Common errors

1. ```
   Connection timeout - Respond to ping messages
   ```
2. ```
   Subscription allFillsAll requires permission: ws:allFills
   ```

   (Only the no-filter firehose form requires the add-on; per-coin allFills is included in every tier.)
3. ```
   Only one allFills subscription is allowed per connection; unsubscribe the existing one first, or select multiple coins via a single subscription's `coins` filter
   ```

   (Sent when a connection that already has an allFills subscription tries to add a second, distinct one.)
4. ```
   Invalid API key
   ```
