Skip to main content
This guide walks through a complete trading terminal, pane by pane: the discovery columns, the trending tab, the search bar, a token page with a live chart, a live tape and due-diligence panels, a watchlist and a portfolio view. Every pane maps to one or two endpoints, every payload shown here is the real shape, and everything works identically on all 18 EVM chains and Solana: build the page once, ship it everywhere.
Every endpoint page in this doc has an interactive playground that runs live without a key: open one and hit Send to see the full response next to the code below.

Ground rules

Three conventions carry the whole build:
  • Auth is one header, Authorization: YOUR_API_KEY, on every call.
  • Every response is { data, meta }, camelCase, millisecond timestamps, and null always means unknown, never a fabricated zero.
  • Chains are evm:<id> (evm:8453 for Base, evm:1 for Ethereum) or solana; a token is always (chain, address).
One helper is all the plumbing you need:
lib/serialized.ts
Errors are machine-readable (INVALID_PARAM, NOT_FOUND, RATE_LIMITED, the full catalog), and you are only billed for 2xx responses: your own errors never cost credits.

The discovery columns

The three launchpad lifecycle columns every terminal opens on are one endpoint, one call per column: view=new (created under 24h), view=bonding (active curves, sorted by bonding progress), view=graduated (migrated in the last 7 days). Around 90 launchpads are tracked natively across chains, and EVM and Solana merge in a single call: list the chains you want in chains and the feed comes back ranked.
discovery.ts
Each card already carries everything the column renders: identity and metadata (icon on our CDN, socials, dexPaid), live figures over the view window (priceChangePct, volumeUsd, txns, buys, sells), feesUsd since the pool’s creation, marketCapUsd, liquidityUsd, bondingProgress, migrated, ageSeconds, and the creator wallet with its display name when known. No second call per row. For sub-second discovery, make the columns live instead of polled: subscribe token-updates on the cards currently on screen (more on the stream below). Discovery beyond launchpads is GET /v1/screener: every tradable market, ranked and paginated. sortBy=trending (the default) weighs 24h activity by real participation, so wash-traded markets sink; sortBy=volume with window=5m|1h|6h|24h gives you the “top last hour” tab; sortBy=createdAt is the new-markets firehose.
Every row is chart-ready: price, market cap, liquidity, and a stats object with the 5m/1h/6h/24h windows (volume, buys, sells, price change), so the whole trending table is one call. One endpoint handles both things users paste into a terminal: an exact address (token or pool, EVM hex or Solana base58) and free text on name or symbol. Leave chain out and it searches EVM and Solana in parallel, merged by USD liquidity, so the search bar is chain-agnostic by default.
Debounce it (say 300 ms) and route straight to the token page on an exact address hit.

The token page

The header

Two calls fill the whole top of the page. GET /v1/token is the snapshot: price (native and USD), market cap, FDV, liquidity, supplies, the token’s main pool, launchpad state (bondingProgress, graduatedAt), deployer, socials and icon, plus stats24h. GET /v1/token/stats adds the windowed row of every terminal header: 5m / 1h / 4h / 6h / 24h, each with volume, buys/sells split and price change, in one call.
token-page.ts

The chart

GET /v1/token/ohlcv serves chart-ready candles from 1s to 1M, up to 2000 per page. Two behaviors matter for a terminal chart:
  • The series survives graduation. By default candles follow the pool the token is priced from, with the bonding-curve history stitched in front: a token that migrated from Pump.fun or a Virtuals curve draws one continuous line, no gap at migration, nothing to handle on your side.
  • The axis is dense. Every bucket is present; a quiet bucket is a flat zero-volume candle at the previous close, so thin tokens still draw a proper chart.
Candles drop straight into a TradingView datafeed: time is unix seconds, intervals use the same keys (aliases like 1min and 60 are accepted), and paging backwards is endTime plus meta.hasMore:
datafeed.ts
Prices are native-quoted by default. On Solana pass quote=usd for USD candles; on EVM multiply by the native USD spot from GET /v1/prices/native, one cached call for all your charts. For the complete TradingView wiring (resolveSymbol, the microcap pricescale trick, live bars, Lightweight Charts), see TradingView Charts.

The tape

