# Femtos API — guide for agents

Femtos serves Hyperliquid data across its three layers: **HyperCore** (the exchange: order book, perps, liquidations,
positions), **HyperEVM** (the EVM chain: pools, swaps, tokens, LiquidLaunch) and **Elysium** (Kinetiq's Orbit L2 on
HyperEVM), over REST and WebSocket, plus a Hyperliquid-compatible `POST /info` and `/ws`.

Human docs with live calls: https://femtos.xyz · OpenAPI: https://api.femtos.xyz/v1/openapi.json · This file: https://femtos.xyz/agents.md (also https://femtos.xyz/llms-full.txt)

## Rules

- Base URL `https://api.femtos.xyz/v1`. Every call takes `Authorization: Bearer $FEMTOS_KEY` (or `X-API-KEY: $FEMTOS_KEY`). Get a key at https://femtos.xyz/accounts/, or
  with no browser through the API (section "Agent onboarding" below).
  `GET /v1/whoami` answers the key's name, tier, billing state (`ok`, `exhausted`, `capped`) and the limits in force
  (`{rps, burst, maxConns}`).
- Most routes take `layer=hypercore|hyperevm|elysium`. Check `GET /v1/status` for each layer's state and head.
- Decimals are exact strings, times are Unix milliseconds, addresses are lowercase `0x`.
- Errors: `401` missing or invalid key · `404 {error}` unknown token, market or launch · `429` over your key's rate
  (`Retry-After`, `X-RateLimit-Limit`, `-Burst`, `-Remaining`, `-Reset`) · `503 {error, unavailable}` the source cannot
  answer right now · `200` with an empty array when the source answers with no data.
- A layer that is syncing (`"state": "syncing"` in `/v1/status`) still answers with what is indexed
  and says so: objects carry `"syncing": true, "dataUntil": <ms>`; arrays carry the headers `X-Layer-State: syncing` and
  `X-Data-Until: <ms>`. Windows such as "24 h" end at the indexed head, not now.
- Elysium is served from its testnet until mainnet indexing starts; `/v1/status` gives the network.
- Each endpoint's field table below gives the type and unit of every field.
- Provenance: a row cites its chain event (`block`, `tx`, and `logIndex` on HyperEVM and Elysium); an aggregate
  (candles, holders, volume) cites the block it is cut at (`height`, with its time `asOf`). Check any value on-chain.
- Hyperliquid-compatible: `POST https://api.femtos.xyz/info` and `wss://api.femtos.xyz/ws` take the same requests and frames as
  `api.hyperliquid.xyz`; switch the host and add your key.

## MCP

A hosted MCP server (Model Context Protocol, Streamable HTTP, stateless) at `https://api.femtos.xyz/mcp`: agents query the three
layers with no code. Same key as REST, in `X-API-KEY: $FEMTOS_KEY` or `Authorization: Bearer $FEMTOS_KEY`.
`initialize` and `tools/list` need no key; a tool call without a key (or with an unknown one) answers a tool error
`{"error": "unauthorized", "signup": {agent, browser}, …}`: an agent can sign up by itself (section "Agent onboarding").
Each tool runs one REST call with your key and counts like it (rate limit and usage). Answers are JSON text with the call they ran (`request`), 50 rows by default, cut to fit an agent's context
(`truncated` lists what was left out). Setup and tools: https://femtos.xyz/mcp

Claude Code:

```bash
claude mcp add --transport http femtos "https://api.femtos.xyz/mcp" \
  --header "X-API-KEY: $FEMTOS_KEY"
```

Cursor:

```jsonc
// ~/.cursor/mcp.json (or .cursor/mcp.json in a project)
{
  "mcpServers": {
    "femtos": {
      "url": "https://api.femtos.xyz/mcp",
      "headers": {
        "X-API-KEY": "${env:FEMTOS_KEY}"
      }
    }
  }
}
```

OpenAI:

```jsonc
// Responses API: tools of the request
[
  {
    "type": "mcp",
    "server_label": "femtos",
    "server_url": "https://api.femtos.xyz/mcp",
    "headers": {
      "X-API-KEY": "$FEMTOS_KEY"
    },
    "require_approval": "never"
  }
]
```

JSON:

```jsonc
// any Streamable HTTP client (VS Code, Windsurf, Zed…)
{
  "url": "https://api.femtos.xyz/mcp",
  "headers": {
    "X-API-KEY": "$FEMTOS_KEY"
  }
}
```

| Tool | Layers | Answers | REST call | Counts as |
|---|---|---|---|---|
| `get_status` | all | Each layer: indexed head, lag, live or syncing | `GET /v1/status` | free |
| `list_markets` | all | Perps, spot, HIP-3, outcomes; DEX pools, most traded first | `GET /v1/markets` | rest |
| `get_candles` | all | OHLCV of a coin or pool; pools in USD and market cap too | `GET /v1/candles` | rest (heavy over 30 days) |
| `get_trades` | all | Latest fills of a coin, swaps of a pool | `GET /v1/trades` | rest |
| `search_coins` | all | Tokens by symbol, name or address, linked across layers | `GET /v1/coins` | rest |
| `get_coin` | all | One token: links, markets, largest holders | `GET /v1/coins/{layer}/{id}` | rest |
| `get_holders` | all | Largest holders and concentration | `GET /v1/holders` | rest |
| `list_launches` | Elysium · HyperEVM | Ascend and LiquidLaunch launches, newest first | `GET /v1/launches` | rest |
| `get_launch` | Elysium · HyperEVM | Launch story: dev wallet, early buyers, signals, fees, Ascend progress | `GET /v1/launches/{token}` | rest |
| `get_launch_timeline` | Elysium · HyperEVM | Replayable life: swaps, holders and market cap over time | `GET /v1/launches/{token}/timeline` | rest |
| `get_token_lifecycle` | cross-layer | One token from Elysium launch to HyperCore perp, each link exact or inferred | `GET /v1/tokens/{address}/lifecycle` | rest |
| `get_bridges` | cross-layer | HyperCore ↔ HyperEVM and HyperEVM ↔ Elysium movements, both legs matched | `GET /v1/bridges` | heavy |
| `get_wallet` | cross-layer | One address on the three layers: positions, balances, bridges, latest events | `GET /v1/wallet/{address}` | heavy |
| `get_token_volume` | HyperEVM · Elysium | Daily USD swap volume of a token | `GET /v1/volume` | rest |
| `get_erc20_transfers` | HyperEVM · Elysium | ERC-20 transfers of a token, newest first | `GET /v1/transfers` | rest |
| `get_book` | HyperCore | Live L2 order book of a market from our node, with order counts | `GET /v1/book` | rest |
| `get_liquidations` | HyperCore | Perp liquidations, newest first, by coin, account or size | `GET /v1/liquidations` | rest |
| `get_liquidation_stats` | HyperCore | Liquidations over 1 h to 30 d: totals, per coin, per bucket, largest | `GET /v1/liquidations/stats` | rest |
| `get_positions` | HyperCore | Open positions of a perp: leverage, PnL, liquidation price | `GET /v1/positions` | rest |
| `list_nft_collections` | HyperEVM · Elysium | Most active NFT collections over 1 h or 24 h | `GET /v1/nfts/collections` | rest |
| `get_nft_collection` | HyperEVM · Elysium | One collection: metadata, tokens seen, 24 h activity | `GET /v1/nfts/collections/{address}` | rest |
| `get_nft_tokens` | HyperEVM · Elysium | Tokens of a collection: owner, metadata URI | `GET /v1/nfts/tokens` | rest |
| `get_nfts_owned` | HyperEVM · Elysium | NFTs a wallet holds, per collection | `GET /v1/nfts/owned` | rest |
| `get_nft_transfers` | HyperEVM · Elysium | Transfers of a collection or one token, newest first | `GET /v1/nfts/transfers` | rest |
| `search_entities` | all | Named wallets: KOLs, traders, funds and their addresses | `GET /v1/entities` | rest |
| `kol_leaderboard` | all | Named wallets ranked by PnL, volume, swaps or holdings | `GET /v1/kols/leaderboard` | rest |
| `kol_activity` | all | Latest fills, swaps and transfers of named wallets | `GET /v1/kols/activity` | rest |

## WebSocket

Get a single-use ticket (valid 30 s), then connect to `wss://api.femtos.xyz/v1/ws?ticket=$TICKET`: the key never goes in the URL, where proxies log it.

```bash
TICKET=$(curl -s -X POST -H "Authorization: Bearer $FEMTOS_KEY" https://api.femtos.xyz/v1/ws-ticket | jq -r .ticket)   # {"ticket","ttlS","expiresAt"}
```

`?token=$FEMTOS_KEY` in the URL still works but is deprecated. The server closes a connection with code 4001 once its key
is revoked, rotated, frozen or expired. Then:

```json
{"op":"subscribe","channel":"<channel>","filter":{"<param>":"<value>"}}
{"op":"unsubscribe","channel":"<channel>","filter":{"<param>":"<value>"}}
{"op":"ping"}
```

Send a ping every 30 s. Each message is `{channel, filter, snapshot?, data, ts, latency_ms?}`: the first message of a
subscription has `"snapshot": true` (current state), the next ones are updates. `ts.source` is the event's chain time.

Limits per key: at most `maxConns` connections (429 at the upgrade past it), 64 subscriptions per connection. Messages
you send count against your key's `rps` / `burst` on each connection: past it a message is answered
`{"error":"rate limit exceeded","retryAfter":<s>}` and ignored, and 20 refused in a row close the connection with code
4029. A subscription no other client holds loads its snapshot: those count against your key's `rps` / `burst` across
all its connections, past it `{"error":"too many new subscriptions, retry later","retryAfter":<s>,channel,filter}`.

## Agent onboarding

An agent can get its own key and pay for its own credits, with no browser and no human:

1. `GET https://femtos.xyz/accounts/agent/challenge` → `{salt, difficulty, expires, algorithm}`. Anti-abuse proof of work, the
   same as the signup page's: find a nonce (1 to 32 characters `[0-9a-zA-Z]`) such that SHA-256 of the string
   `"<salt>:<nonce>"` starts with `difficulty` zero bits (19 today: about a second). A challenge is valid 10 min, once.
2. `POST https://femtos.xyz/accounts/agent/signup` `{"agent_name", "owner_email"?, "salt", "nonce"}` → `201` with the key
   and the `managementSecret` (`fms_…`; **both shown once: store them, apart**), the tier (`free`), its quotas
   (`rps`, `burst`, `wsConnections`, free monthly credits) and the next URLs (docs, OpenAPI, MCP at
   `https://api.femtos.xyz/mcp`, `next.management`). The management secret is not an API key: it is required to rotate the key,
   delete the account or unfreeze the key (step 7). Per IP: 5 signups a day, 10 attempts and 30 challenges a minute.
   `owner_email` is optional and stored; nothing is ever sent to it.
3. Call the API with `Authorization: Bearer $FEMTOS_KEY` (or `X-API-KEY`). Free tier from the first call: no payment needed to start.
4. `GET https://femtos.xyz/accounts/agent/me` (Bearer) → tier, quotas, billing state (`status` `ok` | `exhausted` | `capped`,
   balance, credits used this month, free credits left).
5. Once billing is active, a key past its free monthly credits with no prepaid balance gets `402` on heavy calls:
   `{"error": "payment_required", "checkoutUrl": "https://femtos.xyz/accounts/agent/checkout", "hint": "POST … with your key", …}`.
