SOL-slot-block-tps-priority fee-epoch-mainnet

API reference

A read-only indexer for browsing. Writes always go on-chain through the SDK: no endpoint here can move funds.

Conventions

The base URL comes from configuration, not from source: the app reads it from OTC_API_URL on the server and exposes reads through its own cached mirror at /api/public/otc. Responses are bare JSON: an array for collections, an object for a single record. Every u64 is serialised as a decimal string so it survives JSON, and every timestamp is Unix seconds as a number.

TypeScript
const res = await fetch(`${API_URL}/listings?tokenMint=${mint}`);
const listings = await res.json();          // a bare array, no envelope

// Convert at the boundary, once.
const decoded = listings.map((l) => ({
  ...l,
  amount: BigInt(l.amount),
  remainingAmount: BigInt(l.remaining_amount),
  pricePerToken: BigInt(l.price_per_token),
}));

Listings

GET/listings
Resting asks. Each row carries full token and payment-asset metadata, so a card needs no second request.
NameDescription
openOnlyExclude closed, filled and expired orders
tokenMintFilter by token mint
quoteMintFilter by payment mint
verifiedOnlyOnly mints the indexer has verified
excludeFreezableDrop mints that hold a freeze authority
minPrice / maxPricePrice per whole token, base units
minSizeMinimum remaining size, base units
sortprice, size, created or expiry
orderasc or desc. Asks read best-first as asc
limitPage size
Example response
200 OK
[
  {
    "address": "7Yq3nDkKCk6bPZ1sVJ8mUuA2rXoT4hLdWc5FgEsRk3Np",
    "seller": "5xoT4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA2",
    "token": {
      "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
      "symbol": "BONK",
      "name": "Bonk",
      "decimals": 5,
      "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
      "logo_uri": "https://arweave.net/hQiPZOsRZXGXBJd_82PhVdlM_hACsT_q6wqwf5cSY1I",
      "price_usd": "0.0000214",
      "liquidity_usd": "8412000",
      "token_verified": true
    },
    "quote_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "quote_symbol": "USDC",
    "quote_decimals": 6,
    "quote_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    "price_per_token": "20800",
    "pricing_kind": "fixed",
    "amount": "1000000000",
    "remaining_amount": "640000000",
    "min_fill_amount": "1000000",
    "expiry_ts": 1772150400,
    "allowed_buyer": null,
    "created_ts": 1772063991,
    "closed": false,
    "seller_trades_completed": 12,
    "seller_volume_usd": "184320"
  }
]

GET /listings/{address} returns a single ask, with its fills array attached.

Bids

GET/bids
Resting bids, same parameters as listings. Default sort is price descending, because the best bid is the highest one.
NameDescription
tokenMintFilter by token mint
quoteMintFilter by payment mint
sortprice, size, created or expiry
orderasc or desc. Bids read best-first as desc
limitPage size
Example response
200 OK
[
  {
    "address": "3Np7Yq3nDkKCk6bPZ1sVJ8mUuA2rXoT4hLdWc5FgEsRk",
    "buyer": "9rXoT4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA",
    "token": { "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", "symbol": "BONK", "decimals": 5 },
    "quote_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "quote_symbol": "USDC",
    "quote_decimals": 6,
    "price_per_token": "20800",
    "pricing_kind": "fixed",
    "quote_amount": "1005000000",
    "remaining_quote_amount": "1005000000",
    "remaining_token_capacity": "4807692307",
    "min_fill_amount": "10000000",
    "expiry_ts": 1772150400,
    "allowed_seller": null,
    "created_ts": 1772063800,
    "closed": false
  }
]

GET /bids/{address} returns a single bid with its fills array.

Token summary

GET/tokens/{mint}
Traded volume, VWAP, last traded price and open interest for one mint. This is the data behind a token block in the app. Traded statistics derive only from executed fills, so resting orders never average into a price.
Example response
200 OK
{
  "token": {
    "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
    "symbol": "BONK",
    "decimals": 5,
    "price_usd": "0.0000214"
  },
  "volume_usd": "912400",
  "vwap_usd": "0.0000209",
  "best_ask_price": "20800",
  "best_ask_quote_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "best_bid_price": "20150",
  "best_bid_quote_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "open_listings": 14,
  "open_bids": 6
}

Token book

GET/tokens/{mint}/book
Best bid, best ask and the spread, one entry per payment asset. Use it for a header quote without pulling both order lists.

Impersonations

GET/tokens/impersonations
Unverified mints using a symbol that a verified mint already claims. Ticker collisions are free to create on Solana, so match on the mint address and never on the symbol.

Treasury

GET/treasury
What the protocol has accrued, per mint and per side. Half of every fee is taken in the traded token, so this is the only place token-side balances are visible.

Price series

GET/tokens/{mint}/prices/{quoteMint}
Time-bucketed price points built from executed fills only, oldest first. One series per token and payment-asset pair.
Example response
200 OK
[
  { "ts": 1772060400, "price": "20950", "volume": "1840000000" },
  { "ts": 1772064000, "price": "20800", "volume": "640000000" }
]

Fills

GET/fills
Settled trades, newest first, both sides mixed. Read side on every row: 0 is a fill against an ask, 1 against a bid. It drives the row label and which order page you link to.
NameDescription
side0 for asks, 1 for bids. Omit for both
tokenMintFilter by token mint
orderFills against one ask or bid address
walletFills where this wallet was either side
limitPage size
Example response
200 OK
[
  {
    "signature": "4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA2rXoT4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA2rXoT",
    "side": 0,
    "order": "7Yq3nDkKCk6bPZ1sVJ8mUuA2rXoT4hLdWc5FgEsRk3Np",
    "buyer": "9rXoT4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA",
    "seller": "5xoT4hLdWc5FgEsRk3Np7Yq3nDkKCk6bPZ1sVJ8mUuA2",
    "amount": "360000000",
    "quote_amount": "74880000",
    "quote_symbol": "USDC",
    "ts": 1772063991
  }
]

Venue stats

GET/stats
Venue totals: settled volume, largest single trade, price impact avoided and the number of open asks.
Example response
200 OK
{
  "volume_usd": "4182400",
  "largest_trade_usd": "184320",
  "impact_saved_usd": "212900",
  "open_listings": 148
}

Health

GET/health
Indexer liveness. lastSlot is a decimal string because slots outgrow a safe JS integer, and staleAfterSeconds is the cutoff the indexer itself considers stale.
Example response
200 OK
{
  "ok": true,
  "indexer": {
    "lastSlot": "312884473",
    "lagSeconds": 0.8,
    "staleAfterSeconds": 240
  }
}