GET /v1/token/trades seeds the tape: token-wide by default, newest first, cursor pagination for infinite scroll (meta.nextCursor until hasMore is false). Each row is ready to render (trimmed here):
maker is the wallet actually trading, resolved through relays, solvers and smart accounts, with isProTrader / isSniper badges on every row and isWash on Solana: the tape is attribution-correct out of the box. Filters cover side, trade size, date range and maker lists when you add tape controls.

The side panels

The due-diligence column is three endpoints, one call each, same shape on EVM and Solana:
  • /v1/token/holders: top holders with share of supply, full PnL, behavioral labels and named entities (the “Coinbase” row), plus meta.totalHolders for the header count.
  • /v1/token/top-traders: ranked PnL leaderboard, lifetime or any rolling window from 1h to 30d, with win rate and dev/sniper/pro badges.
  • /v1/token/security: the pre-trade checklist in one shape: mint/freeze authorities, top-10 concentration (exchange custody excluded), dev/sniper/bundler holdings, LP burn/lock, taxes, dexPaid.
Add /v1/token/pools for the market selector: rank 1 is the exact pool the terminal is pricing from, the rest ranked by 24h volume, each with its own stats.

Make it live

Everything above renders a page; one WebSocket makes it move. Open a single connection for the whole app, authenticate, then attach subscriptions per pane as the user navigates: events reuse the exact REST shapes, so the parsing code you just wrote handles the stream unchanged.
stream.ts
How each pane goes live:
  • Header: token-updates pushes the mutable fields of /v1/token (price, market cap, liquidity, bonding progress, stats24h), throttled to one event per second per token. Patch them over the snapshot.
  • Tape: trades events are the exact tape row above. Prepend, and dedup by id.
  • Chart: fold each trade into the forming candle (bucket = floor(at / 1000 / intervalSec) * intervalSec; new bucket opens at the previous close).
  • Discovery / watchlist rows: one token-updates subscription per visible card; unsubscribe by id as rows scroll out, the connection stays.
Two production patterns:
  • Reconnect: delivery is at-most-once, so on reconnect re-subscribe, then backfill the gap with GET /v1/token/trades?fromAt=<last event at> and dedup by id. The tape never misses or doubles a trade.
  • Cost control: every subscription accepts maxUpdatesPerMinute, which caps delivered events (you always get the latest state) and therefore cost. Streams bill 1 credit per event actually delivered, the connection itself is free.
Per key you have 10 concurrent connections, 50 subscriptions per connection and 100 distinct tokens across channels, raised on request: one connection per browser tab is the comfortable pattern.

The watchlist

Batch twins keep pinned lists at one round-trip per refresh, whatever the size: POST /v1/token serves up to 25 full snapshots per call, EVM and Solana mixed freely, per-item error slots so one dead token never breaks the list. POST /v1/token/sparklines draws the row charts: up to 100 tokens per call, best pool resolved for you, curve history stitched so freshly graduated tokens draw one continuous line.

The portfolio tab

GET /v1/wallet/positions is the whole holdings screen in one call: every position with amount, live USD value, average entry, realized + unrealized + total PnL and holdingSince, plus meta.summary for the wallet-level totals at the top. Add includeNative=true&includeStables=true and the SOL/ETH and stablecoin rows are read on-chain at request time, so the total is the real account value.
GET /v1/wallet/pnl draws the performance curve (daily realized PnL with win rate, any period up to all), and /v1/wallet/closed-positions fills the trade-history tab with every completed round trip.

What a session costs

Credits map one-to-one to the calls above, so a terminal’s burn is easy to model before you ship it: Only 2xx responses are billed, batches bill per item, and every billable response carries X-Credits-Remaining so your backend can watch its own burn. Plans and rate limits are on Authentication & Limits.

Ship it

You never built the hard parts: trader attribution through relays and solvers, candle continuity across launchpad migrations, a registry of ~90 launchpads, wash and sniper detection, USD conversion, icon hosting. That is the point: the panes above are the product, the pipeline behind them is ours.

Get a key

Create an account, add a card to unlock 100,000 free credits, and create your key in the portal.

Migrate an existing terminal

Endpoint-by-endpoint maps from Mobula, Codex and Birdeye.

Streams reference

Auth, limits, reconnect semantics, billing.

Conventions

Envelope, chain ids, null semantics, timestamps.