6. `POST https://femtos.xyz/accounts/agent/checkout` (Bearer) `{"amount_usd": 25}` (below the minimum top-up:
   `400` with the minimum) → `card.checkoutUrl` (Stripe Checkout, valid 24 h, for a human to pay) and / or
   `usdc`: the key's own deposit address, the same on HyperCore and HyperEVM, so the agent pays **itself** in USDC:
   - HyperCore: a signed `usdSend` (or `spotSend` of USDC) to `usdc.hypercore.address`. Hyperliquid takes 1 USDC
     from the first transfer to a new address.
   - HyperEVM (chain id 999): ERC-20 `transfer(usdc.hyperevm.address, usd × 10^6)` on `usdc.hyperevm.token` (Circle
     USDC, 6 decimals), credited after `usdc.hyperevm.confirmations` blocks.
   - 1 USDC = 1 USD of balance; transfers under `usdc.minUsd` are recorded, not credited. Progress:
     `GET https://femtos.xyz/accounts/billing/deposit` (Bearer).

   While billing is not active, checkout answers `409 {"error": "billing_inactive"}`: every call is free within the
   rate limits and there is nothing to pay. Only the configured payment methods are offered (`503
   payments_disabled` when none is). A frozen key gets `403 key_frozen` here.
7. Key management, with no human step: send the key (`Authorization: Bearer`) and, where noted, the management
   secret (`X-Management-Secret: <managementSecret>`):
   - `POST https://femtos.xyz/accounts/me/freeze`: **the key alone**. It stops working at once on every API and WebSocket
     (open sockets close with 4001). Use it the moment a key leaks.
   - `POST https://femtos.xyz/accounts/me/unfreeze` + secret → `{"frozen": false}`.
   - `POST https://femtos.xyz/accounts/rotate` + secret → `{"key"}`: a new key (shown once), the old one stops working at
     once; a frozen key is replaced by a live one. The secret stays the same.
   - `DELETE https://femtos.xyz/accounts/me` + secret → `204`.

   Without the secret these answer `401 management_secret_required`, with a wrong one `403
   management_secret_invalid`. Agent accounts created before the secret existed get `403
   management_secret_missing`: ask Femtos to issue one. (Accounts made on the signup page confirm the same actions
   through a link sent to their email.)

Errors: `{error, message}`: `pow_malformed` `pow_forged` `pow_insufficient` `invalid_agent_name` `invalid_email`
`disposable_email` `invalid_amount` (400), `unauthorized` `management_secret_required` (401), `partner_account`
`key_frozen` `management_secret_invalid` `management_secret_missing` (403), `billing_inactive`
`pow_reused` (409), `pow_expired` (410), `rate_limited` `daily_limit` (429).

### Pay with x402: buy credits, get a key

