Skip to content
bankhood.

Integrations & API

REST and WebSocket endpoints exposed by the indexer, with example payloads.

The indexer exposes a small read-only API over the contract events. It is not deployed yet, so every endpoint below currently corresponds to a typed mock module in the interface repository with an identical response shape.

Base URL and conventions

PropertyValue
Base URLhttps://api.bankhood.xyz
AuthNone. All endpoints are public and read-only.
Rate limit60 requests per minute per IP
Paginationlimit (max 100) and cursor query parameters
TimestampsISO 8601 in UTC
AmountsDecimal strings, pre-scaled for display
ErrorsRFC 7807 problem+json

Amounts are returned as strings rather than numbers so that share counts with eighteen decimals survive JSON parsing intact.

GET /v1/reserve

Protocol-level totals. This is the endpoint behind the landing page stat strip and the explorer header.

200 OK — pre-launch
{
  "status": "pre-launch",
  "totalFeesEth": "0",
  "hoodShares": "0",
  "hoodCostBasisUsd": "0",
  "holders": 0,
  "distributions": 0,
  "uniqueClaimers": 0,
  "lastIndexedBlock": null,
  "nextDistributionAt": null
}

status is one of pre-launch, live or paused. It flips to live on the first indexed FeeCollected event.

GET /v1/fees

Individual fee payments, newest first.

200 OK — shape
{
  "data": [
    {
      "id": "18990421-42",
      "txHash": "0x…",
      "block": 18990421,
      "timestamp": "2026-07-25T14:02:11Z",
      "payer": "0x…",
      "side": "buy",
      "notionalEth": "1.000000",
      "feeEth": "0.030000",
      "status": "confirmed"
    }
  ],
  "cursor": null
}

GET /v1/distributions

Settled batches: ETH converted, shares acquired, average fill price and the number of holders credited.

200 OK — shape
{
  "data": [
    {
      "id": "0x8f2c…",
      "txHash": "0x…",
      "block": 18990455,
      "timestamp": "2026-07-25T14:31:04Z",
      "ethRouted": "0.262000",
      "hoodShares": "8.610000",
      "avgFillPrice": "94.88",
      "recipients": 1284,
      "status": "confirmed"
    }
  ],
  "cursor": null
}

GET /v1/claims/:address

Claim history for one address. Omit the address segment to get the global claim feed.

request
curl -s "https://api.bankhood.xyz/v1/claims/0xYourAddress?limit=20" \
  -H "accept: application/json"
200 OK — shape
{
  "data": [
    {
      "id": "1753452664000",
      "txHash": "0x…",
      "block": 18990512,
      "timestamp": "2026-07-25T14:51:04Z",
      "recipient": "0x…",
      "hoodShares": "0.043050",
      "valueUsd": "4.09",
      "status": "confirmed"
    }
  ],
  "cursor": null
}

WebSocket stream

A single multiplexed socket pushes the same events the REST endpoints expose, for interfaces that want live updates without polling.

subscribe
const socket = new WebSocket("wss://api.bankhood.xyz/v1/stream");

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    op: "subscribe",
    channels: ["fees", "distributions", "claims"],
    // optional: only claims for one address
    address: "0xYourAddress",
  }));
});

socket.addEventListener("message", (event) => {
  const { channel, data } = JSON.parse(event.data);
  // channel: "fees" | "distributions" | "claims" | "reserve"
});
ChannelPushes
feesOne message per indexed FeeCollected event
distributionsOne message per FillReported event
claimsOne message per Claimed event, filterable by address
reserveTotals snapshot, at most once every 300 seconds

Local mock modules

Until the indexer exists, the interface reads these modules. Each exports the same shape as its endpoint, so replacing one is a single change at the call site.

ModuleReplacesCurrently returns
lib/mock/reserve.tsGET /v1/reserveGenesis snapshot, all zeros
lib/mock/explorer.tsfees, distributions, claimsEmpty arrays
lib/mock/position.tsbalanceOf and claimable readsDeterministic simulated position

Swapping one out

lib/mock/explorer.ts
-export async function getFeePayments(): Promise<FeePayment[]> {
-  return feePayments;
-}
+export async function getFeePayments(): Promise<FeePayment[]> {
+  const res = await fetch(`${API_BASE}/v1/fees?limit=50`, {
+    next: { revalidate: 15 },
+  });
+  const { data } = await res.json();
+  return data;
+}