# Femtos | Wallet PnL stream | API reference

> A wallet's positions and PnL on HyperEVM (GET /v1/wallet/{address}/pnl), pushed on subscribe, then the positions each block changes. WebSocket channel pnl on Elysium and HyperEVM: parameters, response fields and a live call per layer.

- Base URL: `https://api.femtos.xyz/v1` (REST) · `wss://api.femtos.xyz/v1/ws` (WebSocket) · MCP: `https://api.femtos.xyz/mcp`
- Auth: `Authorization: Bearer $FEMTOS_KEY`. Free key: https://dashboard.femtos.xyz/signup (browser), or with
  no browser: `GET https://femtos.xyz/accounts/agent/challenge`, solve its proof of work, then `POST https://femtos.xyz/accounts/agent/signup`
  (https://femtos.xyz/agents.md#agent-onboarding)
- Decimals are exact strings, times Unix milliseconds, addresses lowercase `0x`
- Whole API in one file: https://femtos.xyz/agents.md · OpenAPI: https://api.femtos.xyz/v1/openapi.json · Index: https://femtos.xyz/llms.txt
- Page with live calls: https://femtos.xyz/reference/ws/pnl

WebSocket: get a ticket (`POST https://api.femtos.xyz/v1/ws-ticket` with your key), connect to `wss://api.femtos.xyz/v1/ws?ticket=$TICKET`, send the frame below; the first message has `"snapshot": true`. Details: https://femtos.xyz/agents.md#websocket

## Wallet PnL stream — WS `pnl`

- Elysium: A wallet's positions and PnL on Elysium (GET /v1/wallet/{address}/pnl), pushed on subscribe, then the positions each block changes.
- HyperEVM: A wallet's positions and PnL on HyperEVM (GET /v1/wallet/{address}/pnl), pushed on subscribe, then the positions each block changes.

Layers: Elysium, HyperEVM. Not on HyperCore: HyperCore trades on its order book: an account's positions and PnL move with its fills, pushed by the wallet channel (`hc.account`).
Page with live calls: https://femtos.xyz/reference/ws/pnl?layer=<elysium|hyperevm>

| Param | In | Example or values | Meaning |
|---|---|---|---|
| `address` | filter | `0x876f1301aaa8452ceb98201cd4407fa9510a8181` (Elysium); `0x5a69a60ca8a4d189855b33bd9f1bbe71095c1039` (HyperEVM) | The wallet: 0x, or a named wallet's handle |
| `layer` | filter | `elysium` (Elysium); `hyperevm` (HyperEVM) | hyperevm or elysium |
| `status` | filter | (optional) | all (default), open (held now) or closed: the positions sent |
| `limit` | filter | `20` | Positions of the snapshot, by USD held, default 100 (1..500) |
| `includeSpam` | filter | (optional) | true: spam tokens too, and in the PnL totals |

Elysium:

```json
{"op":"subscribe","channel":"pnl","filter":{"address":"0x876f1301aaa8452ceb98201cd4407fa9510a8181","layer":"elysium","limit":"20"}}
```

HyperEVM:

```json
{"op":"subscribe","channel":"pnl","filter":{"address":"0x5a69a60ca8a4d189855b33bd9f1bbe71095c1039","layer":"hyperevm","limit":"20"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | WalletPnl | the GET /v1/wallet/{address}/pnl?layer=<layer> answer (sort value): positions, cost basis, PnL, 1d / 7d / 30d / all totals, the block read |
| `data` | PnlUpdate | the positions of the wallet that a block the indexer commits changed (a swap credited to the wallet, a balance moved), whole rows to replace by `token` (any position the filter keeps, not only the snapshot's page), the tokens gone, and the totals. Never sent for a price move: each row carries heldWithCost and costOfHeldUsd, unrealized PnL = heldWithCost × price − costOfHeldUsd at the client's price (`<layer>.prices`): {layer, address, height, asOf, positions, removed, totals} |
| `data.positions[]` | object | The positions the block changed (a swap of the wallet, a balance moved), whole: replace each by `token`: {token, symbol, name, decimals, spam, spamReason, held, heldNative, heldWithCost, heldNoCost, priceUsd, valueUsd, …} |
| `data.removed` | string[] | Positions gone (a token received, never swapped, no longer held) |
| `data.totals` | object | Totals over every position of the wallet (not only the page): the last 24, 168, 720 UTC hours (1d, 7d, 30d) and all: {1d, 7d, 30d, all} |
| `billing` | medium | the snapshot a subscribe asks for counts as GET /v1/wallet/{address}/pnl (medium); every other frame by its bytes (1 credit per 48 KiB) |

## Related (Bridges & wallets)

- [Cross-layer wallet](https://femtos.xyz/reference/wallet.md) `GET /v1/wallet/{address}`: One address (or a named wallet's handle) on HyperCore, HyperEVM and Elysium, plus its latest events. (Elysium, HyperCore, HyperEVM)
- [Wallet stream](https://femtos.xyz/reference/ws/wallet.md) `WS wallet`: Every event of the three layers touching one address. (Elysium, HyperCore, HyperEVM)
- [Wallet list stream](https://femtos.xyz/reference/ws/wallets.md) `WS wallets`: Every event of the three layers touching any of up to 100 addresses, in one subscription, each event tagged with its address. (Elysium, HyperCore, HyperEVM)
- [HyperCore account](https://femtos.xyz/reference/hypercore-account.md) `GET /v1/hypercore/wallet/{address}`: One address's HyperCore account: perp value and margin, positions, spot balances. (HyperCore)
- [Wallet open orders](https://femtos.xyz/reference/wallet-orders.md) `GET /v1/hypercore/wallet/{address}/orders`: One wallet's open orders: resting limit orders and trigger orders, on the main dex and every HIP-3 dex. (HyperCore)
- [Wallet order history](https://femtos.xyz/reference/wallet-order-history.md) `GET /v1/hypercore/wallet/{address}/orders/history`: One wallet's orders that left the book, newest first: how (filled, canceled, rejected) and why, the size filled and its average price. (HyperCore)
- [Wallet fills](https://femtos.xyz/reference/wallet-fills.md) `GET /v1/hypercore/wallet/{address}/fills`: One wallet's HyperCore fills, newest first, with closed PnL, fees and the position before each. (HyperCore)
- [Wallet fills per bar](https://femtos.xyz/reference/wallet-fill-bars.md) `GET /v1/hypercore/wallet/{address}/fills/bars`: One wallet's fills on one market summed per bar: buys and sells with their average price, and the position after each bar. (HyperCore)
- [Wallet funding](https://femtos.xyz/reference/wallet-funding.md) `GET /v1/hypercore/wallet/{address}/funding`: One wallet's funding payments, newest first: paid or received per perp and hour, with the position and the rate. (HyperCore)
- [Swaps by wallet](https://femtos.xyz/reference/wallet-trades.md) `GET /v1/trades`: Every swap a wallet sent (or a pool’s, a token’s), newest first, filterable by token, side, size and time. (Elysium, HyperEVM)
- [Transfers by wallet](https://femtos.xyz/reference/wallet-transfers.md) `GET /v1/transfers`: ERC-20 transfers sent and received by a wallet, newest first, filterable by token, direction, size and time. (Elysium, HyperEVM)
- [Wallet PnL](https://femtos.xyz/reference/wallet-pnl.md) `GET /v1/wallet/{address}/pnl`: Any wallet on HyperEVM: per token balance, cost basis, realized and unrealized PnL, with 1d / 7d / 30d / all totals and win rate. (Elysium, HyperEVM)
- [Portfolio value history](https://femtos.xyz/reference/wallet-value.md) `GET /v1/wallet/{address}/value`: Any address on HyperEVM: its total USD value per 5 min (1d), hour (7d) or day (30d, all). (Elysium, HyperEVM)
- [Wallet PnL curve](https://femtos.xyz/reference/hypercore-wallet-pnl.md) `GET /v1/hypercore/wallet/{address}/pnl`: One HyperCore wallet's PnL per hour or day: realized, fees, funding, net and cumulative, and its account value. (HyperCore)
- [Was I sandwiched?](https://femtos.xyz/reference/wallet-mev.md) `GET /v1/wallet/{address}/mev`: Every sandwich of a wallet’s swaps on Elysium: the bot, its two transactions, what the wallet lost. Free, no key. (Elysium)
- [Ledger stream](https://femtos.xyz/reference/ws/ledger.md) `WS hc.ledger`: Deposits, withdrawals, transfers and other non-trade balance moves. (HyperCore)
- [Bridge movements](https://femtos.xyz/reference/bridge.md) `GET /v1/bridges`: Matched HyperCore ↔ HyperEVM transfers with 24 h stats. (Elysium, HyperCore, HyperEVM)
- [Bridge stream](https://femtos.xyz/reference/ws/bridge.md) `WS elysium.bridge | bridge.transfers`: Each HyperCore ↔ HyperEVM transfer, initiated then completed. (Elysium, HyperCore, HyperEVM)
- [Bridge movements stream](https://femtos.xyz/reference/ws/bridges.md) `WS bridges.recent`: The GET /v1/bridges answer (movements newest first, 24 h stats), pushed on subscribe, then when a movement of the route changes state. (Elysium, HyperCore, HyperEVM)
- [Bridge coverage](https://femtos.xyz/reference/bridge-coverage.md) `GET /v1/bridges/coverage`: Every HyperCore ↔ HyperEVM leg since our data starts, paired with its other leg: matched share per direction and token, why the others are not, latency. (HyperCore, HyperEVM)

Every page: https://femtos.xyz/reference.md