**Disabled until announced**: until then a request with no key answers `401` as above. Once on, an agent with
**no account and no key** buys a credit pack in USDC with [x402](https://x402.org) (v1 and v2) and gets a key in the
same answer. Calls are not paid one by one: each is far cheaper than an on-chain settlement. Packs start at $0.01;
the amounts are in the `402` itself, nothing here fixes them.

**Chains**: USDC on **Base** (`eip155:8453`), **Arbitrum One** (`eip155:42161`) and **HyperEVM** (`eip155:999`);
Elysium once its USDC is published. Plain wallets (EOA signatures) only; you pay no gas, Femtos settles. One wallet
address is one account on every chain: paying from it on Base, then on HyperEVM, credits the same account.

**Take the first entry.** The `402` lists one `accepts` entry per chain, the cheapest to settle first
(`extra.recommended: true` on it, `extra.settleCostUsd` on each); standard clients take the first entry they can
pay, which is the right choice. A chain where settling would cost too large a share of a pack is offered at a bigger
pack, or not at all. `GET https://api.femtos.xyz/v1/x402/networks` (no key) lists the chains, their USDC, the packs each takes and
the current ranking.

1. Call any REST route with no key → `402`. The payment requirements are in the `PAYMENT-REQUIRED` header (x402
   v2, base64 JSON, every chain) and in the body: `x402Networks` (every offer, same order), the x402 v1 `accepts`
   (only chains with an x402 v1 name: `base`), `freeKeyUrl` and `checkoutUrl` for the keyed paths. An entry:
   scheme `exact`, `network` (CAIP-2), `asset` (that chain's USDC, 6 decimals), `payTo`, `amount` (atomic
   units; v1 `maxAmountRequired`), `extra: {name, version}` (the token's EIP-712 domain: `USD Coin` / `2` on
   Base and Arbitrum, `USDC` / `2` on HyperEVM).
2. **A bigger pack**: the same URL with `?x402_pack=<USD>` (one of `packsUsd` in the body); the `402` then offers
   that pack. Your client's retry keeps the URL, so it pays that pack with no extra code.
3. Sign an EIP-3009 `TransferWithAuthorization` (EIP-712, domain `{name, version, chainId: <the entry's chain>,
   verifyingContract: <asset>}`) from your wallet to `payTo` for that amount, `validBefore` = now +
   `maxTimeoutSeconds`, a random 32-byte `nonce`. A signature made for another chain is refused.
4. Send the same request again with the payment: `PAYMENT-SIGNATURE: <base64 PaymentPayload>` (v2) or
   `X-PAYMENT` (v1). Femtos verifies it on that chain (signature, amount, window, your USDC balance, nonce unused),
   settles it and waits for the receipt, credits the amount to **the account of your wallet**, then serves the call.
   - The answer carries the key: `X-Femtos-Key`, and the settlement in `PAYMENT-RESPONSE` (v1:
     `X-PAYMENT-RESPONSE`; base64 `{success, transaction, network, payer}`, v2 with `extensions.femtos`: `account`,
     `key`, `balanceUsd`).
   - The wallet's first payment creates the account (tier free, prepaid balance) and also returns its management
     secret once, in `X-Management-Secret` (key management, step 7 above). **Store both.**
   - Lost the key? Pay again from the same wallet with no key: the same account is credited and its key **rotated**
     (the old one stops working, the balance stays). Paying proves you hold the wallet. At most 5 new keys per wallet
     an hour (past it the payment is still credited, the key kept).
   - A frozen account (step 7 above) is credited but gets no key: `403 account_frozen`; unfreeze it with the key and the
     management secret.
5. Use the key as any other (`Authorization: Bearer`), REST and WebSocket. A keyless WebSocket gets `401` with
   this hint: x402 is REST only, buy the key there first.

A key whose credits run out (billing active) gets on its heavy calls the same `402` with the packs: paid with that
key in the request, the credit goes to **that** account (no new key) and the call is served.

Never charged twice: the same payment header sent again returns the same outcome. `503 settlement_pending` /
`credit_pending` (with `transaction`) = paid, not finished: send the same request with the same header again a few
seconds later. Refused payments answer `402` with `reason` (`invalid_exact_evm_signature`, `insufficient_funds`,
`invalid_exact_evm_nonce_already_used`, `invalid_exact_evm_payload_authorization_valid_before`…), a malformed header
`400`. Unpaid requests without a key are rate limited per IP, payments per wallet (`429`).

With the official x402 client (`@x402/fetch`, `@x402/evm`, `viem`), it is one wrapped fetch. Its defaults pay only
the stablecoins of its own list (USDC on Base and Arbitrum: yes; on HyperEVM: add it in `allowedAssets`) and at most
$1 a payment (raise `maxAmountPerPayment` for a bigger pack):

```ts
import { wrapFetchWithPaymentFromConfig } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm';
import { privateKeyToAccount } from 'viem/accounts';

const wallet = privateKeyToAccount(process.env.WALLET_KEY as `0x${string}`); // holds USDC on Base, Arbitrum or HyperEVM
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: 'eip155:*', client: new ExactEvmScheme(wallet) }],
  // optional: HyperEVM USDC too, and packs above $1 (with ?x402_pack=<USD> on the URL)
  spendControls: {
    allowedAssets: [{ network: 'eip155:999', asset: '0xb88339CB7199b77E23DB6E890353E22632Ba630f' }],
    maxAmountPerPayment: '$5', // your own ceiling per payment (the SDK's default: $1)
  },
});
const res = await pay('https://api.femtos.xyz/v1/status'); // the entry pack; 'https://api.femtos.xyz/v1/status?x402_pack=5' for a bigger one
const key = res.headers.get('X-Femtos-Key'); // store it (and X-Management-Secret on the first payment)
```

By hand, with viem only:

```ts
import { privateKeyToAccount } from 'viem/accounts';

const wallet = privateKeyToAccount(process.env.WALLET_KEY as `0x${string}`);
const url = 'https://api.femtos.xyz/v1/status';
const r402 = await fetch(url);
const req = JSON.parse(atob(r402.headers.get('PAYMENT-REQUIRED')!)); // x402 v2 PaymentRequired
const offer = req.accepts[0]; // the cheapest chain; or the entry of the chain your USDC is on
const chainId = Number(offer.network.split(':')[1]);
const hex = (b: Uint8Array) => [...b].map((x) => x.toString(16).padStart(2, '0')).join('');
const authorization = {
  from: wallet.address, to: offer.payTo, value: BigInt(offer.amount), validAfter: 0n,
  validBefore: BigInt(Math.floor(Date.now() / 1000) + offer.maxTimeoutSeconds),
  nonce: `0x${hex(crypto.getRandomValues(new Uint8Array(32)))}` as `0x${string}`,
};
const signature = await wallet.signTypedData({
  domain: { name: offer.extra.name, version: offer.extra.version, chainId, verifyingContract: offer.asset },
  types: { TransferWithAuthorization: [
    { name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'value', type: 'uint256' },
    { name: 'validAfter', type: 'uint256' }, { name: 'validBefore', type: 'uint256' }, { name: 'nonce', type: 'bytes32' },
  ] },
  primaryType: 'TransferWithAuthorization',
  message: authorization,
});
const payment = { x402Version: 2, resource: req.resource, accepted: offer, payload: { signature, authorization: {
  ...authorization, value: String(authorization.value), validAfter: '0', validBefore: String(authorization.validBefore) } } };
const res = await fetch(url, { headers: { 'PAYMENT-SIGNATURE': btoa(JSON.stringify(payment)) } });
const key = res.headers.get('X-Femtos-Key');
```

### Walkthrough (curl)

```bash
CH=$(curl -s https://femtos.xyz/accounts/agent/challenge)
SALT=$(echo "$CH" | jq -r .salt); DIFF=$(echo "$CH" | jq -r .difficulty)
NONCE=$(python3 solve_pow.py "$SALT" "$DIFF")      # solver below
curl -s https://femtos.xyz/accounts/agent/signup -H 'content-type: application/json' \
  -d "{\"agent_name\": \"my-agent\", \"salt\": \"$SALT\", \"nonce\": \"$NONCE\"}" > signup.json
export FEMTOS_KEY=$(jq -r .key signup.json)        # shown once: keep signup.json private
export FEMTOS_SECRET=$(jq -r .managementSecret signup.json)   # shown once too: rotate / delete / unfreeze
curl -s -H "Authorization: Bearer $FEMTOS_KEY" https://api.femtos.xyz/v1/whoami
curl -s -H "Authorization: Bearer $FEMTOS_KEY" https://femtos.xyz/accounts/agent/me
# a heavy call of an exhausted key (billing active) answers 402 {"error": "payment_required", "checkoutUrl", "hint"}
curl -s -X POST https://femtos.xyz/accounts/agent/checkout -H "Authorization: Bearer $FEMTOS_KEY" \
  -H 'content-type: application/json' -d '{"amount_usd": 25}'
# → {"card": {"checkoutUrl"}, "usdc": {"hypercore": {"address"}, "hyperevm": {"address", "token", "chainId": 999}}, "credits": {…}}
# the key leaked: freeze it now, then rotate it (the new key is live, the frozen one is gone)
curl -s -X POST https://femtos.xyz/accounts/me/freeze -H "Authorization: Bearer $FEMTOS_KEY"
curl -s -X POST https://femtos.xyz/accounts/rotate -H "Authorization: Bearer $FEMTOS_KEY" -H "X-Management-Secret: $FEMTOS_SECRET" > rotated.json
```

### Proof-of-work solver

Python 3 (`solve_pow.py <salt> <difficulty>`, standard library only):

```python
import hashlib, itertools, sys

def solve(salt: str, difficulty: int) -> str:
    for i in itertools.count():
        nonce = format(i, "x")
        h = hashlib.sha256(f"{salt}:{nonce}".encode()).digest()
        if int.from_bytes(h, "big") >> (256 - difficulty) == 0:
            return nonce

print(solve(sys.argv[1], int(sys.argv[2])))
```

JavaScript (Node):

```js
import { createHash } from 'node:crypto';
function solve(salt, difficulty) {
  for (let i = 0; ; i++) {
    const nonce = i.toString(36);
    const h = createHash('sha256').update(`${salt}:${nonce}`).digest();
    let bits = 0;
    for (const b of h) { if (b) { bits += Math.clz32(b) - 24; break; } bits += 8; }
    if (bits >= difficulty) return nonce;
  }
}
```

## Hyperliquid SDKs, drop-in

`POST https://api.femtos.xyz/info` and `wss://api.femtos.xyz/ws` answer like `api.hyperliquid.xyz`: an existing Hyperliquid client only changes its base URL and sends the key.

TypeScript, @nktkas/hyperliquid:

```ts
import { HttpTransport, InfoClient, SubscriptionClient, WebSocketTransport } from '@nktkas/hyperliquid';

const KEY = process.env.FEMTOS_KEY!;
const info = new InfoClient({
  transport: new HttpTransport({ apiUrl: 'https://api.femtos.xyz', fetchOptions: { headers: { Authorization: `Bearer ${KEY}` } } }),
});
console.log(await info.l2Book({ coin: 'BTC' }));
// the WebSocket transport takes no headers: the key goes in the URL
const subs = new SubscriptionClient({ transport: new WebSocketTransport({ url: `wss://api.femtos.xyz/ws?token=${KEY}` }) });
await subs.allMids((d) => console.log(d));
```

Python, hyperliquid-python-sdk:

```python
import os, requests
from hyperliquid.info import Info
from hyperliquid.websocket_manager import WebsocketManager

KEY = os.environ["FEMTOS_KEY"]; BASE = "https://api.femtos.xyz"; AUTH = {"Authorization": f"Bearer {KEY}"}
# Info() fetches meta / spotMeta in its constructor, before headers can be set: pass them in
post = lambda body: requests.post(f"{BASE}/info", json=body, headers=AUTH, timeout=10).json()
info = Info(BASE, skip_ws=True, meta=post({"type": "meta"}), spot_meta=post({"type": "spotMeta"}))
info.session.headers.update(AUTH)
ws = WebsocketManager(BASE)   # wss://api.femtos.xyz/ws
ws.ws.header = AUTH           # sent on the upgrade
info.ws_manager = ws; ws.start()
print(info.all_mids())
info.subscribe({"type": "allMids"}, print)
```

ccxt (JavaScript; Python takes the same options):

```js
import ccxt from 'ccxt';

const KEY = process.env.FEMTOS_KEY;
// read-only: hostname moves every REST URL to api.femtos.xyz (/info); never send these headers to api.hyperliquid.xyz
const ex = new ccxt.pro.hyperliquid({
  hostname: 'femtos.xyz',
  headers: { Authorization: `Bearer ${KEY}` },
  urls: { api: { ws: { public: `wss://api.femtos.xyz/ws?token=${KEY}` } } },
});
await ex.loadMarkets();
console.log(await ex.fetchOrderBook('BTC/USDC:USDC'));
console.log(await ex.watchTrades('BTC/USDC:USDC'));
```

## Elysium

### Launches

#### New launches — GET `/v1/launches`

Latest Ascend launches, newest first, with live market figures.

| Param | In | Example or values |
|---|---|---|
| `limit` | query | `20` |
| `launchpad` | query | `ascend` |
| `creator` | query | (optional) |
| `q` | query | (optional) |
| `minMcapUsd` | query | `50000` |
| `minHolders` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches?limit=20&launchpad=ascend&minMcapUsd=50000&minHolders=20"
```

| Field | Type | Meaning |
|---|---|---|
| `token` | string | launched token |
| `symbol · name` | string \| null | ERC-20 metadata |
| `pair` | string | pool key, the market of candles and trades |
| `creator` | string | dev wallet |
| `launchedAt · block · tx` | int · string | launch event |
| `supply · supplySeeded` | decimal | total supply, tokens seeded in the pool |
| `devBuyTokens` | decimal \| null | tokens the creator bought at launch |
| `priceUsd · mcapUsd` | decimal \| null | last swap price, supply × price |
| `volume24hUsd · trades24h` | decimal · int | rolling 24 h |
| `holders` | int | positive balances, system addresses excluded |
| `top10Share · devHoldsShare` | number \| null | share of supply, 0–1 |
| `devSold` | boolean | creator sold at least once |
| `spam · spamReason` | boolean · string \| null | spam token: left out unless includeSpam=true |
| `volumeSinceLaunchUsd · tradesSinceLaunch` | decimal · int | the pool since the launch |
| `ascend.status` | ascended \| launched \| null | derived: every criterion with a threshold met; null without thresholds |
| `ascend.criteria` | object | mcapUsd · holders · volumeUsd · top10Share: {value, threshold, met, progress} |
| `minMcapUsd · minHolders · minVolumeUsd · maxTop10Share` | query | your thresholds (Ascend publishes none) |
| `creator · quote · q · since · until` | query | filters: dev wallet, quote token, symbol / name, launch time (ms) |
| `before` | query | next page: the X-Next-Cursor header (block:logIndex) |

#### Launches stream — WS `elysium.launches`

One message per new launch, the moment its block is indexed.

| Param | In | Example or values |
|---|---|---|
| `launchpad` | filter | (optional) |

```json
{"op":"subscribe","channel":"elysium.launches","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | LaunchRow[] | last 50 launches at subscribe |
| `data` | LaunchRow | one new launch (same shape as GET /api/launches) |
| `ts.source` | int | block time of the launch (ms) |

#### Ascend swaps stream — WS `ascend.swaps`

Every swap of every Ascend pool, one message per block.

| Param | In | Example or values |
|---|---|---|
| `token` | filter | (optional) |
| `side` | filter | `(empty)`, `buy`, `sell` |
| `min_usd` | filter | (optional) |

```json
{"op":"subscribe","channel":"ascend.swaps","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | AscendSwap[] | last 50 matching swaps |
| `data` | AscendSwap[] | the matching swaps of one block, all pools |
| `token · symbol · pair` | string | the launch the swap trades |
| `side · tokens · quoteAmount · usd` | string | of the launched token; USDC; USD |
| `priceUsd · mcapUsd` | decimal \| null | after the swap |
| `trader · id` | string | tx.from; <tx>:<log>, as /api/trades |
| `block · tx · logIndex` | int · string · int | source: the Swap log |
| `trader · launchpad` | filter | more filters |

#### Ascended transitions — WS `ascend.status`

A message when a launch crosses your thresholds, in the block where it happens.

| Param | In | Example or values |
|---|---|---|
| `min_mcap_usd` | filter | `50000` |
| `min_holders` | filter | `20` |
| `token` | filter | (optional) |

```json
{"op":"subscribe","channel":"ascend.status","filter":{"min_mcap_usd":"50000","min_holders":"20"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | {token, symbol, pair, status, ascend} of the last 50 launches |
| `data.kind` | ascended \| lost \| criterion | status became ascended, left it, or one criterion flipped |
| `data.crossed[]` | object | {criterion, met} |
| `data.ascend` | object | progress after the block |
| `min_volume_usd · max_top10_share` | filter | more thresholds; none at all: refused |

### Market data

#### Candles — GET `/v1/candles`

OHLCV of one pool in pair price, USD and market cap, ascending, UTC-aligned.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `market` | query | `<pair>` |
| `tf` | query | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |
| `limit` | query | `288` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/candles?layer=elysium&market=<pair>&tf=5m&limit=288"
```

| Field | Type | Meaning |
|---|---|---|
| `t` | int | unit start (ms) |
| `o · h · l · c` | decimal | price in the quote token |
| `usd {o,h,l,c}` | decimal | same candle in USD |
| `mcap {o,h,l,c}` | decimal | same candle as market cap, USD |
| `v · vq` | decimal | volume in token, in quote |
| `n` | int | swaps in the unit |
| `vUsd` | decimal \| null | volume in USD |
| `mcUsd` | decimal | market cap at close; absent on filled candles |
| `from · to · fill` | query | window (ms) and flat candles for empty units (fill=1, default) |
| `asOf · height` | int | head the answer is cut at: every trade up to that block counted |

#### Forming candle — WS `elysium.candles`

The forming candle, pushed once per block where it changes.

| Param | In | Example or values |
|---|---|---|
| `pair` | filter | `<pair>` |
| `tf` | filter | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |

```json
{"op":"subscribe","channel":"elysium.candles","filter":{"pair":"<pair>","tf":"1m"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Candle[] | last 300 candles at subscribe |
| `data` | Candle | the forming candle, same shape as REST |

#### Trades — GET `/v1/trades`

Latest swaps of one pool, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `market` | query | `<pair>` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/trades?layer=elysium&market=<pair>&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `t · block` | int | block time (ms), block |
| `px · pxUsd` | decimal | price in quote, in USD |
| `sz · vq · usd` | decimal | size in token, quote, USD |
| `side` | B \| A | buy or sell of the token |
| `mcapUsd` | decimal \| null | market cap after the swap |
| `trader` | string | tx.from (the wallet, not the router) |
| `id` | string | <tx>:<log index>, dedupe REST + WS on it |
| `tx · logIndex` | string · int | source: the Swap log, with block |

#### Trades stream — WS `elysium.trades`

The swaps of one pool, one message per block that has some.

| Param | In | Example or values |
|---|---|---|
| `pair` | filter | `<pair>` |

```json
{"op":"subscribe","channel":"elysium.trades","filter":{"pair":"<pair>"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Trade[] | last 50 swaps at subscribe |
| `data` | Trade[] | the swaps of one block |
| `latency_ms.source_to_sent` | int | block → sent by the server |

#### Daily token volume — GET `/v1/volume`

USD swap volume of a token per UTC day, both sides of every priced swap. Testnet pool prices.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `token` | query | `<token>` |
| `days` | query | `30` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/volume?layer=elysium&token=<token>&days=30"
```

| Field | Type | Meaning |
|---|---|---|
| `days[]` | object | {day (UTC ms), volumeUsd, partial?}, oldest first, days with volume |
| `partial` | boolean | the indexed head day, still filling |
| `totalUsd` | decimal | sum over the days |
| `asOf · height` | int | indexed head: every swap up to that block counted |

#### Token transfers — GET `/v1/transfers`

ERC-20 Transfer events of one token, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `token` | query | `<token>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/transfers?layer=elysium&token=<token>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | {block, t, tx, logIndex, from, to, amount, amountRaw} |
| `amount` | decimal \| null | in token units; null when decimals are unknown |
| `next · before` | string · query | block:logIndex cursor of the next page |

#### Liquidity events — GET `/v1/liquidity`

Liquidity added to and removed from one pool, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `pair` | query | `0x889a96eedb1df35a012d7e48baf7f9c780f1243b:0xfd93e1ba852feba3f05d7089513049c168a87fd058f64f4eb15f1c0bd3534467` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/liquidity?layer=elysium&pair=0x889a96eedb1df35a012d7e48baf7f9c780f1243b%3A0xfd93e1ba852feba3f05d7089513049c168a87fd058f64f4eb15f1c0bd3534467&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | {block, t, tx, kind: add \| remove, provider, amount0, amount1, usd} |
| `liquidityDelta · tickLower · tickUpper` | string · int | V4: the event carries a liquidity delta, no token amounts |
| `token0 · token1` | object | {address, symbol, decimals} |

### Holders & signals

#### Holders — GET `/v1/holders`

Current balances of a token, largest first, with concentration.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `token` | query | `<token>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/holders?layer=elysium&token=<token>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `totalHolders` | int | positive balances, system excluded |
| `top10Share` | number \| null | 10 largest shares, 0–1 |
| `holders[]` | object | {address, amount, share, usd?, side?, label?} |
| `system[]` | object | bridge, pools, fee collector… (excludeSystem=0 to count them) |
| `asOf · height` | int | time and block of the balances |

#### Launch detail & signals — GET `/v1/launches/{token}`

Metrics, dev wallet, early buyers and risk signals of one launch.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<token>` |
| `earlyWindowSec` | query | `60` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches/<token>?earlyWindowSec=60"
```

| Field | Type | Meaning |
|---|---|---|
| `launch` | LaunchRow | same row as GET /api/launches |
| `metrics` | object | price, mcap, ATH mcap, holders, volume, traders, buyers, sellers |
| `dev` | object | creator balance, buys, sells, transfers out |
| `holders.top[]` | object | 20 largest, tagged dev \| early |
| `earlyBuyers` | object | wallets that bought in the first window |
| `signals[]` | object | {rule, severity, addresses, detail}, high first |
| `fees` | object | estimate: 1 % of volume |
| `ascend` | object | progress toward Ascended + coordination evidence (flagged wallets, their share) |

#### Launch holders — GET `/v1/launches/{token}/holders`

Every holder of a launched token, tagged dev or early buyer, with concentration.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<token>` |
| `limit` | query | `20` |
| `offset` | query | (optional) |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches/<token>/holders?limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `totalHolders` | int | positive balances, system excluded |
| `concentration` | object | top 1 / 10 / 20 / 50 shares, HHI, dev, flagged early buyers, held share |
| `system` | object | PancakeSwap Infinity vault and PoolManager, Ascend treasuries: count, share |
| `holders[]` | object | {rank, address, amount, shareOfSupply, firstSeenAt, lastActiveAt, tag?, flags?} |
| `next` | int \| null | offset of the next page |

### NFTs

#### Active NFT collections — GET `/v1/nfts/collections`

Collections with the most transfers over the last 1 h or 24 h.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `window` | query | `24h`, `1h` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/collections?layer=elysium&window=24h&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `collections[]` | object | {address, standard, name, symbol, transfers, mints, burns, lastBlock} |
| `from · to` | int | window (ms), ends at the indexed head |
| `fromBlock · toBlock` | int | blocks read |

#### NFT collection — GET `/v1/nfts/collections/{address}`

Metadata, tokens seen and 24 h activity of one collection.

| Param | In | Example or values |
|---|---|---|
| `address` | path | `<collection>` |
| `layer` | query | `elysium` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/collections/<collection>?layer=elysium"
```

| Field | Type | Meaning |
|---|---|---|
| `collection` | object | {address, standard, name, symbol, firstSeenBlock, firstSeenAt} |
| `tokens` | object | {count, capped}: counted up to 1,000 |
| `activity24h` | object | {transfers, mints, burns, lastBlock, fromBlock, toBlock} |

#### Collection tokens — GET `/v1/nfts/tokens`

Tokens of a collection by id, with their owner and metadata URI.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `collection` | query | `<collection>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/tokens?layer=elysium&collection=<collection>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `tokens[]` | object | {tokenId, standard, owner, uri, firstSeenBlock, lastTransferBlock} |
| `owner` | string \| null | ERC-721 owner, 0x0 once burnt; null for ERC-1155 |
| `uri · uriLength` | string \| null · int | URI as returned; over 2,048 characters: null + its length |
| `next · after` | string · query | last token id, pass as after for the next page |

#### NFTs of a wallet — GET `/v1/nfts/owned`

ERC-721 tokens owned and ERC-1155 balances of one address.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `owner` | query | `<owner>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/owned?layer=elysium&owner=<owner>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `erc721 · erc1155` | int | tokens owned, token ids held (counted up to 10,000) |
| `collections[]` | object | {address, name, symbol, erc721, erc1155} |
| `tokens[]` | object | {collection, tokenId, standard, amount, uri} |
| `asOf · height` | int | indexed head the holdings include |

#### NFT transfers — GET `/v1/nfts/transfers`

Transfers of a collection or one token, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `collection` | query | `<collection>` |
| `tokenId` | query | (optional) |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/transfers?layer=elysium&collection=<collection>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | {block, t, tx, kind, tokenId, amount, from, to, operator} |
| `kind` | mint \| burn \| transfer | from 0x0, to 0x0, else transfer |
| `scope` | all \| 24h \| 7d | whole history, or the block window read |
| `next · before` | string · query | block:log:batch cursor of the next page |

### Lifecycle

#### Lifecycle stage changes — WS `ascend.lifecycle`

A message when a launched token reaches its next stage: listing desk, HyperEVM mirror, HyperCore spot, perp.

| Param | In | Example or values |
|---|---|---|
| `token` | filter | (optional) |

```json
{"op":"subscribe","channel":"ascend.lifecycle","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | {kind: snapshot, stages: {token: [stages]}}, or the lifecycle of `token` |
| `data.kind` | stage | a launched token reached or lost a stage |
| `data.reached · data.lost` | string[] | stages since the previous poll |
| `data.stage · data.previous` | string | current and previous last stage |
| `data.lifecycle` | object | as GET /api/tokens/{token}/lifecycle |

#### Launch timeline — GET `/v1/launches/{token}/timeline`

The whole life of a launch as ordered events with running state.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<token>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches/<token>/timeline"
```

| Field | Type | Meaning |
|---|---|---|
| `launch` | object | {t, block, tx, creator, supplySeeded, devBuyTokens} |
| `events[]` | object | launch \| swap \| transfer, chain order |
| `events[].holders · top10Share` | int · number | running state after the event |
| `events[].mcapUsd · volumeUsd` | decimal | running market cap, cumulated volume |
| `current` | object | figures right now |
| `graduation` | object | {mirror: HyperEVM token \| null, core: HyperCore spot \| null} |
| `truncated` | boolean | over 5,000 swaps: replay stops there |

#### Token across layers — GET `/v1/tokens/{token}/lifecycle`

One token from its Elysium launch to its HyperEVM mirror, HyperCore spot and perps, each link proven or marked inferred.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<token>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/tokens/<token>/lifecycle"
```

| Field | Type | Meaning |
|---|---|---|
| `stage` | string \| null | last stage reached: launched · registered · enrolled · committed · bridged · listed · perp |
| `stages[]` | object | {stage, reached, exact, basis, at {layer, block, time, tx}, observedAt, source, detail} |
| `addresses` | object | elysium · hyperevm · hypercore {index, spot} · perps[] |
| `links[]` | object | {from, to, relation, exact, basis: event \| registry \| attestation \| metadata \| name} |
| `conflicts · unavailable` | string[] | sources that disagree · that could not answer |
| `fees` | object \| null | exact fees of the pool from its events (Ascend) |
| `token` | path | also a HyperEVM address, core:<index>, a HyperCore name or perp coin |

### Bridge & wallet

#### Bridge movements — GET `/v1/bridges`

HyperEVM ↔ Elysium movements with 24 h stats.

| Param | In | Example or values |
|---|---|---|
| `route` | query | `evm_elysium` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/bridges?route=evm_elysium&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | one movement: status, direction, value, token, both chains’ blocks and txs |
| `rows[].bridge_latency_ms` | int \| null | sent → credited |
| `stats` | object | 24 h: count, completed, pending, latency p50 / p99 |
| `direction · token · account · system` | query | filters (system: exclude \| include \| only) |
| `tokens` | object | {address: {symbol, decimals}} |
| `labels` | object | {address: name}: Kinetiq's system senders and contracts |

#### Bridge stream — WS `elysium.bridge`

Each state change of a HyperEVM ↔ Elysium movement, live.

| Param | In | Example or values |
|---|---|---|
| `token` | filter | (optional) |
| `direction` | filter | `(empty)`, `to_child`, `to_parent` |

```json
{"op":"subscribe","channel":"elysium.bridge","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 movements |
| `data` | object | one movement in its new state (REST row shape) |

#### Cross-layer wallet — GET `/v1/wallet/{address}`

One address (or a named wallet's handle) on HyperCore, HyperEVM and Elysium, plus its latest events.

| Param | In | Example or values |
|---|---|---|
| `address` | path | `<creator>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/wallet/<creator>"
```

| Field | Type | Meaning |
|---|---|---|
| `hypercore` | object | perp account, positions, spot balances (mainnet) |
| `hyperevm` | object | balances, NFTs, swaps / transfers scope, HyperCore ↔ HyperEVM bridges |
| `elysium` | object | token balances and NFTs (testnet), Orbit bridges |
| `bridges` | object | legs in flight and journeys Core → HyperEVM → Elysium (and back) |
| `*.freshness` | object | each section: head, headTime, lagMs, behindMs (as /api/status) |
| `recent[]` | object | {layer, kind: fill \| ledger \| bridge \| swap \| transfer, t, data} |
| `labels` | object | known addresses → label |

#### Wallet stream — WS `wallet`

Every event of the three layers touching one address.

| Param | In | Example or values |
|---|---|---|
| `address` | filter | `<creator>` |

```json
{"op":"subscribe","channel":"wallet","filter":{"address":"<creator>"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 events |
| `data` | {channel, data} | one event: hc.trades, hc.ledger, elysium.trades, elysium.bridge… |

#### Token registry — GET `/v1/coins`

Links one token across Elysium, HyperEVM and HyperCore.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `q` | query | `<token>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins?layer=elysium&q=<token>"
```

| Field | Type | Meaning |
|---|---|---|
| `id · symbol · decimals` | string · int | token on this layer |
| `priceUsd` | decimal \| null | last price |
| `links.evm · links.core` | object | the same asset on the other layers |
| `coverage` | object | whether we index it |

#### Coin detail — GET `/v1/coins/{layer}/{id}`

One token: its links across layers, the markets it trades on, its 5 largest holders.

| Param | In | Example or values |
|---|---|---|
| `layer` | path | `elysium` |
| `id` | path | `<token>` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins/elysium/<token>"
```

| Field | Type | Meaning |
|---|---|---|
| `coin` | object | {id, symbol, name, decimals, totalSupply, priceUsd, links, spam, spamReason} |
| `markets[]` | Market | markets where it is base or quote, most traded first |
| `holders` | object | 5 largest holders, or {unavailable} |

### Named wallets

#### KOL leaderboard — GET `/v1/kols/leaderboard`

KOLs, traders and funds ranked by their Elysium swaps, transfers, bridge legs and holdings.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `window` | query | `24h`, `7d`, `30d` |
| `sort` | query | `volume`, `swaps`, `transfers`, `netBuy`, `holdings`, `bridges`, `lastActivity` |
| `limit` | query | `50` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/leaderboard?layer=elysium&window=24h&sort=volume&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[].entity` | {id, name, x, kinds} | who public lists name the wallets |
| `swaps · volumeUsd · netBuyUsd` | int · decimal | DEX swaps sent by its wallets, USD volume, buys − sells |
| `transfersIn · transfersOut · bridges` | int | ERC-20 transfers, bridge legs |
| `holdingsUsd` | decimal \| null | HyperEVM: USD held at the indexed head |
| `scope` | object | blocks read per kind: 24 h without the address indexes (7d / 30d: 503) |

#### KOL moves — GET `/v1/kols/activity`

The latest Elysium swaps and transfers of the named wallets, with who moved.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `elysium` |
| `entity` | query | (optional) |
| `minNotional` | query | (optional) |
| `limit` | query | `50` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/activity?layer=elysium&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | KolItem | {kind: swap \| transfer, t, wallet, entity, pair, base, side, notional, token, amount} |
| `hash · block · logIndex` | string · int · int | source: the swap / Transfer log |
| `bridges[]` | KolItem | first page: their latest bridge legs (kind bridge) |
| `scope` | object | blocks read per kind |
| `spam · spamReason` | boolean · string | spam tokens hidden unless includeSpam=true |
| `next · before` | string | cursor <block>:<logIndex> of the next page |

#### KOL stream — WS `kol.activity`

Every Elysium swap, transfer and bridge leg of a named wallet, on each indexed block.

| Param | In | Example or values |
|---|---|---|
| `layer` | filter | `elysium` |
| `kind` | filter | `(empty)`, `swap`, `transfer`, `bridge` |

```json
{"op":"subscribe","channel":"kol.activity","filter":{"layer":"elysium"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | KolItem[] | last 50 moves seen |
| `data` | KolItem | {layer, kind: swap \| transfer \| bridge, wallet, entity, side, notional} |

## HyperCore

### Market data

#### Markets — GET `/v1/markets`

Every tradable perp, spot, HIP-3 and outcome market with 24 h stats.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `includeOutcomes` | query | `(empty)`, `1` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/markets?layer=hypercore"
```

| Field | Type | Meaning |
|---|---|---|
| `id · symbol · base · quote` | string | market id (BTC, @107, xyz:SP500, #1230) |
| `kind` | perp \| spot \| hip3 \| outcome | market type |
| `price · change24h` | decimal · number | last trade, 24 h change in % |
| `volume24hUsd · trades24h` | decimal · int | rolling 24 h from our fills |
| `szDecimals · maxLeverage · dex` | int · string | contract specs |

#### Candles — GET `/v1/candles`

OHLCV of any HyperCore market down to 1 s, ascending, UTC-aligned.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `market` | query | `BTC` |
| `tf` | query | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |
| `limit` | query | `180` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/candles?layer=hypercore&market=BTC&tf=1m&limit=180"
```

| Field | Type | Meaning |
|---|---|---|
| `t` | int | unit start (ms) |
| `o · h · l · c` | decimal | price; backstop liquidations excluded |
| `v · vq` | decimal | volume in base, in quote |
| `n` | int | trades in the unit |
| `from · to · fill` | query | window (ms) and flat candles for empty units (fill=1, default) |
| `asOf · height` | int | head the answer is cut at: every trade up to that block counted |

#### Forming candle — WS `hc.candles`

The forming candle, pushed once per block where it changes.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `BTC` |
| `tf` | filter | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |

```json
{"op":"subscribe","channel":"hc.candles","filter":{"coin":"BTC","tf":"1s"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Candle[] | last 300 candles at subscribe |
| `data` | Candle | {t,o,h,l,c,v,vq,n,block}, the forming candle |

#### Trades — GET `/v1/trades`

Latest fills of one market, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `market` | query | `BTC` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/trades?layer=hypercore&market=BTC&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `t · block` | int | block time (ms), block |
| `px · sz` | decimal | price, size in base |
| `side` | B \| A | aggressor side |
| `id` | string | trade id (tid) |
| `tx` | string \| null | source: hash of the transaction whose fills made the trade |

#### Trades stream — WS `hc.trades`

All trades of one market as they happen: raced between our node and Hyperliquid's public feed, first copy sent, the other dropped.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `BTC` |

```json
{"op":"subscribe","channel":"hc.trades","filter":{"coin":"BTC"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Trade[] | last 50 trades at subscribe |
| `data` | Trade[] | the new trades: {t, px, sz, side, tid, hash, users, block} |
| `tid` | int | trade id, unique: dedupe on it |
| `users` | [buyer, seller] | both sides, lowercase 0x |
| `hash` | string | transaction hash (all zeros when the public feed gives none) |
| `block` | int \| null | null when the public feed was first; our node fills it in the snapshots |
| `latency_ms.source_to_sent` | int | trade time → sent by the server |

#### Best bid / offer — WS `hc.bbo`

Top of book of one market each block: raced between Hyperliquid's public feed and our node (newest block wins, our node corrects the same block).

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `BTC` |

```json
{"op":"subscribe","channel":"hc.bbo","filter":{"coin":"BTC"}}
```

| Field | Type | Meaning |
|---|---|---|
| `data.bbo` | [[px, sz, n], [px, sz, n]] | best bid, best ask: price, size, order count |
| `data.time` | int | block time (ms) |
| `data.block` | int \| null | null when the public feed was first |
| `latency_ms.source_to_sent` | int | block → sent by the server |

#### Order book — GET `/v1/book`

L2 book of one market with order counts, from our node.

| Param | In | Example or values |
|---|---|---|
| `coin` | query | `BTC` |
| `depth` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/book?coin=BTC&depth=20"
```

| Field | Type | Meaning |
|---|---|---|
| `bids · asks` | [px, sz, n][] | levels best first: price, size, order count |
| `height` | int | block of the book |

#### Book stream — WS `hc.book`

Full-depth book, then the levels each block changes.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `HYPE` |

```json
{"op":"subscribe","channel":"hc.book","filter":{"coin":"HYPE"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | {height, bids, asks} | full depth (a partial top-100 first) |
| `data` | {height, prevHeight, bids, asks} | changed levels; sz "0" = level removed |
| `prevHeight` | int | must equal your height, else resubscribe |

#### Order updates — WS `hc.orders`

Every order status change, filterable by coin, user and status.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `HYPE` |
| `user` | filter | (optional) |
| `status` | filter | `(empty)`, `open`, `filled`, `canceled`, `triggered`, `rejected` |

```json
{"op":"subscribe","channel":"hc.orders","filter":{"coin":"HYPE","status":"filled"}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {coin, side, px, sz, orig_sz, status, order_type, tif, oid, user, block, time} |
| `status` | string | open, filled, canceled, triggered, *Rejected… |

#### HYPE price — WS `prices.hype`

HYPE from the Hyperliquid oracle, perp mark and exchanges.

```json
{"op":"subscribe","channel":"prices.hype","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {token, source, price, quote, ts} |

### Liquidations & positions

#### Liquidations — GET `/v1/liquidations`

Perp liquidations, newest first, one row per account, coin and block.

| Param | In | Example or values |
|---|---|---|
| `coin` | query | (optional) |
| `minNotional` | query | (optional) |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/liquidations?limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `events[]` | object | {block, time, coin, user, side, method, trades, sz, notional, avgPx, markPx} |
| `side` | long \| short | side of the liquidated position |
| `method` | market \| backstop | liquidation path |
| `user · from · to` | query | account, window (ms): the last 7 days, 30 with coin |
| `from` | ms | start of the window read (an older from is clamped to it) |

#### Liquidation stats — GET `/v1/liquidations/stats`

Totals, per coin, per time bucket and the largest, over a window.

| Param | In | Example or values |
|---|---|---|
| `window` | query | `1h`, `24h`, `7d`, `30d` |
| `coin` | query | (optional) |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/liquidations/stats?window=24h"
```

| Field | Type | Meaning |
|---|---|---|
| `total` | object | {notional, count, accounts, longNotional, shortNotional, market, backstop} |
| `byCoin[]` | object | per coin, largest first |
| `buckets[]` | object | {t, longNotional, shortNotional, count}, bucketMs apart |
| `largest[] · topAccounts[]` | object | 10 largest liquidations, 20 most liquidated accounts |

#### Liquidations stream — WS `hc.liquidations`

Each liquidation fill, the block it happens.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | (optional) |
| `min_notional` | filter | (optional) |

```json
{"op":"subscribe","channel":"hc.liquidations","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 liquidation fills |
| `data` | object | {coin, liquidated_user, liquidated_side, method, px, sz, notional, mark_px, time, block} |

#### Positions — GET `/v1/positions`

Open positions of one perp with leverage and liquidation price.

| Param | In | Example or values |
|---|---|---|
| `coin` | query | `BTC` |
| `side` | query | `(empty)`, `long`, `short` |
| `sort` | query | `notional`, `upnl`, `liqDistance` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/positions?coin=BTC&sort=notional&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `positions[]` | object | {address, szi, side, entryPx, notional, upnl, leverage, marginMode, liqPx, liqDistancePct} |
| `markPx · asOf · height` | decimal · int | mark used, snapshot time and block |
| `sort · order` | string | applied sort |

#### Open interest — GET `/v1/positions/overview`

Open interest, accounts and unrealized PnL per perp.

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/positions/overview"
```

| Field | Type | Meaning |
|---|---|---|
| `coins[]` | object | {coin, markPx, longOi, shortOi, longAccounts, shortAccounts, upnlLong, upnlShort, biggest} |
| `longOi = shortOi` | decimal | every perp is zero-sum: the split is in accounts and PnL |

#### Liquidation map — GET `/v1/positions/liqmap`

Notional that would be liquidated at each price around the mark.

| Param | In | Example or values |
|---|---|---|
| `coin` | query | `BTC` |
| `range` | query | `0.3` |
| `buckets` | query | `60` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/positions/liqmap?coin=BTC&range=0.3&buckets=60"
```

| Field | Type | Meaning |
|---|---|---|
| `buckets[]` | object | {px, longNotional, shortNotional, accounts}, px = bucket centre |
| `markPx · range` | decimal · number | centre and half-width (0.3 = ±30 %) |

#### Position changes — WS `hc.positions`

Each perp position change, one per block, account and coin.

| Param | In | Example or values |
|---|---|---|
| `coin` | filter | `BTC` |
| `min_notional` | filter | `100000` |

```json
{"op":"subscribe","channel":"hc.positions","filter":{"coin":"BTC","min_notional":"100000"}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {coin, user, kind, dir, start_position, end_position, sz, px, notional, liquidation} |
| `kind` | string | open, increase, reduce, close, flip |
| `min_notional` | filter | default 100000, "0" for all |

### Holders

#### Token holders — GET `/v1/holders`

Spot balances of a HyperCore token, largest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `token` | query | `HYPE` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/holders?layer=hypercore&token=HYPE&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `totalHolders` | int | positive balances, system excluded |
| `top10Share` | number \| null | 10 largest shares, 0–1 |
| `holders[]` | object | {address, amount, share, usd?, side?, label?} |
| `system[]` | object | bridge, pools, fee collector… (excludeSystem=0 to count them) |
| `asOf · height` | int | time and block of the balances |

#### Perp holders — GET `/v1/holders`

Largest open positions of a perp, long and short.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `token` | query | `BTC` |
| `kind` | query | `positions`, `balances` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/holders?layer=hypercore&token=BTC&kind=positions&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `totalHolders` | int | positive balances, system excluded |
| `top10Share` | number \| null | 10 largest shares, 0–1 |
| `holders[]` | object | {address, amount, share, usd?, side?, label?} |
| `system[]` | object | bridge, pools, fee collector… (excludeSystem=0 to count them) |
| `asOf · height` | int | time and block of the balances |

#### Token registry — GET `/v1/coins`

HyperCore tokens with their HyperEVM contract and price.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hypercore` |
| `q` | query | (optional) |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins?layer=hypercore&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `id · symbol · decimals` | string · int | token name on HyperCore |
| `priceUsd · totalSupply` | decimal \| null | last price, supply |
| `links.core · links.evm` | object | spot index, HyperEVM contract |
| `coverage` | object | bridge link kind and verification |

#### Coin detail — GET `/v1/coins/{layer}/{id}`

One token: its links across layers, the markets it trades on, its 5 largest holders.

| Param | In | Example or values |
|---|---|---|
| `layer` | path | `hypercore` |
| `id` | path | `HYPE` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins/hypercore/HYPE"
```

| Field | Type | Meaning |
|---|---|---|
| `coin` | object | {id, symbol, name, decimals, totalSupply, priceUsd, links} |
| `markets[]` | Market | markets where it is base or quote, most traded first |
| `holders` | object | 5 largest holders, or {unavailable} |

### Named wallets

#### KOL leaderboard — GET `/v1/kols/leaderboard`

KOLs, traders and funds ranked by their HyperCore PnL, volume and open positions.

| Param | In | Example or values |
|---|---|---|
| `window` | query | `24h`, `7d`, `30d` |
| `sort` | query | `netPnl`, `realizedPnl`, `volume`, `fills`, `winRate`, `openNotional` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/leaderboard?window=7d&sort=netPnl&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[].entity` | {id, name, x, kinds} | who public lists name the wallets |
| `netPnl · realizedPnl · fees` | decimal | closed PnL of the fills minus USDC fees |
| `volume · fills · winRate` | decimal · int · 0–1 | quote volume, fills, closing fills in profit |
| `open` | object | open perps now: positions, notional, upnl, top 3 |

#### KOL trades — GET `/v1/kols/activity`

The latest fills of the named wallets, newest first, with who traded.

| Param | In | Example or values |
|---|---|---|
| `minNotional` | query | `10000` |
| `entity` | query | (optional) |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/activity?minNotional=10000&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | KolItem | {t, wallet, entity, coin, side, px, sz, notional, dir, closedPnl, tid} |
| `hash · block` | string · int | source: the fill’s transaction and block |
| `next · before` | string | cursor <time ms>:<block>:<event> of the next page |

#### KOL stream — WS `kol.activity`

Every fill, liquidation, EVM swap, transfer and bridge leg of a named wallet, live.

| Param | In | Example or values |
|---|---|---|
| `min_notional` | filter | `1000` |

```json
{"op":"subscribe","channel":"kol.activity","filter":{"min_notional":"1000"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | KolItem[] | last 50 moves seen |
| `data` | KolItem | {layer, kind: trade \| liquidation \| swap \| transfer \| bridge, wallet, entity, coin, side, notional} |

#### Named wallets — GET `/v1/entities`

Every named entity, its X account, kinds, sources and wallets.

| Param | In | Example or values |
|---|---|---|
| `q` | query | (optional) |
| `kind` | query | (optional) |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/entities"
```

| Field | Type | Meaning |
|---|---|---|
| `entities[]` | Entity | {id, name, x, kinds, aliases, sources, wallets[]} |
| `wallets[].address` | handle | <entityId>.<hex>: a named wallet's address is never served, its handle stands for it in every answer and is accepted wherever an address is |
| `entity · <field>Entity` | {id, name, x, kinds} | next to named addresses in every answer |

#### One entity — GET `/v1/entities/{id}`

One named entity: its wallets on the three layers and 30 days of HyperCore trading.

| Param | In | Example or values |
|---|---|---|
| `id` | path | `abraxascapital` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/entities/abraxascapital"
```

| Field | Type | Meaning |
|---|---|---|
| `totals` | object | account value, open perps, spot and HyperEVM balances |
| `hypercore30d` | object | {fills, volume, realizedPnl, fees, netPnl, winRate} |
| `wallets[]` | object | each wallet: HyperCore account, HyperEVM / Elysium balances, recent moves |

### Bridge & wallet

#### Bridge transfers — GET `/v1/bridges`

Matched HyperCore ↔ HyperEVM transfers with 24 h stats.

| Param | In | Example or values |
|---|---|---|
| `route` | query | `core_evm` |
| `direction` | query | `(empty)`, `evm_to_core`, `core_to_evm` |
| `token` | query | (optional) |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/bridges?route=core_evm&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | status, direction, token, account, amount, core{block,time,hash}, evm{block,time,tx} |
| `rows[].bridge_latency_ms` | int \| null | first leg → credited on the other layer |
| `stats` | object | 24 h: count, completed, stuck, latency p50 / p99 per direction, byToken |
| `rows[].matched_by` | nonce \| order \| null | how both legs were paired: nonce = exact (coreReceiveWithData), order = same system address, account and amount, in order; null while unmatched |
| `rows[].final_latency_ms` | int \| null | evm_to_core: HyperEVM leg → the beneficiary credited on HyperCore |
| `rows[].forwarding` | {amount, dex} \| null | a deposit wallet (Circle CoreDepositWallet) forwarded the deposit with CoreWriter sendAsset; dex 0 = main perp dex |
| `rows[].beneficiary` | string \| null | who is finally credited: the account, or a forwarded deposit's recipient; null for a CCTP withdrawal or until resolved |
| `rows[].depositor` | string \| null | who paid on the first layer: the account, or who funded the deposit wallet |
| `rows[].origin · rows[].final` | object \| null | origin: CCTP mint {domain, sender}; final: the HyperCore leg that credits the beneficiary |
| `labels` | object | {address: name} of known addresses in the rows (Circle CctpForwarder: the depositor of every CCTP mint) |
| `cctpDomains` | object | CCTP source domain → chain (0 Ethereum, 1 Avalanche, 2 OP Mainnet, 3 Arbitrum, 5 Solana, 6 Base, 7 Polygon PoS), for origin.domain |

#### Bridge coverage — 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.

| Param | In | Example or values |
|---|---|---|
| `window` | query | `all`, `30d`, `7d`, `24h` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/bridges/coverage?window=all"
```

| Field | Type | Meaning |
|---|---|---|
| `directions.evm_to_core · core_to_evm` | object | {legs, matched, coverage, unmatched: {reason: n}, notALeg, latencyMs: {p50, p90, p99, p999, max}, tokens[]} |
| `coverage` | number | matched / (legs − not legs − in flight): 1 = every settled leg has its other leg |
| `unmatched` | object | in_flight · missing_peer · amount_mismatch · late_peer · unknown_token |
| `core_to_evm.matchedBy` | object | {nonce: exact (coreReceiveWithData), order: same key in order} |
| `unpairedCredits` | object \| null | credits on the receiving side no leg took |
| `source · settledUntil` | string · ms | materialized tables (and how far they are settled) or the views |

#### Bridge stream — WS `bridge.transfers`

Each HyperCore ↔ HyperEVM transfer, initiated then completed.

| Param | In | Example or values |
|---|---|---|
| `token` | filter | (optional) |
| `direction` | filter | `(empty)`, `evm_to_core`, `core_to_evm` |

```json
{"op":"subscribe","channel":"bridge.transfers","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 transfers |
| `data` | object | one transfer in its new state (REST row shape) |

#### Cross-layer wallet — GET `/v1/wallet/{address}`

One address (or a named wallet's handle) on HyperCore, HyperEVM and Elysium, plus its latest events.

| Param | In | Example or values |
|---|---|---|
| `address` | path | `<address>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/wallet/<address>"
```

| Field | Type | Meaning |
|---|---|---|
| `hypercore.perp` | object | account value, margin, positions with liquidation price |
| `hypercore.spot` | object | balances with USD value |
| `hyperevm · elysium` | object | balances, NFTs, swaps / transfers and bridges on the other layers |
| `bridges` | object | legs in flight and journeys across the three layers |
| `*.freshness` | object | each section: head, headTime, lagMs, behindMs (as /api/status) |
| `recent[]` | object | {layer, kind: fill \| ledger \| bridge \| swap \| transfer, t, data} |

#### Wallet stream — WS `wallet`

Every event of the three layers touching one address.

| Param | In | Example or values |
|---|---|---|
| `address` | filter | `<address>` |
| `channel` | filter | (optional) |

```json
{"op":"subscribe","channel":"wallet","filter":{"address":"<address>"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 events |
| `data` | {channel, data} | one event: hc.trades, hc.orders, hc.ledger, bridge.transfers… |
| `channel` | filter | kinds to keep, comma list |

#### Ledger stream — WS `hc.ledger`

Deposits, withdrawals, transfers and other non-trade balance moves.

| Param | In | Example or values |
|---|---|---|
| `kind` | filter | (optional) |
| `token` | filter | (optional) |
| `min_amount` | filter | (optional) |

```json
{"op":"subscribe","channel":"hc.ledger","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {kind, user, token, amount, usdc_value, destination, hash, block, time} |
| `kind` | string | spotTransfer, send, deposit, withdraw, borrowLend… |

### Hyperliquid-compatible

#### POST /info — POST `/info`

Hyperliquid’s /info request bodies, answered from our node.

Same request bodies as `https://api.hyperliquid.xyz/info`, on `https://api.femtos.xyz/info` with `Authorization: Bearer $FEMTOS_KEY`.

| Field | Type | Meaning |
|---|---|---|
| `allMids · l2Book · metaAndAssetCtxs` | type | market state |
| `candleSnapshot · fundingHistory` | type | history by coin and window |
| `userFills · userFillsByTime · historicalOrders` | type | one account |
| `body · answer` | JSON | same as api.hyperliquid.xyz/info |

#### Hyperliquid WS — WS `/ws`

Hyperliquid’s WebSocket subscriptions, served from our node.

Same frames as `wss://api.hyperliquid.xyz/ws`, on `wss://api.femtos.xyz/ws?token=$FEMTOS_KEY`.

| Field | Type | Meaning |
|---|---|---|
| `{"method":"subscribe","subscription":{…}}` | frame | same frames as api.hyperliquid.xyz/ws |
| `trades · l2Book · candle · allMids · bbo` | type | market subscriptions |
| `userFills · orderUpdates` | type | one account |

## HyperEVM

### Launches

#### LiquidLaunch launches — GET `/v1/launches`

Latest LiquidLaunch bonding-curve launches, newest first.

| Param | In | Example or values |
|---|---|---|
| `launchpad` | query | `liquidlaunch` |
| `limit` | query | `20` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches?launchpad=liquidlaunch&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `token` | string | launched token |
| `symbol · name` | string \| null | ERC-20 metadata |
| `pair` | string | pool key, the market of candles and trades |
| `creator` | string | dev wallet |
| `launchedAt · block · tx` | int · string | launch event |
| `supply · supplySeeded` | decimal | total supply, tokens seeded in the pool |
| `devBuyTokens` | decimal \| null | tokens the creator bought at launch |
| `priceUsd · mcapUsd` | decimal \| null | last swap price, supply × price |
| `volume24hUsd · trades24h` | decimal · int | rolling 24 h |
| `holders` | int | positive balances, system addresses excluded |
| `top10Share · devHoldsShare` | number \| null | share of supply, 0–1 |
| `devSold` | boolean | creator sold at least once |
| `spam · spamReason` | boolean · string \| null | spam token: left out unless includeSpam=true |
| `bondedAt` | int \| null | curve completed, liquidity moved to the DEX |
| `bondingProgress` | number | share of the curve sold, 0–1 |

#### Launches stream — WS `hyperevm.launches`

One message per new LiquidLaunch launch, the moment its block is indexed.

| Param | In | Example or values |
|---|---|---|
| `include_spam` | filter | `(empty)`, `true` |

```json
{"op":"subscribe","channel":"hyperevm.launches","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | LaunchRow[] | last 50 launches at subscribe |
| `data` | LaunchRow | one new launch (same shape as GET /api/launches) |
| `include_spam` | filter | true: launches of spam tokens too, flagged spam |

#### Launch detail & signals — GET `/v1/launches/{token}`

Metrics, dev wallet, early buyers and risk signals of one launch.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<llToken>` |
| `earlyWindowSec` | query | `60` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches/<llToken>?earlyWindowSec=60"
```

| Field | Type | Meaning |
|---|---|---|
| `launch` | LaunchRow | with bondedAt, bondingProgress |
| `metrics · dev · holders` | object | as on Elysium |
| `signals[]` | object | {rule, severity, addresses, detail}, high first |

#### Launch timeline — GET `/v1/launches/{token}/timeline`

The whole life of a launch as ordered events with running state.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `<llToken>` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/launches/<llToken>/timeline"
```

| Field | Type | Meaning |
|---|---|---|
| `launch · events[] · current` | object | as on Elysium |
| `bondedAt` | int \| null | curve completed |
| `truncated` | boolean | over 5,000 swaps: replay stops there |

### Market data

#### Markets — GET `/v1/markets`

Active HyperEVM pools with 24 h stats.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/markets?layer=hyperevm"
```

| Field | Type | Meaning |
|---|---|---|
| `id · symbol · base · quote` | string | pool key and tokens |
| `kind · protocol · feeTier` | string | pool, DEX protocol |
| `price · change24h` | decimal · number | last swap, 24 h change in % |
| `volume24hUsd · trades24h · mcapUsd` | decimal · int | rolling 24 h, market cap |
| `spam · spamReason` | boolean · string \| null | base or quote is a spam token; hidden unless includeSpam=true |

#### Candles — GET `/v1/candles`

OHLCV of one pool in pair price, USD and market cap, ascending, UTC-aligned.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `market` | query | `<evmPair>` |
| `tf` | query | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |
| `limit` | query | `288` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/candles?layer=hyperevm&market=<evmPair>&tf=5m&limit=288"
```

| Field | Type | Meaning |
|---|---|---|
| `t` | int | unit start (ms) |
| `o · h · l · c` | decimal | price in the quote token |
| `usd {o,h,l,c}` | decimal | same candle in USD |
| `mcap {o,h,l,c}` | decimal | same candle as market cap, USD |
| `v · vq` | decimal | volume in token, in quote |
| `n` | int | swaps in the unit |
| `vUsd` | decimal \| null | volume in USD |
| `mcUsd` | decimal | market cap at close; absent on filled candles |
| `from · to · fill` | query | window (ms) and flat candles for empty units (fill=1, default) |
| `asOf · height` | int | head the answer is cut at: every trade up to that block counted |

#### Forming candle — WS `hyperevm.candles`

The forming candle, pushed once per block where it changes.

| Param | In | Example or values |
|---|---|---|
| `pair` | filter | `<evmPair>` |
| `tf` | filter | `1s`, `15s`, `1m`, `5m`, `15m`, `1h`, `4h`, `1d` |

```json
{"op":"subscribe","channel":"hyperevm.candles","filter":{"pair":"<evmPair>","tf":"1m"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Candle[] | last 300 candles at subscribe |
| `data` | Candle | the forming candle, same shape as REST |

#### Trades — GET `/v1/trades`

Latest swaps of one pool, newest first.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `market` | query | `<evmPair>` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/trades?layer=hyperevm&market=<evmPair>&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `t · block` | int | block time (ms), block |
| `px · pxUsd` | decimal | price in quote, in USD |
| `sz · vq · usd` | decimal | size in token, quote, USD |
| `side` | B \| A | buy or sell of the token |
| `mcapUsd` | decimal \| null | market cap after the swap |
| `trader` | string | tx.from (the wallet, not the router) |
| `id` | string | <tx>:<log index>, dedupe REST + WS on it |
| `tx · logIndex` | string · int | source: the Swap log, with block |

#### Trades stream — WS `hyperevm.trades`

The swaps of one pool, one message per block that has some.

| Param | In | Example or values |
|---|---|---|
| `pair` | filter | `<evmPair>` |

```json
{"op":"subscribe","channel":"hyperevm.trades","filter":{"pair":"<evmPair>"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | Trade[] | last 50 swaps at subscribe |
| `data` | Trade[] | the swaps of one block |

### Holders & tokens

#### Holders — GET `/v1/holders`

Current balances of an ERC-20, largest first, with concentration.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `token` | query | `<evmToken>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/holders?layer=hyperevm&token=<evmToken>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `totalHolders` | int | positive balances, system excluded |
| `top10Share` | number \| null | 10 largest shares, 0–1 |
| `holders[]` | object | {address, amount, share, usd?, side?, label?} |
| `system[]` | object | bridge, pools, fee collector… (excludeSystem=0 to count them) |
| `asOf · height` | int | time and block of the balances |
| `spam · spamReason` | boolean · string \| null | the token is flagged spam; its holders still answer |

#### Token registry — GET `/v1/coins`

HyperEVM tokens with their HyperCore spot link and price.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `q` | query | (optional) |
| `limit` | query | `50` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins?layer=hyperevm&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `id · symbol · decimals` | string · int | contract address, ERC-20 metadata |
| `priceUsd · totalSupply` | decimal \| null | last price, supply |
| `links.core` | object | the HyperCore spot token |
| `spam · spamReason` | boolean · string \| null | flagged by the indexer; hidden unless includeSpam=true |

#### Coin detail — GET `/v1/coins/{layer}/{id}`

One token: its links across layers, the markets it trades on, its 5 largest holders.

| Param | In | Example or values |
|---|---|---|
| `layer` | path | `hyperevm` |
| `id` | path | `<evmToken>` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/coins/hyperevm/<evmToken>"
```

| Field | Type | Meaning |
|---|---|---|
| `coin` | object | {id, symbol, name, decimals, totalSupply, priceUsd, links, spam, spamReason} |
| `markets[]` | Market | markets where it is base or quote, most traded first |
| `holders` | object | 5 largest holders, or {unavailable} |

#### Daily token volume — GET `/v1/volume`

USD swap volume of a token per UTC day, both sides of every priced swap.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `token` | query | `<evmToken>` |
| `days` | query | `30` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/volume?layer=hyperevm&token=<evmToken>&days=30"
```

| Field | Type | Meaning |
|---|---|---|
| `days[]` | object | {day (UTC ms), volumeUsd, partial?}, oldest first, days with volume |
| `partial` | boolean | the indexed head day, still filling |
| `totalUsd` | decimal | sum over the days |
| `asOf · height` | int | indexed head: every swap up to that block counted |

#### Token families — GET `/v1/token-families`

Tokens whose balance moves without Transfer logs: Aave aTokens and debt tokens, stHYPE, xStocks.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `family` | query | `(empty)`, `aave_atoken`, `aave_vtoken`, `sthype`, `wrapped_shares`, `backed`, `scaling_factor` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/token-families?layer=hyperevm"
```

| Field | Type | Meaning |
|---|---|---|
| `families` | object | tokens per family |
| `tokens[]` | object | {token, family, description, symbol, decimals, params, spam, spamReason} |
| `description` | string | how balanceOf follows from the base the contract keeps |

#### Family token holders — GET `/v1/token-families/{token}`

Holders of one family token with balanceOf at the indexed head.

| Param | In | Example or values |
|---|---|---|
| `token` | path | `0xffaa4a3d97fe9107cef8a3f48c069f577ff76cc1` |
| `layer` | query | `hyperevm` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/token-families/0xffaa4a3d97fe9107cef8a3f48c069f577ff76cc1?layer=hyperevm&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `holders` | int | holders with a positive base |
| `top[]` | object | {address, base, balance, lastBlock} |
| `base · balance` | decimal | what the contract keeps (raw), balanceOf in token units |
| `state · stateBlock` | object · int | token state the formula reads |

#### Spam tokens — GET `/v1/tokens/spam`

Tokens the indexer flags as spam, left out of every list, and the latest flag changes.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/tokens/spam?layer=hyperevm&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `tokens[]` | object | {address, symbol, name, spamReason, spamSince}, newest flag first |
| `spamReason` | string | strongest first: homoglyph:<T>, impostor:<T>, phishing_name, fake_transfers, unreadable_balance, verifier_ignore |
| `changes[]` | object | {token, spam, spamReason, previousReason, changedAt}: flags set, changed or cleared |
| `available` | boolean | false: no spam flags on this layer yet, nothing hidden |

### NFTs

#### Active NFT collections — GET `/v1/nfts/collections`

Collections with the most transfers over the last 1 h or 24 h.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `window` | query | `24h`, `1h` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/collections?layer=hyperevm&window=24h&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `collections[]` | object | {address, standard, name, symbol, transfers, mints, burns, lastBlock} |
| `from · to` | int | window (ms), ends at the indexed head |
| `fromBlock · toBlock` | int | blocks read |

#### NFT collection — GET `/v1/nfts/collections/{address}`

Metadata, tokens seen and 24 h activity of one collection.

| Param | In | Example or values |
|---|---|---|
| `address` | path | `<collection>` |
| `layer` | query | `hyperevm` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/collections/<collection>?layer=hyperevm"
```

| Field | Type | Meaning |
|---|---|---|
| `collection` | object | {address, standard, name, symbol, firstSeenBlock, firstSeenAt} |
| `tokens` | object | {count, capped}: counted up to 1,000 |
| `activity24h` | object | {transfers, mints, burns, lastBlock, fromBlock, toBlock} |

#### Collection tokens — GET `/v1/nfts/tokens`

Tokens of a collection by id, with their owner and metadata URI.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `collection` | query | `<collection>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/tokens?layer=hyperevm&collection=<collection>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `tokens[]` | object | {tokenId, standard, owner, uri, firstSeenBlock, lastTransferBlock} |
| `owner` | string \| null | ERC-721 owner, 0x0 once burnt; null for ERC-1155 |
| `uri · uriLength` | string \| null · int | URI as returned; over 2,048 characters: null + its length |
| `next · after` | string · query | last token id, pass as after for the next page |

#### NFTs of a wallet — GET `/v1/nfts/owned`

ERC-721 tokens owned and ERC-1155 balances of one address.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `owner` | query | `<owner>` |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/owned?layer=hyperevm&owner=<owner>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `erc721 · erc1155` | int | tokens owned, token ids held (counted up to 10,000) |
| `collections[]` | object | {address, name, symbol, erc721, erc1155} |
| `tokens[]` | object | {collection, tokenId, standard, amount, uri} |
| `asOf · height` | int | indexed head the holdings include |

#### NFT transfers — GET `/v1/nfts/transfers`

Transfers of a collection or one token, newest first. While HyperEVM syncs: the last 24 h or 7 d of indexed blocks.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `collection` | query | `<collection>` |
| `tokenId` | query | (optional) |
| `limit` | query | `20` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/nfts/transfers?layer=hyperevm&collection=<collection>&limit=20"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | {block, t, tx, kind, tokenId, amount, from, to, operator} |
| `kind` | mint \| burn \| transfer | from 0x0, to 0x0, else transfer |
| `scope` | all \| 24h \| 7d | whole history, or the block window read |
| `next · before` | string · query | block:log:batch cursor of the next page |

### Bridge & wallet

#### Bridge transfers — GET `/v1/bridges`

HyperCore ↔ HyperEVM transfers (core_evm) or HyperEVM ↔ Elysium movements (evm_elysium), with 24 h stats.

| Param | In | Example or values |
|---|---|---|
| `route` | query | `core_evm`, `evm_elysium` |
| `limit` | query | `50` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/bridges?route=core_evm&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | object | core_evm: status, direction, token, amount, core{…}, evm{…}; evm_elysium: Orbit movement |
| `rows[].bridge_latency_ms` | int \| null | first leg → credited on the other layer |
| `stats` | object | 24 h: count, completed, pending, stuck, latency p50 / p99 per direction |
| `coverageFrom` | object \| null | core_evm: first time each direction is scanned on HyperEVM |
| `tokens · includeSpam · spamHidden` | object · query · int | evm_elysium: parent tokens with spam / spamReason; rows of spam tokens hidden unless includeSpam=true |
| `rows[].matched_by` | nonce \| order \| null | how both legs were paired: nonce = exact (coreReceiveWithData), order = same system address, account and amount, in order; null while unmatched |
| `rows[].final_latency_ms` | int \| null | evm_to_core: HyperEVM leg → the beneficiary credited on HyperCore |
| `rows[].forwarding` | {amount, dex} \| null | a deposit wallet (Circle CoreDepositWallet) forwarded the deposit with CoreWriter sendAsset; dex 0 = main perp dex |
| `rows[].beneficiary` | string \| null | who is finally credited: the account, or a forwarded deposit's recipient; null for a CCTP withdrawal or until resolved |
| `rows[].depositor` | string \| null | who paid on the first layer: the account, or who funded the deposit wallet |
| `rows[].origin · rows[].final` | object \| null | origin: CCTP mint {domain, sender}; final: the HyperCore leg that credits the beneficiary |
| `labels` | object | {address: name} of known addresses in the rows (Circle CctpForwarder: the depositor of every CCTP mint) |
| `cctpDomains` | object | CCTP source domain → chain (0 Ethereum, 1 Avalanche, 2 OP Mainnet, 3 Arbitrum, 5 Solana, 6 Base, 7 Polygon PoS), for origin.domain |

#### Bridge coverage — 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.

| Param | In | Example or values |
|---|---|---|
| `window` | query | `all`, `30d`, `7d`, `24h` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/bridges/coverage?window=all"
```

| Field | Type | Meaning |
|---|---|---|
| `directions.evm_to_core · core_to_evm` | object | {legs, matched, coverage, unmatched: {reason: n}, notALeg, latencyMs: {p50, p90, p99, p999, max}, tokens[]} |
| `coverage` | number | matched / (legs − not legs − in flight): 1 = every settled leg has its other leg |
| `unmatched` | object | in_flight · missing_peer · amount_mismatch · late_peer · unknown_token |
| `core_to_evm.matchedBy` | object | {nonce: exact (coreReceiveWithData), order: same key in order} |
| `unpairedCredits` | object \| null | credits on the receiving side no leg took |
| `source · settledUntil` | string · ms | materialized tables (and how far they are settled) or the views |

#### Bridge stream — WS `bridge.transfers`

Each HyperCore ↔ HyperEVM transfer, initiated then completed.

| Param | In | Example or values |
|---|---|---|
| `token` | filter | (optional) |
| `direction` | filter | `(empty)`, `evm_to_core`, `core_to_evm` |

```json
{"op":"subscribe","channel":"bridge.transfers","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | object[] | last 50 transfers |
| `data` | object | one transfer in its new state (core_evm row shape) |

#### Cross-layer wallet — GET `/v1/wallet/{address}`

One address (or a named wallet's handle) on HyperCore, HyperEVM and Elysium, plus its latest events.

| Param | In | Example or values |
|---|---|---|
| `address` | path | `<owner>` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/wallet/<owner>"
```

| Field | Type | Meaning |
|---|---|---|
| `hyperevm.balances[]` | object | {token, symbol, amount, priceUsd, usd, spam, spamReason, family?} at the indexed head |
| `includeSpam · spamHidden` | query · int | spam tokens out of lists and USD totals unless includeSpam=true |
| `hyperevm.height · asOf` | int | indexed head block and time |
| `hyperevm.nfts` | object | {erc721, erc1155, collections[], tokens[]} held |
| `hyperevm.activity` | object | {scope, swaps, transfers}: its moves are in recent[] |
| `hyperevm.freshness` | object | head, lagMs, blocksBehind, behindMs (as /api/status) |
| `hyperevm.bridges[] · bridges` | object | HyperCore ↔ HyperEVM transfers; legs in flight, journeys |
| `hypercore · elysium` | object | the same address on the other layers |

### Named wallets

#### KOL leaderboard — GET `/v1/kols/leaderboard`

KOLs, traders and funds ranked by their HyperEVM swaps, transfers, bridge legs and holdings.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `window` | query | `24h`, `7d`, `30d` |
| `sort` | query | `volume`, `swaps`, `transfers`, `netBuy`, `holdings`, `bridges`, `lastActivity` |
| `limit` | query | `50` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/leaderboard?layer=hyperevm&window=24h&sort=volume&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[].entity` | {id, name, x, kinds} | who public lists name the wallets |
| `swaps · volumeUsd · netBuyUsd` | int · decimal | DEX swaps sent by its wallets, USD volume, buys − sells |
| `transfersIn · transfersOut · bridges` | int | ERC-20 transfers, bridge legs |
| `holdingsUsd` | decimal \| null | HyperEVM: USD held at the indexed head |
| `scope` | object | blocks read per kind: 24 h without the address indexes (7d / 30d: 503) |

#### KOL moves — GET `/v1/kols/activity`

The latest HyperEVM swaps and transfers of the named wallets, with who moved.

| Param | In | Example or values |
|---|---|---|
| `layer` | query | `hyperevm` |
| `entity` | query | (optional) |
| `minNotional` | query | (optional) |
| `limit` | query | `50` |
| `includeSpam` | query | `(empty)`, `true` |

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/kols/activity?layer=hyperevm&limit=50"
```

| Field | Type | Meaning |
|---|---|---|
| `rows[]` | KolItem | {kind: swap \| transfer, t, wallet, entity, pair, base, side, notional, token, amount} |
| `hash · block · logIndex` | string · int · int | source: the swap / Transfer log |
| `bridges[]` | KolItem | first page: their latest bridge legs (kind bridge) |
| `scope` | object | blocks read per kind |
| `spam · spamReason` | boolean · string | spam tokens hidden unless includeSpam=true |
| `next · before` | string | cursor <block>:<logIndex> of the next page |

#### KOL stream — WS `kol.activity`

Every HyperEVM swap, transfer and bridge leg of a named wallet, on each indexed block.

| Param | In | Example or values |
|---|---|---|
| `layer` | filter | `hyperevm` |
| `kind` | filter | `(empty)`, `swap`, `transfer`, `bridge` |

```json
{"op":"subscribe","channel":"kol.activity","filter":{"layer":"hyperevm"}}
```

| Field | Type | Meaning |
|---|---|---|
| `snapshot: true` | KolItem[] | last 50 moves seen |
| `data` | KolItem | {layer, kind: swap \| transfer \| bridge, wallet, entity, side, notional} |

## Reference

#### Blocks stream — WS `elysium.blocks`

Each new Elysium block header, from our node.

```json
{"op":"subscribe","channel":"elysium.blocks","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {number, hash, parent_hash, timestamp, tx_count, gas_used, base_fee, l1_block_number} |
| `timestamp` | int | block time (s) |

#### Freshness — GET `/v1/status`

Head and lag of each layer, measured now.

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/status"
```

| Field | Type | Meaning |
|---|---|---|
| `layers.hypercore` | object | {state, head, headTime, lagMs} |
| `layers.hyperevm` | object | {state: syncing \| live, head?, headTime?, lagMs?, chainHead?, blocksBehind?, behindMs?, clock?, reason?} |
| `layers.elysium` | object | {state, network, head, headTime, lagMs, chainHead?, blocksBehind?, behindMs?, clock?} |
| `chainHead · blocksBehind · behindMs` | int · int · ms | EVM layers: the node’s own head (pushed), how far our indexed head is behind it; behindMs = how long the next block has waited, on our receive clock (0 = in sync) |
| `stream · flows` | object | our two live feeds: {connected, lagMs} |
| `bridges` | object | HyperCore ↔ HyperEVM matching: {evm_to_core, core_to_evm: {legs, matched, coverage, p50Ms, p99Ms}} |
| `serverTime` | int | server clock (ms) |

#### Check your key — GET `/v1/whoami`

Answers the name your key is registered under, its tier, billing state and the limits in force.

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/whoami"
```

| Field | Type | Meaning |
|---|---|---|
| `key` | string | name of your key |
| `tier` | string \| null | free · builder · pro · scale · enterprise · partner (null: internal key) |
| `billing` | string | ok · exhausted · capped (the last two run at the free row's limits) |
| `limits` | object \| null | {rps, burst, maxConns} in force: REST rate and burst, open WebSockets (null: no limit) |

#### OpenAPI document — GET `/v1/openapi.json`

The OpenAPI 3.1 contract of every REST call, public.

```bash
curl -H "Authorization: Bearer $FEMTOS_KEY" "https://api.femtos.xyz/v1/openapi.json"
```

| Field | Type | Meaning |
|---|---|---|
| `paths` | object | every operation |
| `components.schemas` | object | response shapes |
| `x-websocket.channels` | object[] | WebSocket channels |

#### Stream stats — WS `stats`

Our HyperCore stream health, once a second.

```json
{"op":"subscribe","channel":"stats","filter":{}}
```

| Field | Type | Meaning |
|---|---|---|
| `data` | object | {msgsPerSec, p50, p99 (block → stream, ms), height, books, clients} |
