# AI Integration Source: https://docs.solanatracker.io/ai Use Solana Tracker documentation with AI assistants like Cursor, ChatGPT, and Claude — copy markdown, paste prompts, and connect via MCP and llms.txt. Solana Tracker documentation is fully available for AI consumption. Whether you're building AI agents, using LLM-powered coding assistants, or just want quick answers — we've got you covered. *** ## LLM-Ready Documentation We provide machine-readable versions of our entire documentation for use with AI models, agents, and tools like Cursor, Claude Code, Claude, ChatGPT, and more. Lightweight summary of all endpoints, parameters, and resources. Ideal for context-limited models. Complete documentation in plain text. Best when you need full detail and have a large context window. ### When to use which | File | Size | Best for | | - | - | - | | `llms.txt` | Compact | Quick lookups, smaller context windows, coding assistants | | `llms-full.txt` | Full | Deep integration work, building agents, comprehensive reference | *** ## AI Chatbot Every page on this documentation site includes an **AI-powered search and chat** built right in. Click the search bar or press `⌘K` to ask questions like: * *"How do I get the price of a token?"* * *"What parameters does the swap endpoint accept?"* * *"Show me how to stream new tokens via WebSocket"* The chatbot has full context of all Solana Tracker APIs — Data API, Swap API, Datastream, Solana RPC, and Yellowstone gRPC. *** ## Use with AI Coding Assistants ### Cursor / Claude Code Add the documentation as context by referencing the URL directly: ``` https://docs.solanatracker.io/llms-full.txt ``` Or add it to your project's AI instructions or system prompt: ``` Use https://docs.solanatracker.io/llms.txt as reference for all Solana Tracker API calls. ``` ### ChatGPT / Claude Paste the contents of `llms.txt` or `llms-full.txt` into your conversation, or provide the URL when using web-enabled models. ### Custom AI Agents Fetch the documentation programmatically for your agent's knowledge base: ```bash theme={null} curl -s https://docs.solanatracker.io/llms.txt ``` ```bash theme={null} curl -s https://docs.solanatracker.io/llms-full.txt ``` Cache these files locally when possible. Do not fetch them on every prompt or every tool call. *** ## What's Included Both files cover the full Solana Tracker API surface: * **Data API** — Token prices, holders, trades, chart data, stats, and more * **Swap API** — Quote and execute swaps across Solana DEXs * **Raptor DEX Aggregator** — Next-gen swap routing * **Datastream** — Real-time WebSocket streams for tokens, wallets, and events * **Solana RPC** — Standard and custom RPC methods * **Yellowstone gRPC** — High-performance Geyser streaming # Changelog Source: https://docs.solanatracker.io/changelog New features, improvements, and fixes across Solana Tracker.
Latest release 2026 updates 2025 archive
October 8, 2026
New Raptor Swap API
## Raptor V1: 71 DEXes, JIT routing, and out of beta Raptor V1 is live on mainnet. It adds 47 DEXes and JIT routing, and the hosted API has a new address. * **47 new DEXes.** Raptor now routes across 71, including MetaDAO, Hylo, Sanctum, JupLend, Solayer and Invariant. See the [full list](/raptor/overview#supported-dexs). * **JIT routing, on by default.** A JIT swap carries several candidate pools and chooses between them on-chain when it executes, using live prices. `minAmountOut` is still enforced. Set `jitRouting` to `true` or `false` to force it on or off. * **Token-2022 transfer fees in the quote.** If a token charges a transfer fee, the quote includes `tokenTransfers` with `depositFee`, `deliveryFee` and `netOutput`. * **Error codes.** No route now returns `422` instead of `500`, and an invalid amount returns `400`. Both are JSON. ### Update your base URL The hosted API moved from `raptor-beta.solanatracker.io` to `raptor.solanatracker.io`. Change the base URL in your code. The program ID is still `RaptorD5ojtsqDDtJeRsunPLg6GvLYNnwKJWxYE4m87`. ```diff theme={null} - https://raptor-beta.solanatracker.io + https://raptor.solanatracker.io ```
September 18, 2026
New Data API Datastream
## Swaps, LP moves, and wallet labels in one feed Track buys and sells alongside LP adds and removes. See which wallets are adding liquidity, which are pulling it, and where it all lands in your trade feed.
Updated trade feed with All, Swaps, and Liquidity tabs, green LP adds, red LP removes, and wallet labels.

After: swaps and LP activity in one feed, with wallet labels and All / Swaps / Liquidity filters.

Previous trade feed showing buys and sells with shortened wallet addresses.

Before: a swaps-only feed with wallet addresses.

* **Stream LP moves.** Five new liquidity room scopes: token, token + pool, token + pool + wallet, pool, or wallet. * **Build All / Swaps / Liquidity tabs.** Query `events=all`, `events=trades`, or `events=liquidity` on all four token trade endpoints. Set `limit` to load up to 500 rows per page. * **Put a name to the wallet.** Use `enrich=identity` on REST or `:enriched` on live rooms for available KOL profiles, dev labels, SNS names, and trading platforms. * **Keep LP amounts exact.** Adds and removes include the pool and each token's amount as a decimal string. Liquidity stays in token units, separate from swap volume. ```http theme={null} GET /trades/{token}?events=all&enrich=identity&limit=100 ``` ```json theme={null} { "type": "join", "room": "liquidity:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN:enriched" } ``` Load the history with REST, then keep the feed moving with Datastream. Existing trade requests and rooms remain swaps-only by default. Live LP events are provisional; use REST to reconcile confirmed activity. ### Changed endpoints and rooms

REST · Trade history

Datastream · Live liquidity

Build your LP activity feed →
2026
September 7–16, 2026
Data API Datastream Solana RPC PnL V2 General

Platform speed, Search API, RidgeDB, and dashboard updates

### Faster data, from indexing to delivery * **Search and holders:** faster Search API responses and improved holder data performance. * **Token coverage:** support for all quote tokens on Meteora Curve, Raydium LaunchLab, and Pump.fun, plus Pump.fun `isHolderReward` and Transaction V1 support. * **Indexing and streaming:** rebuilt metadata indexing, RidgeDB, and Ridge streaming for improved speed, accuracy, and efficiency across Data API and RPC services. * **PnL V2:** improved redundancy and accuracy. ### More ways to manage your subscription * **Teams:** invite teammates and manage their access on Premium, Business, and dedicated node plans. * **On-chain USDC subscriptions:** automatic renewals and top-ups using native USDC on Solana.
August 2026
Data API

See what is moving across Solana memecoin markets

Lighthouse gives you a live view of activity across Solana launchpads and DEXs. * See buys, sells, traders, volume, new token launches, and migrations * Track activity over `5m`, `1h`, `6h`, and `24h` * Compare each period with the one before it * Build memecoin dashboards and “what is moving now?” pages with `GET /lighthouse`
Lighthouse guide↗ API reference↗
August 2026
Data API Datastream

See what whales and KOLs are trading as it happens

Know when high-value wallets move. New REST endpoints and Datastream rooms make it easy to follow whale activity, track KOL trades, power token pages, and trigger alerts from a single trade feed. * **REST endpoints:** Fetch the latest whale trades, all KOL trades, or KOL activity for a specific token. * **Live Datastream rooms:** Subscribe to whale and KOL trades as they happen. * **Flexible volume filters:** Watch trades from `$1k` to `$10k`, or request all eligible KOL trades with `minVolume=0`. * **KOL identity:** Show names, Twitter handles, and other identity metadata when available. * **More context when you need it:** Paginate with opaque cursors, add token metadata, and filter arbitrage activity when needed.
Whale & KOL guide↗ REST API reference↗ Datastream reference↗
August 2026
Prediction Markets Datastream

Beta Prediction Markets API for Kalshi and Polymarket

Unified read-only API for **Kalshi** and **Polymarket** with full historical market data. * **REST:** `https://prediction-market-api.solanatracker.io` * **Datastream:** `pm:*` rooms on `wss://datastream.solanatracker.io/{apiKey}` (same hub and key as other Datastream products) * Markets, events, trades, candlesticks, orderbooks, crypto up/down windows, and Polymarket wallet analytics * Auth with your existing Data API key (`x-api-key`)
Overview↗ Getting started↗ Datastream guide↗
July 2026
PnL V2

Currency denomination (SOL/EUR) and performance trade-count fix

### Currency query parameter `GET /v2/pnl/wallets/:wallet`, `/history`, and `/performance` now accept `?currency=usd|sol|eur` (default `usd`). * Pass `sol` or `eur` to convert USD snapshot values at read time using historical token prices. * Response includes top-level `"currency": "sol"` or `"currency": "eur"` when requested. * Historical endpoints convert per day; wallet summary uses current spot. * Counts, percentages, timestamps, and ROI are not converted. * Invalid currency returns **400**: `{ "error": "Invalid currency. Options: usd, sol, eur" }`. ```http theme={null} GET /v2/pnl/wallets/{wallet}?currency=sol GET /v2/pnl/wallets/{wallet}/history?period=30d¤cy=eur GET /v2/pnl/wallets/{wallet}/performance?period=30d¤cy=sol ``` ### Performance trade counts fixed `totals.trades` and per-day `trades` on `/performance` now count **daily activity within the window** (`day_buys + day_sells`) instead of summing cumulative lifetime snapshot totals. Trade counts should now align with wallet summary lifetime trades when summed over the full trading history.
PnL V2 overview↗ Wallet analysis guide↗
July 2026
Datastream

Meteora DLMM and Raydium CLMM pool monitors improved for new pool creations

Meteora DLMM and Raydium CLMM pool monitors have been improved for new pool creations.
June 2026
Data API Datastream

Jupiter DCA V2 — full support and indexing for recurring orders

Jupiter DCA V2 orders (`openDcaV2`) are now fully supported and indexed across the DCA API and Datastream feeds. Previously hidden DCA V2 positions are now visible in REST responses and live WebSocket events. Existing `/dca/*` endpoints and `dca:jupiter` rooms automatically include V2 orders — no query changes required. Order objects include `openInstruction: "openDcaV2"` to distinguish V2 accounts.
Jupiter DCA API↗ Jupiter DCA Datastream↗
June 2026
Solana RPC

Ridge custom RPC — Address Lookup Tables & SNS Domains

Eight new Ridge DB-powered RPC methods for address lookup table queries and Solana Name Service (`.sol`) resolution. Each method costs **1 credit** per call. ### Address Lookup Tables * **`getLookupTablesByAuthority`** — LUTs owned by a wallet authority * **`getLookupTablesByAccount`** — LUTs containing a specific account * **`getLookupTablesByMint`** — LUTs containing a token mint * **`getLookupTablesByAccounts`** — LUTs containing all listed accounts, or a minimal LUT set with `bestSet: true` ### SNS Domains * **`getPrimaryDomain`** — Primary `.sol` domain for a wallet * **`getMultiplePrimaryDomains`** — Batch primary domains (up to 100 wallets) * **`getAllDomains`** — All `.sol` names owned by a wallet * **`resolveSolDomain`** — Forward resolution: `name.sol` → owner ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getPrimaryDomain", "params": ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] } ``` Resolve SNS identity and find LUTs for transaction compression in a single RPC call — no need to chain `getAccountInfo` / `getMultipleAccounts`.
Address Lookup Tables↗ SNS Domains↗ Credits and rate limits↗
June 2026
PnL V2

Wallet identity: SNS primary `.sol` domain tag

Wallet `identity` now includes an optional **`sns`** tag and **`identity.sns.domain`**, the wallet's primary **`.sol` domain** (Solana Name Service). Returned on all `/v2/pnl/*` responses that include `identity`, plus `GET /tokens/:tokenAddress/holders?enrich=identity` (and `?enrich=all`).
PnL V2 SNS primary domain guide↗ Solana Wallet Tags guide↗
May 2026
Data API

Search — Coin Communities filters, sorting, and response fields

**`GET /search`** now includes Coin Communities live message activity. ### New query parameters * **`hasCoinCommunity`** — Filter tokens with or without monitored community messages (`true` / `false`) * **`minCommunityMessages`** / **`maxCommunityMessages`** — Filter by live message count range (inclusive) ### Sorting * **`sortBy=communityMessages`** — Sort by live community message count (use with `sortOrder=asc` or `desc`) ### Response fields Each result now includes **`hasCoinCommunity`** (`boolean`) and **`communityMessages`** (`integer`).
Search — Coin Communities guide↗ Search API reference↗
May 2026
Data API Datastream

Jupiter DCA — recurring order REST API and live WebSocket feeds

### Jupiter DCA Track Jupiter recurring (DCA) orders on Solana: query live positions over REST and subscribe to open, fill, close, deposit, withdraw, fee, and position updates over Datastream. Jupiter is available today (`program=jupiter`); responses include a `program` id for when more platforms are added. ### Data API New endpoints under `/dca/*`. Full reference: [Jupiter DCA](/data-api/dca). * **`GET /dca/programs`** — List supported DCA programs (`id`, `label`, `programId`) * **`GET /dca/wallet/{wallet}`** — All DCA orders for a wallet with status summary * **`GET /dca/wallet/{wallet}/orders`** — Paginated wallet orders (`cursor`, `sort`, `status`, `program`) * **`GET /dca/order/{address}`** — Single DCA account by pubkey * **`GET /dca/token/{mint}`** — Token buy/sell flow overview * **`GET /dca/token/{mint}/buyers`** — Orders buying this token (output mint) * **`GET /dca/token/{mint}/sellers`** — Orders selling this token (input mint) * **`GET /dca/token/{mint}/users`** — Top wallets by DCA activity on this token * **`GET /dca/pair/{inputMint}/{outputMint}`** — Orders for a trading pair Query helpers: `program` (aliases `dex`, `platform`), `limit`, `cursor`, `sort` / `sortBy` (`volume`, `deposited`, `remaining`, `progress`, `recent`, `created`, `status`), and `status` (`active`, `paused`, `completed`, `pending`, `all`). Orders include USD fields when price data is available. ### Live Jupiter DCA streams New WebSocket rooms on Premium, Business, and Enterprise plans. Reference: [Jupiter DCA Datastream](/datastream/dca). Join with `{ "type": "join", "room": "" }`. Each event is delivered to the global room, the matching event-type room, and any scoped rooms that apply. | Room | Use | | - | - | | **`dca:jupiter`** | All Jupiter DCA events | | **`dca:jupiter:opened`** | New DCA opened | | **`dca:jupiter:filled`** | Cycle fill | | **`dca:jupiter:closed`** | DCA closed | | **`dca:jupiter:deposit`** | Deposit | | **`dca:jupiter:withdraw`** | Withdraw | | **`dca:jupiter:collected_fee`** | Fee collected | | **`dca:jupiter:position`** | Account snapshot (no `eventName`) | | **`dca:jupiter:{mint}:buyers`** | DCAs buying this token | | **`dca:jupiter:{mint}:sellers`** | DCAs selling this token | | **`dca:jupiter:wallet:{wallet}`** | Any event for that owner | | **`dca:jupiter:{dcaAddress}`** | Any event for that DCA account | Transaction events include a full **`order`** object (same shape as REST). Position updates include **`order`** and **`writeVersion`**.
May 2026
Data API PnL V2

PnL V2 fuller responses, faster trending & volume endpoints, and improved search

### PnL V2 API * **`GET /v2/pnl/wallets/{wallet}/positions`** and **`GET /v2/pnl/tokens/{mint}/traders`** now return the full available data set (not a reduced field subset). * **Average hold time** added to the wallet PnL summary (`GET /v2/pnl/wallets/{wallet}`). * General PnL V2 bug fixes. ### Performance * **Up to 10× faster in the EU** and **up to 20× faster in the US** for: * **`/tokens/trending/*`** * **`/tokens/volume/*`** * **`/top-performers`** * **`/tokens/multi/all`** * **Improved spam token filtering** on trending, volume, and top performers for more accurate lists. * **Faster live holder count updates.** ### Search * **Better results** when queries contain special characters such as `-` and `"`.
May 2026
Data API PnL V2

Expanded holder token PnL enrichment; legacy PnL endpoints now powered by PnL V2

### Holder token PnL enrichment When you call `/tokens/:tokenAddress/holders` with `?enrich=walletPnl` or `?enrich=all`, the `pnl.token` object now returns full position detail for that mint — not just `realized`, `unrealized`, and `total`. New fields include trade counts (`buys`, `sells`, `totalTrades`), ROI, position size (`balance`, `costBasis`, `value`, `price`), volume (`totalBought`, `totalSold`, `avgBuy`, `avgSell`), and timing (`firstBuy`, `lastBuy`, `firstSell`, `lastSell`, `firstTrade`, `lastTrade`). ### Legacy PnL endpoints use PnL V2 data The deprecated PnL endpoints now read from the PnL V2 engine under the hood. Request paths and response shapes are unchanged, but the underlying numbers match `/v2/pnl/*`. * **`GET /pnl/{wallet}`** — wallet PnL across all positions * **`GET /pnl/{wallet}/{token}`** — wallet PnL for one token * **`GET /first-buyers/{token}`** — first 100 buyers with PnL * **`GET /top-traders/all`** and **`GET /top-traders/all/{page}`** — top traders across all tokens * **`GET /top-traders/{token}`** — top traders for one token We still recommend migrating to the PnL V2 endpoints for richer fields, sorting, filters, wallet labels, and batch lookups. See the [PnL V2 overview](/guides/pnl-v2/overview).
May 2026
Data API Datastream PnL V2

PnL V2 launch: wallet profit/loss, trader lists, wallet labels, and live PnL streams

### PnL V2 API PnL means profit and loss. PnL V2 adds new endpoints under `/v2/pnl/*` so you can see how wallets and traders are doing. PnL V2 chart showing wallet profit and loss over time #### Wallet PnL Use these endpoints when you want to study one wallet: * **`GET /v2/pnl/wallets/:wallet`** — Shows the wallet's total profit/loss, ROI, win rate, and trade counts. * **`GET /v2/pnl/wallets/:wallet/positions`** — Lists every token position for the wallet. You can sort and filter the list. * **`GET /v2/pnl/wallets/:wallet/tokens/:token`** — Shows one wallet's history with one token. * **`GET /v2/pnl/wallets/:wallet/history`** — Shows daily PnL over time. * **`GET /v2/pnl/wallets/:wallet/performance`** — Shows best day, worst day, streaks, drawdown, and daily totals. * **`GET /v2/pnl/wallets/:wallet/highlights`** — Shows the biggest wins, losses, bags, flips, and most active tokens. * **`GET /v2/pnl/wallets/:wallet/risk`** — Shows where the wallet is most exposed. * **`GET /v2/pnl/wallets/:wallet/chart`** — Gives chart points ready to draw. #### Token PnL Use these endpoints when you want to study one token: * **`GET /v2/pnl/tokens/:token/traders`** — Lists wallets that traded the token. It shows PnL for this token and lifetime wallet PnL. * **`GET /v2/pnl/tokens/:token/first-buyers`** — Lists the earliest buyers first. Use `/traders` if you need sorting by ROI, PnL, size, or latest trade. #### Leaderboards Use these endpoints to rank wallets: * **`GET /v2/pnl/leaderboard/top`** — Ranks top Solana traders for `1`, `7`, `30`, or `90` days. * **`GET /v2/pnl/leaderboard/kols`** — Ranks tracked KOL wallets for all time. * **`GET /v2/pnl/leaderboard/kols/period`** — Ranks KOL wallets for a time range. * **`GET /v2/pnl/leaderboard/kols/calendar`** — Shows KOL PnL by day for a month. * **`GET /v2/pnl/leaderboard/kols/date`** — Shows KOL activity for one day. #### Batch Lookups Use batch endpoints when you need many results in one request: * **`POST /v2/pnl/wallets/:wallet/positions/batch`** — One wallet, up to 100 tokens. * **`POST /v2/pnl/tokens/:token/positions/batch`** — One token, up to 200 wallets. * **`POST /v2/pnl/positions/batch`** — Up to 200 wallet-token pairs. * **`POST /v2/pnl/wallets/batch`** — Up to 100 wallet summaries with labels and tags. ### New Features #### `pnlMode` Some positions can look wrong. For example, a wallet may show more sold than bought. `pnlMode` lets you choose how to handle those rows. | Mode | What it does | | - | - | | `strict` (default) | Safest view. Flagged positions count as **0** realized PnL. | | `adjusted` | Keeps flagged positions, but caps the PnL with a safer cost-basis rule. | | `raw` | No filtering. Shows the raw realized PnL number. | Supported responses return the mode they used. Position rows also include `realizedRaw`, so your app can show both filtered and raw numbers. #### Wallet Labels PnL V2 can now return an `identity` object for wallets. A wallet can have more than one label. Common labels: * **`kol`** — known public wallet, with name, Twitter handle, and avatar. * **`bot`** — known bot wallet. * **`pool`** — pool vault, authority, LP mint, or bonding curve account. * **`developer`** — token creator, pool deployer, or mint authority. * **`arbitrage`** / **`potential_bot`** — confirmed or likely arbitrage-style wallet. * **`hacker`** — known exploit, scam, or attacker wallet. * **`spam_dusting`** — known spam-dusting wallet. * **`exchange`** — known exchange hot wallet. * **Platform tags** — `axiom`, `bloom`, and `photon`. `axiom-flash` also works and returns as `axiom`. Token endpoints also show wallet roles for that exact token. This helps you spot developers, pools, LPs, and early buyers without another request. #### Holder Enrichment `/tokens/:tokenAddress/holders` now supports `?enrich=`. * `?enrich=identity` — Adds wallet labels for each holder. * `?enrich=walletPnl` — Adds lifetime wallet PnL and this-token PnL. * `?enrich=all` — Adds both. If you do not pass `enrich`, the endpoint works the same as before. ### Live PnL Streams New WebSocket rooms send PnL updates in real time. They are available on Premium, Business, and Enterprise plans. * **`pnl:{wallet}:{token}`** — Live PnL for one wallet and one token. * **`pnl:{wallet}`** — Live PnL for every token a wallet trades. * **`pnl:{wallet}:summary`** — Live total PnL summary for one wallet. Use REST once to load the starting data. Then use these rooms to keep the data live.
April 2026
Data API Datastream Solana RPC General

Performance improvements, new load balancers, and reduced latency

### Infrastructure * **Improved shred delivery** — Faster shred delivery for improved block propagation. * **New global load balancer for Data API** — Added a global load balancer for the Data API. * **New US-based Data API load balancer** — Dedicated US load balancer for lower-latency access. * **Colocated US servers** — Some endpoints dropped from 600ms response times to under 100ms. * **Migrated and upgraded ClickHouse cluster** — Better latency and faster queries across the API. ### Data API * **Improved trades endpoint speeds** — All trades endpoints are now faster. * **Improved `/chart` response speed** — Faster chart data retrieval. * **Improved `/tokens/:token` response time** — Faster token detail lookups. * **Improved metadata retrieval speed** — Faster metadata fetching across endpoints. * **Improved `/wallet/:wallet/chart` endpoint** — Now returns a chart even with only 1 data point. * **Fixed pagination bug on ascending trades** — Fixed a pagination issue when fetching trades in ascending order. * **Fixed Meteora DAMM liquidity** — Resolved a liquidity calculation issue on some older Meteora DAMM pools. * **Fixed PumpFun token creation edge cases** — Resolved edge cases on token creation events. * **Imported all missing PumpFun curve data** — Backfilled 15M+ tokens of PumpFun curve data. * **Fixed curve pools on `/tokens/:token`** — Curve pools (5+) now always appear after migration. * **Fixed Axiom transaction fee parser** — Moved from transfer to internal CPI call for accurate fee parsing. * **`uniqueTokens` query param on deployers API** — Returns latest graduated pool and first non-graduated pool in the regular list. * **Raydium LaunchLab tweaks** — Adjustments for Raydium LaunchLab support. * **Raydium CPMM improvements** — Improved Raydium CPMM handling. * **Search API bug fixes** — Various fixes to the search endpoint. ### Ridge DB * **Improved performance** — Improved indexes and response times across several queries. * **Globally load balanced** — US RPC users can now call methods like `getProgramAccounts`, `getProgramAccountsV2`, etc. around 200–400ms faster. * **Fixed frozen token account decoding** — Frozen token accounts now always show and decode properly. ### Datastream * **Improved Datastream performance** — Improved price, pool, and transaction update latency.
March 2026
Data API

Bags.fm creator updates

* **Updated Bags.fm creators** — Updated creator data for Bags.fm tokens.
February 2026
Data API Datastream

Search & deployer improvements, pool creation data

### Data API * **Multiple markets filter** — `/search` `market` parameter now accepts comma-separated values (e.g. `?market=raydium,orca,pumpfun`). Single values still work as before. * **Multiple launchpads filter** — `/search` `launchpad` parameter now accepts comma-separated values (e.g. `?launchpad=pumpfun,boop`). Single values still work as before. * **Launchpad filter on `/deployer`** — The `?launchpad=` parameter now works on `/deployer/{wallet}` (previously silently ignored). * **Full token format** — `/search` and `/deployer/{wallet}` now support `?format=full`, which returns results as full token objects (same shape as `/tokens/:token` — with token, pools, events, risk, buys, sells, txns, holders). * **Lower page limit for full format** — When `format=full`, the max per-page limit is capped at 100 (instead of 500) to keep queries efficient.
Search docs↗ Deployer docs↗
### Datastream * **Pool creation data** — The `latest` and `graduated` rooms now include a `creation` object on each pool with `creator`, `created_tx`, and `created_time`. (This is currently only available on the websocket for Pools. Token creation is also available on the Data API)
February 2026
Datastream

New stats total and volume rooms

* **New total stats rooms** * `stats:token:{tokenAddress}:total` * `stats:pool:{poolId}:total` * **New volume rooms** * `volume:token:{tokenAddress}` * `volume:pool:{poolId}`
Total Token Stats↗ Total Pool Stats↗ Token Volume↗ Pool Volume↗
January 2026
Data API Datastream

Price, charts, and streaming improvements

### Data API * **Improved price change percentages** — More accurate percent change calculations. * **Improved chart wicks** — Chart API shows more accurate wicks via a new aggregation technique. * **Fixed chart volume in some cases** — Ensures volume uses all pools when not filtering by pool. * **Added Humidifi, Tessera, and Solfi V1/V2 support.** ### Datastream * **Fixed price change percentages on stats room** — Corrected percent change calculations in the stats room. * **Improved pool selection** — Better pool selection on token and price rooms. * **Transaction monitor updates** — Added Raptor to the transaction monitor * **Added Humidifi, Tessera, and Solfi V1/V2 support.** * **Stability improvements** — Fixed and improved stability of transaction and price updates.
January 2026
Data API

Chart currency option

* **Chart currency option** — `/chart/{token}` and `/chart/{token}/{pool}` now support `currency=usd|sol|eur` (default `usd`).
View documentation↗
January 2026
Data API

Bundlers endpoint and new token data

* **New bundlers endpoint** — Use `/tokens/{token}/bundlers` to fetch bundler wallet stats for a token. * **Risk now includes bundlers** — The `risk` object returned on token responses includes bundler analysis. * **Search improvements** — `/search` now returns `riskScore` and bundler-related fields. ### Risk scores * **Bundlers** — New count-based + percentage-based scoring from new bundler data. * **Suspicious volume** — Flags extreme buy/sell imbalance.
January 2026
Datastream

Bundler tracking room

* **New room:** `bundlers:{tokenAddress}` — Real-time bundler wallet updates (wallet, current/previous amount & %, and totalBundlerPercentage).
January 2026
Data API

Top performers endpoint

* **Top performers endpoint** — Added `/top-performers/{timeframe}` to retrieve top performing tokens launched today. * **Timeframes** — Supports `5m`, `15m`, `30m`, `1h`, `6h`, `12h`, and `24h`.
December 2025
Data API Datastream

Data accuracy and trade enhancements

### Data API * **First buyers endpoint accuracy** — Improved accuracy for first buyers endpoints to match with other PnL endpoints * **Pricing and volume fixes** — Fixed pricing and volume calculation bug on some trades * **Exact token price at trade time** — Added exact token price at time of trade for each token when using the `showMeta` flag on `/trades` ### Datastream - Trade rooms * **Global Load Balancer** - Added a global load balancer for the Datastream that routes to US or EU based Datastream servers automatically. * **Enhanced Datastream trade rooms** — Added `price` and `marketCap` to each token in Datastream trade rooms for better accuracy (uses main pool data). The main object `priceUsd` can be considered the exchange rate. ### Image proxy * **Image proxy filtering** — Enhanced image proxy filtering for invalid SVGs with reduced false positives
November 2025
Datastream General

API and Datastream improvements

* **Faster transaction and price updates** — Reduced latency for real-time data delivery * **Enhanced tokens overview API** — Pulse/Memescope now features improved filters and dramatically better performance * **Upgraded Yellowstone gRPC** — New Rust client delivers faster streaming performance ### Data Accuracy & Reliability Major improvements to data quality and consistency: * **Program filtering** — Excluded unknown programs that could cause invalid data from arbitrage bots and other sources * **Pool data updates** — Liquidity changes now trigger pool updates even without swaps * **Time accuracy improvements** — Edge case handling now uses `blockTime` when gRPC is behind or transaction parsing is delayed by more than a few seconds ### New Features **Automatic Pool Rotation** * Main pool rotation now happens automatically for `price:token:{address}` and `token:{primary}` rooms — no client-side changes required **Aggregated Price Room** * New **`price:aggregated:{token}`** room provides min, average, median, and max price updates * Aggregates price data across top 10 valid pools * Each update includes individual pool prices for full transparency **Pumpfun Mayhem Mode** * Added support for Pumpfun Mayhem mode * Pool data now includes `tokenProgram` and `isMayhemMode` fields ### Infrastructure **Redis Server Upgrade** * Deployed new Redis infrastructure * Eliminates random 500/503 errors during high load periods * Improved overall platform stability
November 2025
Datastream

Aggregated Price Stream

We've added a new WebSocket room that provides aggregated price data across multiple liquidity pools for any token. ### What's New **`price:aggregated:{tokenAddress}`** * **Multi-pool aggregation** — Get median, average, min, and max prices calculated across top liquidity pools * **Top pools data** — Detailed breakdown of the 10 highest liquidity pools with individual prices * **Real-time updates** — Live price aggregation as pools update * **Pool count tracking** — Know exactly how many pools contributed to the aggregated data * **Automatic pool rotation** - No need to subscribe to new rooms after token migration. ### Why Use Aggregated Pricing? Single pool prices can be manipulated or show temporary volatility. Aggregated pricing gives you: * **More accurate market prices** — Median and average across multiple sources * **Manipulation resistance** — Harder to distort when aggregating across pools * **Price range visibility** — See min/max spread to identify arbitrage opportunities * **Liquidity-weighted insights** — Focus on pools that matter most ```json theme={null} { "type": "message", "data": { "token": "So11111111111111111111111111111111111111112", "timestamp": 1762964449215, "price": 153.70666202103925, "pool": "3nMFwZXwY1s1M5s8vYAHqd4wGs4iSxXE4LRoUMMYqEgF", "aggregated": { "median": 153.6850599485249, "average": 153.6735820182654, "min": 153.36863801111053, "max": 153.71662179961638, "poolCount": 10 }, "topPools": [ { "poolId": "3ucNos4NbumPLZNWztqGHNFFgkHeRMBQAVemeeomsUxv", "price": 153.68241854665007, "liquidity": 17950616.091940343, "market": "raydium-clmm" }, ... ] }, "room": "price:aggregated:So11111111111111111111111111111111111111112" } ``` Perfect for trading interfaces, price oracles, and portfolio tracking applications that need reliable, manipulation-resistant pricing.
November 2025
Solana RPC

Batch Token Balance Queries

We've added a new Ridge DB-powered RPC method that lets you query token balances for multiple wallets in a single request. ### What's New **`getTokenAccountsByOwners`** * **Batch up to 250 wallets** — Query hundreds of addresses in one call instead of making individual requests * **Multiple accounts support** — Automatically returns all token accounts if a wallet has multiple for the same mint * **Zero balance handling** — Wallets without a token account return a clean zero balance response * **Slot tracking** — Each account includes the slot when the balance was last updated ### Use Cases Perfect for: * Portfolio tracking across multiple wallets * Airdrop eligibility verification * Multi-wallet dashboards * Token distribution snapshots ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getTokenAccountsByOwners", "params": [ ["wallet1...", "wallet2...", "wallet3..."], "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ] } ``` This method drastically reduces API calls and latency when you need to check token holdings across many addresses at once.
November 2025
Data API Datastream

Ridge Stream Launch

All holder endpoints and real-time streams have been migrated to **Ridge Stream**, from our new high-performance service RidgeDB ### What's New **REST Endpoints** * **`/tokens/{token}/holders`** — Get top 100 holders (use /tokens//holders/pagination for pagination and higher limits ) * **`/tokens/{token}/holders/top`** — Fetch top holders by balance (excluding known wallets like lp) * **`/holders/multi`** — Multi-token holder count lookups * **`/holders/chart`** — Historical holder charts with more datapoints (now also includes SOL, USDC, and more) **Real-Time Streams** * **Holder count updates** — Live tracking of total holders * **Wallet balance updates** — Now includes native SOL with improved reliability * **Top 100 holders** — Real-time rankings of largest holders * **Snipers and insiders** — Track early buyers and insider activity You can now also get holder data for **large tokens** like WSOL, USDC, and USD1 that weren't available before. All holder counts and top 100 rankings work for these tokens via both API and real-time streaming.
October 28 2025
Data API

Search Filters

## New Search Filters Added new filters to the token search endpoint: * **`launchpad`** — Filter by launch platform (`pumpfun`, `moonshot`, `letsbonk.fun`, `believe`) * **`image`** — Search by exact image URL * **`hasImage`** — Filter tokens that have/don't have images (`true`/`false`) [View documentation →](/data-api/search/token-search)
October 22 2025
Data API

Paginated Token Holders

## Paginated Token Holders Endpoint We've launched a new endpoint for fetching all token holders with cursor-based pagination. ### What's New **`GET /tokens/{tokenAddress}/holders/paginated`** * **Cursor pagination** — Navigate through all holders efficiently * **Up to 5,000 per page** — Fetch large batches in a single request * **Ridge DB powered** — Fast queries even for tokens with millions of holders * **Complete holder data** — Returns wallet, token account, amount, USD value, total holder count and ownership percentage ### The Improvement Previously limited to 100 holders, this endpoint now handles tokens with any number of holders while maintaining consistent performance. ```bash theme={null} GET /tokens/{tokenAddress}/holders/paginated?limit=1000&cursor=nextPageCursor ``` [View documentation →](/data-api/tokens/get-all-token-holders-paginated)
October 21 2025
Solana RPC

RPC Enhancements

## Ridge DB Performance & Features Update We've shipped several improvements to our Ridge DB-powered RPC methods to give you even more control and speed. ### What's New * **Total count support** — `getProgramAccountsV2` and `getTokenAccountsByOwnerV2` now return `totalCount` in responses, making pagination and UI updates easier * **Faster queries** — New indexes dramatically improve response times for certain account lookups * **Stability improvements** — Bug fixes and optimizations These updates build on our Ridge DB launch, delivering better performance and more developer-friendly responses.
October 16 2025
Solana RPC

Ridge DB Launch

We've rolled out **two new RPC methods** powered by **Ridge DB** — our high-performance engine designed for lightning-fast account lookups on Solana. ### 🧭 New Methods #### `getProgramAccountsV2` Supercharged program account queries with: * **`changedSince`** — Fetch only accounts updated after a given slot (great for incremental syncs) * **`excludeZero`** — Automatically skip empty token accounts * **Cursor pagination** — Retrieve up to 10,000 accounts per request #### `getTokenAccountsByOwnerV2` Optimized token account retrieval, featuring the same Ridge DB speed and: * **`changedSince`** — Get only new or updated token accounts * **`excludeZero`** — Filter out dust or empty balances * **Cursor pagination** — Smoothly handle large token sets ### 💡 Why Ridge DB? Ridge DB isn't your standard RPC backend. It's a purpose-built system for account-heavy workloads that delivers: * Faster response times * Slot-based incremental updates * Cursor pagination for big datasets In short — faster queries, cleaner data, and a smoother developer experience.
October 2025
General

Documentation Launch

We've launched a brand-new documentation hub that brings all our products and APIs together, complete with guides and hands-on examples. You can now explore detailed docs for: * **Yellowstone gRPC** — Real-time Solana data streaming * **Data API** — REST access to historical and live Solana data * **Datastream** — WebSocket-based live data feeds * **Solana RPC** — Enhanced endpoints powered by Ridge DB * **Swap API** — High-performance token swaps and routing The new docs include interactive code samples, and best practices to help you build faster and smarter on Solana.
# Get Bundlers Chart Data Source: https://docs.solanatracker.io/data-api/chart/get-bundlers-chart-data /data-api/openapi.json get /bundlers/chart/{token} Gets bundler holding percentage data over time. Returns up to 1000 of the most recent data points ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getBundlersChart('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '1h'); ``` # Get Holders Chart Data Source: https://docs.solanatracker.io/data-api/chart/get-holders-chart-data /data-api/openapi.json get /holders/chart/{token} Gets token holder count data over time. Returns up to 1000 of the most recent data points ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getHoldersChart('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '1h'); ``` # Get Insiders Chart Data Source: https://docs.solanatracker.io/data-api/chart/get-insiders-chart-data /data-api/openapi.json get /insiders/chart/{token} Gets insider holding percentage data over time. Returns up to 1000 of the most recent data points ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getInsidersChart('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '1h'); ``` # Get OHLCV Data for a token Source: https://docs.solanatracker.io/data-api/chart/get-ohlcv-data-for-a-token /data-api/openapi.json get /chart/{token} Gets OHLCV (Open, High, Low, Close, Volume) data for charts ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getChartData({ tokenAddress: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', type: '1h', timeFrom: 1700000000, timeTo: 1700086400 }); ``` # Get OHLCV Data for a token/pool pair Source: https://docs.solanatracker.io/data-api/chart/get-ohlcv-data-for-a-tokenpool-pair /data-api/openapi.json get /chart/{token}/{pool} Gets OHLCV (Open, High, Low, Close, Volume) data for charts for a specific pool ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPoolChartData('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', '1h', 1700000000, 1700086400); ``` # Get Snipers Chart Data Source: https://docs.solanatracker.io/data-api/chart/get-snipers-chart-data /data-api/openapi.json get /snipers/chart/{token} Gets sniper holding percentage data over time. Returns up to 1000 of the most recent data points ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getSnipersChart('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '1h'); ``` # Get API Credits Source: https://docs.solanatracker.io/data-api/credits/get-api-credits /data-api/openapi.json get /credits Gets the remaining API credits for your API key ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCredits(); ``` # Get Subscription Information Source: https://docs.solanatracker.io/data-api/credits/get-subscription-information /data-api/openapi.json get /subscription Gets current subscription information including credits, plan, and billing details ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getSubscription(); ``` # Get Pool Events Source: https://docs.solanatracker.io/data-api/events/get-pool-events /data-api/openapi.json get /events/{tokenAddress}/{poolAddress} **Deprecated.** Switch to [`GET /stats/{token}/{pool}`](/data-api/stats/get-token-pool-stats) instead. With the SDK, use `client.getPoolStats(token, pool)`. The stats endpoint returns computed statistics as JSON, so you no longer need to decode binary events or run `processEventsAsync`. Gets raw event data for a specific token and pool. Returns binary data that needs to be decoded ## SDK Example ```typescript import { Client, processEventsAsync } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); // Deprecated: use client.getPoolStats(token, pool) instead. const data = await client.getPoolEvents('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2'); const stats = await processEventsAsync(data); ``` # Get Token Events Source: https://docs.solanatracker.io/data-api/events/get-token-events /data-api/openapi.json get /events/{tokenAddress} **Deprecated.** Switch to [`GET /stats/{token}`](/data-api/stats/get-token-stats) instead. With the SDK, use `client.getTokenStats(token)`. The stats endpoint returns computed statistics as JSON, so you no longer need to decode binary events or run `processEventsAsync`. Gets raw event data for live processing. Returns binary data that needs to be decoded ## SDK Example ```typescript import { Client, processEventsAsync } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); // Deprecated: use client.getTokenStats(token) instead. const data = await client.getEvents('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); const stats = await processEventsAsync(data); ``` # Latest KOL spot trades Source: https://docs.solanatracker.io/data-api/kol-trades/latest-kol-spot-trades /data-api/whale-kol.json get /trades/kols Returns the newest spot DEX trades from wallets on the shared KOL roster with absolute USD volume at or above `minVolume`. Each trade includes `identity` when available. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getKolTrades({ limit: 100, showMeta: true }); ``` # Latest KOL spot trades for one token Source: https://docs.solanatracker.io/data-api/kol-trades/latest-kol-spot-trades-for-one-token /data-api/whale-kol.json get /trades/kols/{token} Returns the newest KOL spot trades for a single mint with absolute USD volume at or above `minVolume`. Supports `hideArb` to keep only legs involving that mint. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getKolTradesByToken('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { limit: 100, showMeta: true }); ``` # Solana memecoin market stats Source: https://docs.solanatracker.io/data-api/lighthouse/solana-memecoin-market-stats /data-api/lighthouse.json get /lighthouse Returns rolling stats for Solana memecoin markets such as `all`, `pumpfun`, `raydium-all`, and `meteora-curve:bags`. Includes DEXs, launchpads, and discovered launchpad markets. No query parameters. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getLighthouse(); ``` # Get KOL Leaderboard Source: https://docs.solanatracker.io/data-api/pnl-v2/leaderboard/get-kol-leaderboard /data-api/pnl-v2/openapi.json get /v2/pnl/leaderboard/kols Ranks tracked KOL wallets by all-time performance. Use it to compare lifetime realized and unrealized PnL, ROI, trade count, and recency across known wallets. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2KOLLeaderboard({ limit: 50 }); ``` # Deprecated: Get First Token Buyers Source: https://docs.solanatracker.io/data-api/pnl/deprecated:-get-first-token-buyers /data-api/openapi.json get /first-buyers/{token} Deprecated. Use PnL V2 instead: `GET /v2/pnl/tokens/{token}/first-buyers` for chronological first buyers with token PnL, wallet PnL, identity, and holding state. Retrieves the first 100 buyers of a token (since API started recording data) with PnL data for each wallet ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getFirstBuyers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Deprecated: Get Token-Specific PnL Source: https://docs.solanatracker.io/data-api/pnl/deprecated:-get-token-specific-pnl /data-api/openapi.json get /pnl/{wallet}/{token} Deprecated. Use PnL V2 instead: `GET /v2/pnl/wallets/{wallet}/tokens/{token}`. Gets Profit and Loss data for a specific token in a wallet ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenPnL('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Deprecated: Get Wallet PnL Source: https://docs.solanatracker.io/data-api/pnl/deprecated:-get-wallet-pnl /data-api/openapi.json get /pnl/{wallet} Deprecated. Use PnL V2 instead: `GET /v2/pnl/wallets/{wallet}` for wallet summaries and `GET /v2/pnl/wallets/{wallet}/positions` for token positions. Gets Profit and Loss data for all positions of a wallet ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWalletPnL('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Historic Price Information Source: https://docs.solanatracker.io/data-api/price/get-historic-price-information /data-api/openapi.json get /price/history Gets historic price information for a single token ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPriceHistory('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get lowest and highest price in time range Source: https://docs.solanatracker.io/data-api/price/get-lowest-and-highest-price-in-time-range /data-api/openapi.json get /price/history/range Gets the lowest and highest price in a time range ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPriceRange('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', 1700000000, 1700086400); ``` # Get Multiple Token Prices Source: https://docs.solanatracker.io/data-api/price/get-multiple-token-prices /data-api/openapi.json get /price/multi Gets price information for multiple tokens (up to 100) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMultiplePrices(['So11111111111111111111111111111111111111112', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'], true); ``` # Get Price at Specific Timestamp Source: https://docs.solanatracker.io/data-api/price/get-price-at-specific-timestamp /data-api/openapi.json get /price/history/timestamp Gets specific historic price information for a token at a given timestamp ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPriceAtTimestamp('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', 1700000000); ``` # Get Token Price Source: https://docs.solanatracker.io/data-api/price/get-token-price /data-api/openapi.json get /price Gets price information for a single token ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPrice('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', true); ``` # Post Multiple Token Prices Source: https://docs.solanatracker.io/data-api/price/post-multiple-token-prices /data-api/openapi.json post /price/multi Similar to GET /price/multi, but accepts token addresses in the JSON body. Pass `priceChanges: true` to include the `priceChanges` object on each token. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.postMultiplePrices(['So11111111111111111111111111111111111111112', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'], true); ``` # Recent changes Source: https://docs.solanatracker.io/data-api/recent-changes New endpoints, added features, and fixes for Data API. [View the full changelog](/changelog)
September 18, 2026
New Data API Datastream
## Swaps, LP moves, and wallet labels in one feed Track buys and sells alongside LP adds and removes. See which wallets are adding liquidity, which are pulling it, and where it all lands in your trade feed.
Updated trade feed with All, Swaps, and Liquidity tabs, green LP adds, red LP removes, and wallet labels.

After: swaps and LP activity in one feed, with wallet labels and All / Swaps / Liquidity filters.

Previous trade feed showing buys and sells with shortened wallet addresses.

Before: a swaps-only feed with wallet addresses.

* **Stream LP moves.** Five new liquidity room scopes: token, token + pool, token + pool + wallet, pool, or wallet. * **Build All / Swaps / Liquidity tabs.** Query `events=all`, `events=trades`, or `events=liquidity` on all four token trade endpoints. Set `limit` to load up to 500 rows per page. * **Put a name to the wallet.** Use `enrich=identity` on REST or `:enriched` on live rooms for available KOL profiles, dev labels, SNS names, and trading platforms. * **Keep LP amounts exact.** Adds and removes include the pool and each token's amount as a decimal string. Liquidity stays in token units, separate from swap volume. ```http theme={null} GET /trades/{token}?events=all&enrich=identity&limit=100 ``` ```json theme={null} { "type": "join", "room": "liquidity:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN:enriched" } ``` Load the history with REST, then keep the feed moving with Datastream. Existing trade requests and rooms remain swaps-only by default. Live LP events are provisional; use REST to reconcile confirmed activity. ### Changed endpoints and rooms

REST · Trade history

Datastream · Live liquidity

Build your LP activity feed →
September 7–16, 2026
Data API Datastream Solana RPC PnL V2 General

Platform speed, Search API, RidgeDB, and dashboard updates

### Faster data, from indexing to delivery * **Search and holders:** faster Search API responses and improved holder data performance. * **Token coverage:** support for all quote tokens on Meteora Curve, Raydium LaunchLab, and Pump.fun, plus Pump.fun `isHolderReward` and Transaction V1 support. * **Indexing and streaming:** rebuilt metadata indexing, RidgeDB, and Ridge streaming for improved speed, accuracy, and efficiency across Data API and RPC services. * **PnL V2:** improved redundancy and accuracy. ### More ways to manage your subscription * **Teams:** invite teammates and manage their access on Premium, Business, and dedicated node plans. * **On-chain USDC subscriptions:** automatic renewals and top-ups using native USDC on Solana.
August 2026
Data API

See what is moving across Solana memecoin markets

Lighthouse gives you a live view of activity across Solana launchpads and DEXs. * See buys, sells, traders, volume, new token launches, and migrations * Track activity over `5m`, `1h`, `6h`, and `24h` * Compare each period with the one before it * Build memecoin dashboards and “what is moving now?” pages with `GET /lighthouse`
Lighthouse guide↗ API reference↗
August 2026
Data API Datastream

See what whales and KOLs are trading as it happens

Know when high-value wallets move. New REST endpoints and Datastream rooms make it easy to follow whale activity, track KOL trades, power token pages, and trigger alerts from a single trade feed. * **REST endpoints:** Fetch the latest whale trades, all KOL trades, or KOL activity for a specific token. * **Live Datastream rooms:** Subscribe to whale and KOL trades as they happen. * **Flexible volume filters:** Watch trades from `$1k` to `$10k`, or request all eligible KOL trades with `minVolume=0`. * **KOL identity:** Show names, Twitter handles, and other identity metadata when available. * **More context when you need it:** Paginate with opaque cursors, add token metadata, and filter arbitrage activity when needed.
Whale & KOL guide↗ REST API reference↗ Datastream reference↗
July 2026
PnL V2

Currency denomination (SOL/EUR) and performance trade-count fix

### Currency query parameter `GET /v2/pnl/wallets/:wallet`, `/history`, and `/performance` now accept `?currency=usd|sol|eur` (default `usd`). * Pass `sol` or `eur` to convert USD snapshot values at read time using historical token prices. * Response includes top-level `"currency": "sol"` or `"currency": "eur"` when requested. * Historical endpoints convert per day; wallet summary uses current spot. * Counts, percentages, timestamps, and ROI are not converted. * Invalid currency returns **400**: `{ "error": "Invalid currency. Options: usd, sol, eur" }`. ```http theme={null} GET /v2/pnl/wallets/{wallet}?currency=sol GET /v2/pnl/wallets/{wallet}/history?period=30d¤cy=eur GET /v2/pnl/wallets/{wallet}/performance?period=30d¤cy=sol ``` ### Performance trade counts fixed `totals.trades` and per-day `trades` on `/performance` now count **daily activity within the window** (`day_buys + day_sells`) instead of summing cumulative lifetime snapshot totals. Trade counts should now align with wallet summary lifetime trades when summed over the full trading history.
PnL V2 overview↗ Wallet analysis guide↗
June 2026
Data API Datastream

Jupiter DCA V2 — full support and indexing for recurring orders

Jupiter DCA V2 orders (`openDcaV2`) are now fully supported and indexed across the DCA API and Datastream feeds. Previously hidden DCA V2 positions are now visible in REST responses and live WebSocket events. Existing `/dca/*` endpoints and `dca:jupiter` rooms automatically include V2 orders — no query changes required. Order objects include `openInstruction: "openDcaV2"` to distinguish V2 accounts.
Jupiter DCA API↗ Jupiter DCA Datastream↗
# Token Search Source: https://docs.solanatracker.io/data-api/search/token-search /data-api/openapi.json get /search Searches for tokens by symbol, name, or address with various filtering and sorting options ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.searchTokens({ query: 'BONK', limit: 10 }); ``` # Get Token-Pool Stats Source: https://docs.solanatracker.io/data-api/stats/get-token-pool-stats /data-api/openapi.json get /stats/{token}/{pool} Gets detailed stats for a token-pool pair over various time intervals ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPoolStats('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2'); ``` # Get Token Stats Source: https://docs.solanatracker.io/data-api/stats/get-token-stats /data-api/openapi.json get /stats/{token} Gets detailed stats for a token over various time intervals ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenStats('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get All-Time High Price Source: https://docs.solanatracker.io/data-api/tokens/get-all-time-high-price /data-api/openapi.json get /tokens/{tokenAddress}/ath Retrieves the all-time high price of a token (since the data API started recording) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAthPrice('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get All Token Holders (Paginated) Source: https://docs.solanatracker.io/data-api/tokens/get-all-token-holders-paginated /data-api/openapi.json get /tokens/{tokenAddress}/holders/paginated Gets token holders with cursor-based pagination support. Returns holders sorted by amount in descending order. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenHoldersPaginated('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', 100); ``` # Get Graduated Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-graduated-tokens /data-api/openapi.json get /tokens/multi/graduated Overview of all graduated launchpad tokens (Pump.fun, letsbonk.fun, jupiter studio etc) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getGraduatedTokens({ limit: 50 }); ``` # Get Graduating Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-graduating-tokens /data-api/openapi.json get /tokens/multi/graduating Overview of all graduating launchpad tokens (Pump.fun, letsbonk.fun, jupiter studio etc) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getGraduatingTokens({ limit: 50 }); ``` # Get Latest Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-latest-tokens /data-api/openapi.json get /tokens/latest Retrieves the latest 100 tokens ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getLatestTokens(1); ``` # Get Multiple Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-multiple-tokens /data-api/openapi.json post /tokens/multi Accepts an array of token addresses in the request body (up to 20 per request) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMultipleTokens(['So11111111111111111111111111111111111111112', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN']); ``` # Get Token Bundlers Source: https://docs.solanatracker.io/data-api/tokens/get-token-bundlers /data-api/openapi.json get /tokens/{token}/bundlers Retrieves bundler information for a specific token, including top 500 bundler wallets and statistics ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenBundlers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get Token by Pool Address Source: https://docs.solanatracker.io/data-api/tokens/get-token-by-pool-address /data-api/openapi.json get /tokens/by-pool/{poolAddress} Retrieves token information by searching with a pool address ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenByPool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2'); ``` # Get Token Holders (Top 100) Source: https://docs.solanatracker.io/data-api/tokens/get-token-holders-top-100 /data-api/openapi.json get /tokens/{tokenAddress}/holders Gets the top 100 holders for a specific token and the total holder count. Optional enrichment adds wallet identity (`?enrich=identity`) and/or PnL (`?enrich=walletPnl`). Use `?enrich=identity,walletPnl`, `?enrich=all`, or `?enrich=*` for both. When enrichment is requested, the response includes an `enrich` array listing applied modules. `pnl.token` uses the same flat field set as PnL V2 (`invested`, `proceeds`, trade counts, volume, timing, `avgCost`, `holdTimeSecs`). `pnl.wallet` is lifetime wallet PnL. Enrichment fields are omitted per account when not applicable — for example, pool accounts may have `identity` only, and wallets with no trade history for the token omit `pnl`. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenHolders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get Token Information Source: https://docs.solanatracker.io/data-api/tokens/get-token-information /data-api/openapi.json get /tokens/{tokenAddress} Retrieves comprehensive information about a specific token, including pools, events, and risk. `risk.bundlers` may be omitted even when sniper/insider data is present; call `GET /tokens/{token}/bundlers` for the full bundler wallet list. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenInfo('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get Token Overview Source: https://docs.solanatracker.io/data-api/tokens/get-token-overview /data-api/openapi.json get /tokens/multi/all Gets an overview of latest, graduating, and graduated tokens (Axiom Pulse / Photon Memescope style) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenOverview({ limit: 50 }); ``` # Get Tokens by Deployer Source: https://docs.solanatracker.io/data-api/tokens/get-tokens-by-deployer /data-api/openapi.json get /deployer/{wallet} Retrieves all tokens created by a specific wallet with pagination support ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokensByDeployer('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { page: 1, limit: 50 }); ``` # Get Tokens by Volume Source: https://docs.solanatracker.io/data-api/tokens/get-tokens-by-volume /data-api/openapi.json get /tokens/volume Retrieves the top 100 tokens sorted by highest volume within the default timeframe Response body is a **top-level JSON array** of token rows (not wrapped in `{ "items": [...] }`). ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokensByVolume(); ``` # Get Tokens by Volume with Timeframe Source: https://docs.solanatracker.io/data-api/tokens/get-tokens-by-volume-with-timeframe /data-api/openapi.json get /tokens/volume/{timeframe} Retrieves the top 100 tokens sorted by highest volume within the specified timeframe Response body is a **top-level JSON array** of token rows (not wrapped in `{ "items": [...] }`). ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokensByVolume('24h'); ``` # Get Top 20 Token Holders Source: https://docs.solanatracker.io/data-api/tokens/get-top-20-token-holders /data-api/openapi.json get /tokens/{tokenAddress}/holders/top Gets the top 20 holders for a token ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTopHolders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get Top Performing Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-top-performing-tokens /data-api/openapi.json get /top-performers/{timeframe} Retrieves the top performing tokens launched today within the specified timeframe ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTopPerformers('1h'); ``` # Get Trending Tokens Source: https://docs.solanatracker.io/data-api/tokens/get-trending-tokens /data-api/openapi.json get /tokens/trending Gets the top 100 trending tokens based on transaction volume in the specified timeframe (default: past hour) Response body is a **top-level JSON array** of token rows (not wrapped in `{ "items": [...] }`). ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTrendingTokens(); ``` # Get Trending Tokens by Timeframe Source: https://docs.solanatracker.io/data-api/tokens/get-trending-tokens-by-timeframe /data-api/openapi.json get /tokens/trending/{timeframe} Gets the top 100 trending tokens based on transaction volume in the specified timeframe Response body is a **top-level JSON array** of token rows (not wrapped in `{ "items": [...] }`). ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTrendingTokens('1h'); ``` # Deprecated: Get Top Traders (All Tokens) Source: https://docs.solanatracker.io/data-api/top-traders/deprecated:-get-top-traders-all-tokens /data-api/openapi.json get /top-traders/all Deprecated. For current Solana trader rankings, use `GET /v2/pnl/leaderboard/top`. Gets the most profitable traders across all tokens ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTopTraders(); ``` # Deprecated: Get Top Traders (All Tokens) with Pagination Source: https://docs.solanatracker.io/data-api/top-traders/deprecated:-get-top-traders-all-tokens-with-pagination /data-api/openapi.json get /top-traders/all/{page} Deprecated. For current Solana trader rankings with cursor pagination, use `GET /v2/pnl/leaderboard/top`. Gets the most profitable traders across all tokens, with optional pagination ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTopTraders(2); ``` # Deprecated: Get Top Traders for Specific Token Source: https://docs.solanatracker.io/data-api/top-traders/deprecated:-get-top-traders-for-specific-token /data-api/openapi.json get /top-traders/{token} Deprecated. Use PnL V2 instead: `GET /v2/pnl/tokens/{token}/traders` for token trader rankings with sorting and filters. Gets top 100 traders by PnL for a token ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenTopTraders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get Pool-Specific Trades Source: https://docs.solanatracker.io/data-api/trades/get-pool-specific-trades /data-api/openapi.json get /trades/{tokenAddress}/{poolAddress} Retrieve token activity within this route’s token, pool and wallet scope. Use `events=all` to combine swaps with liquidity additions/removals, or `events=liquidity` for liquidity only. Omit `events` for the existing trades-only response. Add `enrich=identity` to identify wallets on either event type. Liquidity rows use `type: add_liquidity | remove_liquidity`, a single `pool`, and exact string amounts in `tokens[]`; they do not contain swap prices, volume or PnL. See the [liquidity guide](/guides/liquidity) for REST examples, pagination and live rooms. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPoolTradeHistory('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', { events: 'all', // Use 'liquidity' for LP adds/removes only, or 'trades' for swaps. enrich: 'identity', limit: 100, sortDirection: 'DESC', }); ``` # Get Token Trades Source: https://docs.solanatracker.io/data-api/trades/get-token-trades /data-api/openapi.json get /trades/{tokenAddress} Retrieve token activity within this route’s token, pool and wallet scope. Use `events=all` to combine swaps with liquidity additions/removals, or `events=liquidity` for liquidity only. Omit `events` for the existing trades-only response. Add `enrich=identity` to identify wallets on either event type. Liquidity rows use `type: add_liquidity | remove_liquidity`, a single `pool`, and exact string amounts in `tokens[]`; they do not contain swap prices, volume or PnL. See the [liquidity guide](/guides/liquidity) for REST examples, pagination and live rooms. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTokenTradeHistory('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { events: 'all', // Use 'liquidity' for LP adds/removes only, or 'trades' for swaps. enrich: 'identity', limit: 100, sortDirection: 'DESC', }); ``` # Get User-Specific Pool Trades Source: https://docs.solanatracker.io/data-api/trades/get-user-specific-pool-trades /data-api/openapi.json get /trades/{tokenAddress}/{poolAddress}/{owner} Retrieve token activity within this route’s token, pool and wallet scope. Use `events=all` to combine swaps with liquidity additions/removals, or `events=liquidity` for liquidity only. Omit `events` for the existing trades-only response. Add `enrich=identity` to identify wallets on either event type. Liquidity rows use `type: add_liquidity | remove_liquidity`, a single `pool`, and exact string amounts in `tokens[]`; they do not contain swap prices, volume or PnL. See the [liquidity guide](/guides/liquidity) for REST examples, pagination and live rooms. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getUserPoolTradeHistory('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', 'FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { events: 'all', // Use 'liquidity' for LP adds/removes only, or 'trades' for swaps. enrich: 'identity', limit: 100, sortDirection: 'DESC', }); ``` # Get User-Specific Token Trades Source: https://docs.solanatracker.io/data-api/trades/get-user-specific-token-trades /data-api/openapi.json get /trades/{tokenAddress}/by-wallet/{owner} Retrieve token activity within this route’s token, pool and wallet scope. Use `events=all` to combine swaps with liquidity additions/removals, or `events=liquidity` for liquidity only. Omit `events` for the existing trades-only response. Add `enrich=identity` to identify wallets on either event type. Liquidity rows use `type: add_liquidity | remove_liquidity`, a single `pool`, and exact string amounts in `tokens[]`; they do not contain swap prices, volume or PnL. See the [liquidity guide](/guides/liquidity) for REST examples, pagination and live rooms. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getUserTokenTradeHistory('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', 'FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { events: 'all', // Use 'liquidity' for LP adds/removes only, or 'trades' for swaps. enrich: 'identity', limit: 100, sortDirection: 'DESC', }); ``` # Get Basic Wallet Information Source: https://docs.solanatracker.io/data-api/wallet/get-basic-wallet-information /data-api/openapi.json get /wallet/{owner}/basic Gets all tokens in a wallet with current value in USD (lightweight, non-cached option) ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWalletBasic('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Portfolio Chart Source: https://docs.solanatracker.io/data-api/wallet/get-wallet-portfolio-chart /data-api/openapi.json get /wallet/{owner}/chart Legacy **portfolio-value** chart (historical wallet USD value series with period PnL percentages). This is **not** equivalent to PnL V2 trade/performance charts. Prefer `GET /v2/pnl/wallets/{wallet}/chart` (PnL V2) for trade-based PnL time series. If chart data cannot be built for the wallet, the endpoint may return HTTP `400` with `{ "error": "Error fetching wallet chart data" }`. That is an empty/unavailable legacy chart result — not the same contract as PnL V2. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWalletChart('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Tokens Source: https://docs.solanatracker.io/data-api/wallet/get-wallet-tokens /data-api/openapi.json get /wallet/{owner} Gets all tokens in a wallet with current value in USD ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Tokens with Pagination Source: https://docs.solanatracker.io/data-api/wallet/get-wallet-tokens-with-pagination /data-api/openapi.json get /wallet/{owner}/page/{page} Retrieves wallet tokens using pagination with a limit of 250 tokens per request ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWalletPage('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', 2); ``` # Get Wallet Trades Source: https://docs.solanatracker.io/data-api/wallet/get-wallet-trades /data-api/openapi.json get /wallet/{owner}/trades Gets the latest trades of a wallet ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWalletTrades('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Latest high-volume (whale) spot trades Source: https://docs.solanatracker.io/data-api/whale-trades/latest-high-volume-whale-spot-trades /data-api/whale-kol.json get /trades/whales Returns the newest spot DEX trades with absolute USD volume at or above `minVolume`. When the trader is a KOL, `identity` is included. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getWhaleTrades({ minVolume: 5000, limit: 100, showMeta: true }); ``` # Glossary Source: https://docs.solanatracker.io/glossary Plain-language definitions for Solana Tracker terms — wallet tags, sniper, bundler, KOL, PnL, datastream rooms, slippage, priority fees, and more. Use this page when a guide uses a term you have not seen before. The API names stay exact, but the explanations here use plain language. ## API Basics | Term | Plain meaning | | - | - | | Data API | Solana Tracker's HTTP API for token prices, wallets, trades, holders, charts, and analytics. | | RPC | A direct way to ask a Solana node for blockchain data or to send transactions. | | WebSocket | A live connection that keeps sending updates after you subscribe. | | WebSocket room | A named live feed, such as `latest` or `price:{tokenAddress}`, that you join to receive messages. | | Cursor pagination | A way to load large lists in pages. The response gives you a `cursor`; send it in the next request to get the next page. | | API key | Your private key for using Solana Tracker APIs. Keep it secret. | ## Token And Trading Terms | Term | Plain meaning | | - | - | | Token mint | The Solana address that identifies a token. | | SPL token | A standard Solana token. Most tokens on Solana use this format. | | DEX | A decentralized exchange where users swap tokens on-chain. | | DEX aggregator | A tool that checks many exchanges and picks a route for a swap. | | Liquidity | Money in a trading pool that lets people buy and sell. | | Liquidity pool | A pool of tokens used for trading. More liquidity usually means smoother trades. | | LP | Short for liquidity provider or liquidity position, depending on context. | | Slippage | The price change you allow between quote time and trade time. | | Smallest units | Blockchain integer amounts without decimals. For example, lamports are the smallest unit of SOL. | | Bonding curve | A pricing path where the token price changes as people buy or sell before it moves to a normal pool. | | Graduation | When a token leaves its bonding curve and moves liquidity to a DEX pool. | | Rug pull | A risky token event where liquidity or safety disappears and buyers may not be able to sell safely. | | Sniper | A wallet that buys very early after a token launches. | | Bundler | A wallet or service that groups transactions together, often during launch. | | MEV | Profit made by changing or using transaction order. In these docs it often means bot-like trading behavior. | ## Price And Chart Terms | Term | Plain meaning | | - | - | | OHLCV | Open, high, low, close, and volume. These are the values used for candlestick charts. | | Open | The first price in a time window. | | High | The highest price in a time window. | | Low | The lowest price in a time window. | | Close | The last price in a time window. | | Volume | The amount traded in a time window. | | Market cap | Token price multiplied by supply, when supply data is available. | ## Wallet And PnL Terms | Term | Plain meaning | | - | - | | PnL | Profit and loss. It shows how much a wallet gained or lost. | | Realized PnL | Profit or loss from tokens already sold. | | Unrealized PnL | Paper profit or loss on tokens still held. It changes when price changes. | | Total PnL | Realized PnL plus unrealized PnL. | | Cost basis | What the wallet paid for a token position. | | FIFO | First in, first out. The oldest buys are matched to sells first when calculating PnL. | | Open position | Tokens the wallet still holds. | | Equity curve | A line chart of wallet value over time. | | Drawdown | A drop from a high point to a lower point. | | Quote asset | The token used as the price side of a trade, such as SOL or a stablecoin. | ## Solana Infrastructure Terms | Term | Plain meaning | | - | - | | Slot | A short time window when Solana can produce a block. | | Block | A group of transactions recorded by the network. | | Entry | A lower-level part of a block that helps show transaction order. | | Shred | A small piece of Solana block data sent across the network. | | Leader | The validator scheduled to produce a block for a slot. | | Commitment | How final a result is. Common levels are `processed`, `confirmed`, and `finalized`. | | `processed` | Fastest, but the result can still change. | | `confirmed` | Slower, with stronger network agreement. | | `finalized` | Slowest, with the strongest finality. | | gRPC | A fast streaming protocol used by Yellowstone for live Solana data. | # Stream Solana wallet and position PnL Source: https://docs.solanatracker.io/guides/datastream-pnl Subscribe to Solana wallet PnL, position changes, and summaries. Pair PnL rooms with price streams for live unrealized returns. Use a PnL room to keep wallet totals or token positions current after loading a REST snapshot. Add a price room when the display needs unrealized PnL updates between trades. PnL V2 Datastream is available on **Premium, Business, and Enterprise** plans.\ Connect to `wss://datastream.solanatracker.io/{apiKey}` with your Data API key. ## Room types Choose whether the display needs one position, all positions, or wallet totals: | Room | What it emits | Use when | | - | - | - | | `pnl:{wallet}:{token}` | `tradeUpdate`, `balanceUpdate`, `priceUpdate` for one token | You're tracking one specific position | | `pnl:{wallet}` | `tradeUpdate`, `balanceUpdate`, `priceUpdate` for all tokens | You want live updates on every position a wallet holds | | `pnl:{wallet}:summary` | Total wallet PnL summary | You want aggregated wallet-level PnL totals | PnL rooms report trades with `tradeUpdate`, balance changes with `balanceUpdate`, and periodic valuations with `priceUpdate`. Add a [price stream](#fastest-live-unrealized-pnl-combining-rooms) to update unrealized PnL between position events. ## Connecting ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { // subscribe to a room ws.send(JSON.stringify({ type: "join", room: "pnl:WALLET_ADDRESS:TOKEN_ADDRESS" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); console.log(msg.type, msg.data); }; ``` ## Room: pnl:\{wallet}:\{token} Subscribe to one wallet-token position. Trade and balance notifications update the position; periodic `priceUpdate` messages refresh its price-dependent values. **`tradeUpdate`** reports a buy or sell: ```json theme={null} { "type": "message", "room": "pnl:DJqkH...D61:A7Fbn...pump", "data": { "type": "tradeUpdate", "wallet": "DJqkH...D61", "token": "A7Fbn...pump", "buyCount": 3, "sellCount": 1, "totalBuyUsd": 0.0257, "totalSellUsd": 0.0043, "avgCostPerToken": 0.000082, "currentBalance": 205.39, "currentPrice": 0.0000911, "currentValue": 0.01871, "holdingCostBasis": 0.01715, "realizedPnl": -0.00087, "unrealizedPnl": 0.00156, "proceeds": 0.0043, "totalTransactions": 4 } } ``` **`balanceUpdate`** reports a position balance update: ```json theme={null} { "type": "message", "room": "pnl:DJqkH...D61:A7Fbn...pump", "data": { "type": "balanceUpdate", "wallet": "DJqkH...D61", "token": "A7Fbn...pump", "avgCostPerToken": 0.0000835, "currentBalance": 205.39, "currentPrice": 0.0000911, "currentValue": 0.01871, "holdingCostBasis": 0.01715, "unrealizedPnl": 0.00156 } } ``` ### Subscribe example ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "pnl:DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61:A7FbnhhkY2R6hZhkT2oexNNFQyGG7cBZJLWmC32spump" })); ``` ## Room: pnl:\{wallet} Subscribe to `pnl:{wallet}` for updates across a wallet's positions. You do not need a separate PnL subscription for each mint. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "pnl:DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61" })); ws.onmessage = (event) => { const { data } = JSON.parse(event.data); if (!data) return; if (data.type === "tradeUpdate") { console.log(`Trade on ${data.token}: unrealized PnL $${data.unrealizedPnl.toFixed(4)}`); } if (data.type === "balanceUpdate") { console.log(`Price update for ${data.token}: value now $${data.currentValue.toFixed(4)}`); } }; ``` Use `pnl:{wallet}` when building a live portfolio dashboard — you only need one room subscription per wallet. ## Room: pnl:\{wallet}:summary Receive the wallet's total PnL summary whenever the aggregate changes. This room returns wallet-level totals, not individual positions. ```json theme={null} { "type": "message", "room": "pnl:DJqkH...D61:summary", "data": { "averages": { "buy": 1.1751933473135445, "sell": 1.7625162156883138 }, "counts": { "buys": 1664, "sells": 745, "tokensHeldEver": 842, "tokensTraded": 862, "trades": 2409 }, "invested": 708.3246017180338, "openPositions": { "cost": 962.9218710198314, "value": 37.196319618271204 }, "pnl": { "realized": 604.7499789697601, "total": -421.18843262884593, "unrealized": -1025.938411598606 }, "proceeds": 1313.0745806877937, "roi": -59.46262936614906, "timing": { "firstTrade": 1704067810000, "lastTrade": 1778966213113 } } } ``` ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "pnl:DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61:summary" })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.room !== `pnl:${wallet}:summary`) return; const { data } = msg; console.log(`Total PnL: $${data.pnl.total.toFixed(2)}`); console.log(`Realized: $${data.pnl.realized.toFixed(2)}`); console.log(`Unrealized: $${data.pnl.unrealized.toFixed(2)}`); console.log(`ROI: ${data.roi.toFixed(2)}%`); }; ``` ## Update unrealized PnL with price streams Use PnL room values for cost basis, realized PnL, and token balance. A separate price stream can update the valuation between position events. To update unrealized PnL on price ticks, pair the position room with one of these price rooms: | Stream | What it gives you | | - | - | | `pnl:{wallet}` (or `pnl:{wallet}:{token}`) | Live cost basis, FIFO realized PnL, balance changes, trade fills | | `price:aggregated:{token}` | Cross-pool price summary | | `price-by-token:{token}` | Price from the primary pool | Use the PnL room as the source of truth for `currentBalance` and `holdingCostBasis`, and recompute `unrealizedPnl = (currentBalance × livePrice) − holdingCostBasis` whenever a price tick arrives. ### Example: live unrealized PnL on a single position ```javascript theme={null} const wallet = "DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61"; const token = "A7FbnhhkY2R6hZhkT2oexNNFQyGG7cBZJLWmC32spump"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); const position = { balance: 0, costBasis: 0, realizedPnl: 0, livePrice: 0, }; const recompute = () => { const value = position.balance * position.livePrice; const unrealized = value - position.costBasis; console.log( `value=$${value.toFixed(4)} unrealized=$${unrealized.toFixed(4)} realized=$${position.realizedPnl.toFixed(4)}` ); }; ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `pnl:${wallet}:${token}` })); ws.send(JSON.stringify({ type: "join", room: `price:aggregated:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; if (d?.type === "tradeUpdate" || d?.type === "balanceUpdate") { position.balance = d.currentBalance; position.costBasis = d.holdingCostBasis; if (d.type === "tradeUpdate") position.realizedPnl = d.realizedPnl; position.livePrice = d.currentPrice; recompute(); return; } if (msg.room?.startsWith("price:aggregated:")) { position.livePrice = d.price; recompute(); } }; ``` ### Example: live unrealized PnL across an entire wallet Subscribe to `pnl:{wallet}` for trade and balance updates on every position, then dynamically subscribe to a price room for each token the wallet holds. Price streams can update often. In production, batch UI updates or throttle logs so every price tick does not flood your console or browser. ```javascript theme={null} const wallet = "DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); const positions = new Map(); // token -> { balance, costBasis, realizedPnl, livePrice } const subscribed = new Set(); const portfolioUnrealized = () => { let total = 0; for (const p of positions.values()) { total += p.balance * p.livePrice - p.costBasis; } return total; }; const subscribePrice = (token) => { if (subscribed.has(token)) return; subscribed.add(token); // Use price:aggregated for high-liquidity tokens, price-by-token for memecoins / single-pool ws.send(JSON.stringify({ type: "join", room: `price:aggregated:${token}` })); }; ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `pnl:${wallet}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; if (d?.type === "tradeUpdate" || d?.type === "balanceUpdate") { const p = positions.get(d.token) ?? { balance: 0, costBasis: 0, realizedPnl: 0, livePrice: 0 }; p.balance = d.currentBalance; p.costBasis = d.holdingCostBasis; p.livePrice = d.currentPrice; if (d.type === "tradeUpdate") p.realizedPnl = d.realizedPnl; positions.set(d.token, p); subscribePrice(d.token); } if (msg.room?.startsWith("price:aggregated:")) { const token = msg.room.split(":")[2]; const p = positions.get(token); if (!p) return; p.livePrice = d.price; positions.set(token, p); } console.log(`Portfolio unrealized PnL: $${portfolioUnrealized().toFixed(4)}`); }; ``` **Choose a price source** * `price:aggregated:{token}` — Cross-pool median price. * `price-by-token:{token}` — primary-pool price. Slightly lower latency for memecoins or anything that effectively trades on a single pool. ### `priceUpdate` payload (PnL room) A PnL `priceUpdate` is a periodic position refresh. Its cadence differs from the dedicated price streams: ```json theme={null} { "type": "message", "room": "pnl:DJqkH...D61:A7Fbn...pump", "data": { "type": "priceUpdate", "wallet": "DJqkH...D61", "token": "A7Fbn...pump", "currentBalance": 205.39, "currentPrice": 0.0000911, "currentValue": 0.01871, "holdingCostBasis": 0.01715, "unrealizedPnl": 0.00156 } } ``` ## Unsubscribing Leave any room by sending a `leave` message: ```javascript theme={null} ws.send(JSON.stringify({ type: "leave", room: "pnl:DJqkHSmx9XosFpNqdi2DevtNgaf52oow4pFpJECv6D61:summary" })); ``` ## Related guides Core PnL V2 concepts, endpoints, and how wallet indexing works. `price:aggregated` and `price-by-token` rooms — pair these with PnL for live unrealized PnL. Analyze wallet PnL, positions, trade timing, and exposure with the REST API. Combine live wallet activity with PnL streams for a real-time portfolio dashboard. # Stream Kalshi and Polymarket prices and trades Source: https://docs.solanatracker.io/guides/datastream-prediction-markets Stream Kalshi and Polymarket trades, prices, quotes, books, volume, and resolutions through Solana Tracker Datastream. Subscribe to `pm:*` rooms for prediction-market updates. Select an exchange, market, or event scope, and use the correct ID for that room. Price and orderbook subscriptions are market-specific. **Public Beta** — Prediction market rooms use the same Datastream hub as other Solana Tracker streams.\ Connect to `wss://datastream.solanatracker.io/{apiKey}` with your Data API key. ## Connecting ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "pm:trades" })); ws.send(JSON.stringify({ type: "join", room: "pm:market:polymarket:YOUR_TOKEN_ID:prices" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") console.log(msg.room, msg.data); }; ``` Join / leave: ```json theme={null} { "type": "join", "room": "pm:trades" } { "type": "leave", "room": "pm:trades" } ``` ## Room types | Room | Purpose | | - | - | | `pm:trades` | Full trade tape (all exchanges) | | `pm:trades:significant` | Trades with **notional ≥ \$25** | | `pm:{exchange}:trades` | e.g. `pm:polymarket:trades` | | `pm:market:{exchange}:{marketId}:trades` | Single-market tape | | `pm:event:{exchange}:{eventId}:trades` | All markets under one event | | `pm:market:{exchange}:{tokenId}:prices` | Live top-of-book mid (+ `displayPrice`) | | `pm:market:{exchange}:{tokenId}:quotes` | Streaming size-aware VWAP ladder | | `pm:market:{exchange}:{tokenId}:orderbook` | Full book snapshots | | `pm:event:{exchange}:{eventId}:volume` | Live cumulative USD volume for an event | | `pm:market:{exchange}:{tokenId}:volume` | Live cumulative USD volume for one outcome | | `pm:crypto:{asset}` | Chainlink underlying (BTC/ETH/…) — not outcome chance | | `pm:market_lifecycle` / `pm:resolution` | Lifecycle and resolution fan-out | Price, quote, and orderbook subscriptions require a market ID. There is no global `pm:prices` room. `notionalUsd` is `price × quantity` (USD). The significant room uses threshold **\$25**. Event rooms accept identities included in the payload, such as `eventId`, `eventSlug`, `gammaEventId`, or a Kalshi `eventTicker`. ## Volume example Crypto 5m windows — join with the **event slug**: ```json theme={null} { "type": "join", "room": "pm:event:polymarket:btc-updown-5m-1785347100:volume" } ``` ```json theme={null} { "type": "message", "room": "pm:event:polymarket:btc-updown-5m-1785347100:volume", "data": { "type": "volume", "channel": "volume", "exchange": "polymarket", "marketId": "{tokenId}", "timestamp": 1785347120123, "eventId": "btc-updown-5m-1785347100", "volume": 48210.55, "marketVolume": 24105.27, "delta": 42.5 } } ``` Replace the displayed volume with the latest frame. Fields include `volume`, `marketVolume`, `delta`, and `eventId`. ## Quotes vs REST Join `pm:market:polymarket:{tokenId}:quotes` for a streaming size-aware VWAP ladder. For arbitrary sizes use REST `GET /v1/markets/{id}/quote` on `prediction-market-api.solanatracker.io`. ## Prices vs crypto underlying | Feed | Room | Meaning | | - | - | - | | Outcome chance | `pm:market:polymarket:{tokenId}:prices` | CLOB top-of-book mid | | Underlying | `pm:crypto:{asset}` / `pm:crypto:{asset}:prices` | Chainlink USD ticks | ## IDs * Room segments are **lowercase**. * Polymarket market rooms require decimal **CLOB token IDs** (not `0x` condition ids). * Kalshi tickers appear uppercase in many REST payloads but **lowercase** in room names. ## API reference In the **Datastream** nav, Prediction Market rooms are grouped as: | Group | Rooms | | - | - | | Prediction Markets — Trades | `pm:trades`, significant, exchange / market / event trades | | Prediction Markets — Prices | market prices, quotes, orderbook | | Prediction Markets — Volume | event and market volume | | Prediction Markets — Lifecycle | lifecycle and resolution | | Prediction Markets — Crypto | `pm:crypto:{asset}` | | Prediction Markets — Feeds | exchange, market, event, type, category, series, status, sport | # Stream Solana token prices and update live charts Source: https://docs.solanatracker.io/guides/datastream-prices Subscribe to Solana token prices by pool or across pools. Combine REST candle history with Datastream ticks to update live charts. Choose a price room by scope: the primary pool, a specific pool, every pool, or an aggregate across pools. For charts, combine these ticks with historical candles from the Data API. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Available on Premium, Business, and Enterprise plans. ## Connect All Datastream channels use the same WebSocket connection. Send JSON messages to join and leave rooms. See the [Datastream protocol](/guides/datastream-protocol) for heartbeat (`ping`/`pong`), auth failures, and leave semantics. ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { console.log("Connected"); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "ping") { ws.send(JSON.stringify({ type: "pong" })); return; } if (msg.type === "message") { // Handle data } }; ``` ## Price by token Subscribe to `price-by-token:{tokenAddress}` for the primary pool's price. The primary pool is usually the one with the most liquidity. ```javascript theme={null} const token = "9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump"; // Join ws.send(JSON.stringify({ type: "join", room: `price-by-token:${token}` })); // Receive ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "joined") { console.log(`Subscribed to ${msg.room}`); } if (msg.type === "message") { const { price, price_quote, pool, time } = msg.data; console.log(`$${price} (${price_quote} SOL) at ${new Date(time).toISOString()}`); } }; // Leave when done ws.send(JSON.stringify({ type: "leave", room: `price-by-token:${token}` })); ``` **Payload:** ```json theme={null} { "type": "message", "room": "price-by-token:9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump", "data": { "price": 0.008006, "price_quote": 0.00010064, "pool": "EWiYmq3nWQpoTkcU4UfGYEoYvDHduDsXhpPvqmoqpump", "token": "9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump", "time": 1723728065246 } } ``` ## Aggregated price Subscribe to `price:aggregated:{tokenAddress}` for a cross-pool price summary. The payload includes median, average, minimum, maximum, and pool count. ```javascript theme={null} const sol = "So11111111111111111111111111111111111111112"; ws.send(JSON.stringify({ type: "join", room: `price:aggregated:${sol}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") { const { price, aggregated } = msg.data; console.log(`Price: $${price}`); console.log(`Median: $${aggregated.median} (${aggregated.poolCount} pools)`); console.log(`Range: $${aggregated.min} — $${aggregated.max}`); } }; ``` **Payload:** ```json theme={null} { "price": 153.70, "aggregated": { "median": 153.68, "average": 153.67, "min": 153.36, "max": 153.71, "poolCount": 10 }, "topPools": [...] } ``` ## Price by pool Subscribe to `price:{poolId}` for price updates from one specific pool. Use this when you care about a particular DEX or liquidity source. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "price:EWiYmq3nWQpoTkcU4UfGYEoYvDHduDsXhpPvqmoqpump" })); ``` ## All pool prices Subscribe to `price:{tokenAddress}` (without `aggregated`) to receive individual price updates from every pool a token trades on. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `price:${token}` })); ``` ## Token changes (full updates) Subscribe to `token:{tokenAddress}` when you need pool state beyond price, including liquidity, market cap, supply, and security fields. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `token:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") { const d = msg.data; console.log(`Price: $${d.price.usd}`); console.log(`Liquidity: $${d.liquidity.usd}`); console.log(`Market Cap: $${d.marketCap.usd}`); console.log(`LP Burn: ${d.lpBurn}%`); } }; ``` For primary pool only (less noise on multi-pool tokens): ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `token:${token}:primary` })); ``` ## Live transactions Subscribe to `transaction:{tokenAddress}` to see every swap as it happens. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `transaction:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") { const trades = Array.isArray(msg.data) ? msg.data : [msg.data]; trades.forEach(t => { const side = t.type === "buy" ? "BUY " : "SELL"; console.log(`${side} $${t.volume.toFixed(2)} by ${t.wallet}`); }); } }; ``` Filter by pool: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `transaction:${token}:${poolId}` })); ``` ## Build a live chart Load historical candles from the [OHLCV endpoint](/data-api/chart/get-ohlcv-data-for-a-token), then use price ticks to update the current candle's open, high, low, and close. Price ticks alone do not provide traded volume. ```javascript theme={null} const token = "9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump"; const headers = { "x-api-key": "YOUR_API_KEY" }; // 1. Load historical candles via REST const now = Math.floor(Date.now() / 1000); const candles = await fetch( `https://data.solanatracker.io/chart/${token}?type=1m&time_from=${now - 3600}&time_to=${now}`, { headers } ).then(r => r.json()); let currentCandle = candles[candles.length - 1]; // 2. Stream live price updates const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `price-by-token:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { price, time } = msg.data; const candleStart = Math.floor(time / 60000) * 60; if (candleStart > currentCandle.time) { // New candle candles.push(currentCandle); currentCandle = { time: candleStart, open: price, high: price, low: price, close: price, volume: 0 }; } else { // Update current candle currentCandle.close = price; currentCandle.high = Math.max(currentCandle.high, price); currentCandle.low = Math.min(currentCandle.low, price); } // Render candles + currentCandle to your chart library }; ``` ### Open-source chart examples These example repositories show how to connect the history and live feeds: Minimal real-time line chart using the Datastream WebSocket. Good starting point for custom UIs. Full TradingView Advanced Charts integration with real-time candle updates from the Datastream. ## Volume & statistics ### Token volume Subscribe to `volume:token:{tokenAddress}` for aggregated volume updates: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `volume:token:${token}` })); ``` ### Token statistics Subscribe to `stats:token:{tokenAddress}` for multi-timeframe stats (1m, 5m, 1h, 6h, 24h buy/sell counts, volume, unique traders): ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `stats:token:${token}` })); ``` For a single total snapshot: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `stats:token:${token}:total` })); ``` ## Room reference | Room pattern | What you get | | - | - | | `price-by-token:{token}` | Price from primary pool | | `price:aggregated:{token}` | Cross-pool median/avg/min/max | | `price:{pool}` | Price from one pool | | `price:{token}` | Price from all pools | | `token:{token}` | Full pool state (price, liquidity, mcap) | | `token:{token}:primary` | Primary pool state only | | `transaction:{token}` | All swaps on a token | | `transaction:{token}:{pool}` | Swaps in a specific pool | | `volume:token:{token}` | Aggregated volume | | `stats:token:{token}` | Multi-timeframe statistics | REST endpoints for historical OHLCV, price snapshots, and ATH data. Stream new tokens, graduating tokens, and market events. # Connect to Solana Tracker Datastream WebSocket Source: https://docs.solanatracker.io/guides/datastream-protocol Connect to Solana Tracker Datastream, authenticate with an API key, subscribe to rooms, and handle JSON heartbeats and connection errors. Connect once and join the rooms your app needs. Every Datastream subscription uses the same authentication, join/leave messages, and JSON heartbeat protocol. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Use your Data API key in the path. Available on Premium, Business, and Enterprise plans. ## Connection URL Always connect to the canonical Datastream host: ```text theme={null} wss://datastream.solanatracker.io/{apiKey} ``` Datastream authentication uses the API key in the WebSocket path. REST base URLs are separate from the Datastream host. ## Authentication failures An invalid or missing API key may still complete the WebSocket handshake, then close almost immediately with: * no JSON error payload * no `joined` acknowledgment If the connection closes immediately without a room acknowledgment, check the API key and URL before retrying. ## Join and leave ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "price-by-token:TOKEN_MINT" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "joined") { console.log("Subscribed", msg.room); } if (msg.type === "message") { // Room payload in msg.data } // Application heartbeat (not WebSocket protocol ping/pong) if (msg.type === "ping") { ws.send(JSON.stringify({ type: "pong" })); } }; // Call after joining when the app no longer needs this subscription. // There is no separate `left` acknowledgment. function unsubscribe() { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: "leave", room: "price-by-token:TOKEN_MINT" })); } } ``` | Envelope | Direction | Meaning | | - | - | - | | `{ "type": "join", "room" }` | Client → server | Subscribe | | `{ "type": "joined", "room" }` | Server → client | Subscribe confirmed | | `{ "type": "leave", "room" }` | Client → server | Unsubscribe (no `left` ack) | | `{ "type": "message", "room", "data" }` | Server → client | Room data | | `{ "type": "ping" }` | Server → client | App heartbeat | | `{ "type": "pong" }` | Client → server | Heartbeat reply | ## Heartbeat (JSON ping/pong) The server may emit a JSON control frame: ```json theme={null} { "type": "ping" } ``` Reply with: ```json theme={null} { "type": "pong" } ``` Reply to JSON heartbeats in your message handler. They are application messages, separate from WebSocket protocol ping/pong frames. ## Wallet balance amounts On `wallet:{wallet}:balance` and `wallet:{wallet}:{token}:balance`: * `amount` is a **UI decimal** (human units), not raw integer base units / lamports * native SOL uses mint `So11111111111111111111111111111111111111112` ```json theme={null} { "type": "message", "room": "wallet:WALLET:balance", "data": { "wallet": "WALLET", "token": "So11111111111111111111111111111111111111112", "amount": 1.2345 } } ``` ## Limits and quotas Premium+ Datastream includes **unlimited messages** (no per-message fees). There is **no limit** on concurrent WebSocket connections or rooms per connection. REST monthly request quotas do **not** disconnect an established Datastream session when exhausted. ## Next Price and candle rooms. Launches, graduations, and market events. Snipers, bundlers, and holder signals. Live wallet and position PnL. # Monitor Solana token risk signals over WebSocket Source: https://docs.solanatracker.io/guides/datastream-safety Stream sniper, bundler, insider, developer-holding, and concentration updates for Solana tokens with Datastream WebSocket rooms. Subscribe to the risk signals your app displays: sniper and bundler balances, insider activity, developer holdings, or concentration. Use the token risk API for the initial snapshot. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Available on Premium, Business, and Enterprise plans. ## Sniper tracking Subscribe to `sniper:{tokenAddress}` to get notified when a sniper wallet's balance changes — buys, sells, or partial exits. ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `sniper:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; const direction = d.percentage > d.previousPercentage ? "INCREASED" : "DECREASED"; console.log(`Sniper ${d.wallet} ${direction}`); console.log(` Balance: ${d.tokenAmount} (${d.percentage}%)`); console.log(` Previous: ${d.previousAmount} (${d.previousPercentage}%)`); console.log(` Total sniper hold: ${d.totalSniperPercentage}%`); console.log(` Total insider hold: ${d.totalInsiderPercentage}%`); }; ``` **Payload:** ```json theme={null} { "wallet": "WalletAddress", "amount": "1000000000", "tokenAmount": 1000000, "percentage": 0.15, "previousAmount": 500000, "previousPercentage": 0.075, "totalSniperPercentage": 5.25, "totalInsiderPercentage": 12.5 } ``` ## Bundler tracking Subscribe to `bundlers:{tokenAddress}` for changes in wallets associated with bundled transactions. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `bundlers:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; const action = d.tokenAmount > d.previousAmount ? "BOUGHT" : "SOLD"; console.log(`Bundler ${d.wallet} ${action}`); console.log(` Holdings: ${d.tokenAmount} (${d.percentage}%)`); console.log(` Total bundler hold: ${d.totalBundlerPercentage}%`); }; ``` **Payload:** ```json theme={null} { "wallet": "4ZwYf8okEL7vgyBDZEcas2mcpDAVujsgtthxRHCMDqyP", "amount": "7965607901843", "tokenAmount": 7965607.901843, "percentage": 0.79656, "previousAmount": 8997866.309773, "previousPercentage": 0.89979, "boughtAmount": 0, "boughtPercentage": 0, "totalBundlerPercentage": 22.83809 } ``` Use `totalBundlerPercentage` to measure the supply held by detected bundled wallets. Treat any alert threshold as an application choice. ## Insider tracking Subscribe to `insider:{tokenAddress}` for changes in wallets identified by the API's insider signals. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `insider:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; console.log(`Insider ${d.wallet}: ${d.percentage}% (was ${d.previousPercentage}%)`); console.log(` Total insider hold: ${d.totalInsiderPercentage}%`); }; ``` ## Developer holdings Subscribe to `dev_holding:{tokenAddress}` to monitor changes in developer holdings. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `dev_holding:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const d = msg.data; const change = d.percentage - d.previousPercentage; const emoji = change < 0 ? "SOLD" : "ADDED"; console.log(`Dev ${d.creator} ${emoji}: ${d.percentage}% (was ${d.previousPercentage}%)`); }; ``` **Payload:** ```json theme={null} { "token": "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", "creator": "4Rz5xqikxtZ2s7wE9uQ6n2oLXQi6K65XGoYpKxf24Hqo", "amount": "150000000000", "percentage": 15.0, "previousPercentage": 20.0, "timestamp": 1739318753652 } ``` ## Holder changes ### Holder count Subscribe to `holders:{tokenAddress}` for real-time holder count updates: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `holders:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") { console.log(`Holders: ${msg.data.total}`); } }; ``` ### Top 10 holders Subscribe to `top10:{tokenAddress}` to track concentration among the top 10 wallets: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `top10:${token}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const totalPct = msg.data.holders.reduce((sum, h) => sum + h.percentage, 0); console.log(`Top 10 hold ${totalPct.toFixed(1)}% of supply`); msg.data.holders.forEach((h, i) => { console.log(` #${i + 1} ${h.address}: ${h.percentage}%`); }); }; ``` ## Wallet monitoring ### Wallet transactions Subscribe to `wallet:{walletAddress}` to see every swap a wallet makes in real time: ```javascript theme={null} const wallet = "FV1r15rbNKkJanXLheoJA7fXEq6NDuMJ3bukXuhJWyV1"; ws.send(JSON.stringify({ type: "join", room: `wallet:${wallet}` })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const t = msg.data; const fromToken = t.from?.token?.symbol; const toToken = t.to?.token?.symbol; console.log(`${fromToken} → ${toToken}: $${t.volume?.usd?.toFixed(2)}`); }; ``` ### Wallet balance changes Subscribe to `wallet:{walletAddress}:balance` for overall balance changes: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `wallet:${wallet}:balance` })); ``` ### Specific token balance Subscribe to `wallet:{walletAddress}:{tokenAddress}:balance` to watch a single token balance: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `wallet:${wallet}:${token}:balance` })); ``` ## Fee tracking Subscribe to `fees:{tokenAddress}` to track platform and network fees on a token: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `fees:${token}` })); ``` ## Example: token safety monitor Combine multiple safety streams to build a real-time risk dashboard: ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); const alerts = []; ws.onopen = () => { // Subscribe to all safety signals ws.send(JSON.stringify({ type: "join", room: `sniper:${token}` })); ws.send(JSON.stringify({ type: "join", room: `bundlers:${token}` })); ws.send(JSON.stringify({ type: "join", room: `insider:${token}` })); ws.send(JSON.stringify({ type: "join", room: `dev_holding:${token}` })); ws.send(JSON.stringify({ type: "join", room: `top10:${token}` })); ws.send(JSON.stringify({ type: "join", room: `holders:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const room = msg.room; const d = msg.data; if (room.startsWith("sniper:") && d.percentage < d.previousPercentage) { alerts.push(`Sniper selling: ${d.wallet} (${d.previousPercentage}% → ${d.percentage}%)`); } if (room.startsWith("bundlers:") && d.totalBundlerPercentage > 20) { alerts.push(`High bundler concentration: ${d.totalBundlerPercentage}%`); } if (room.startsWith("dev_holding:") && d.percentage < d.previousPercentage) { alerts.push(`Dev selling: ${d.percentage}% (was ${d.previousPercentage}%)`); } if (room.startsWith("top10:")) { const totalPct = d.holders.reduce((sum, h) => sum + h.percentage, 0); if (totalPct > 50) { alerts.push(`Top 10 hold ${totalPct.toFixed(1)}% — high concentration`); } } if (alerts.length > 0) { console.log(`[ALERT] ${alerts[alerts.length - 1]}`); } }; ``` ## Room reference | Room | What you get | | - | - | | `sniper:{token}` | Sniper wallet balance changes | | `bundlers:{token}` | Bundler wallet activity | | `insider:{token}` | Insider wallet movements | | `dev_holding:{token}` | Developer/creator holdings | | `holders:{token}` | Total holder count | | `top10:{token}` | Top 10 holder percentages | | `wallet:{wallet}` | All swaps for a wallet | | `wallet:{wallet}:balance` | Wallet balance changes | | `wallet:{wallet}:{token}:balance` | Specific token balance | | `fees:{token}` | Fee tracking | REST endpoints for first buyers, bundlers, and chart-based detection. Stream real-time prices and build live charts. # Stream new Solana tokens and graduations Source: https://docs.solanatracker.io/guides/datastream-tokens Subscribe to new Solana token launches, bonding curve milestones, graduation events, and metadata changes with Datastream. Use `latest` for new indexed tokens and pools, `graduating` for tokens near curve completion, and `graduated` for migrations. Add curve or metadata subscriptions when you need those updates. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Available on Premium, Business, and Enterprise plans. ## New tokens Subscribe to `latest` for newly indexed tokens and pools. ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "latest" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools } = msg.data; console.log(`New: ${token.name} (${token.symbol})`); console.log(` Mint: ${token.mint}`); console.log(` Created on: ${token.createdOn}`); console.log(` Pool: ${pools[0]?.poolId}`); console.log(` Deployer: ${pools[0]?.deployer}`); }; ``` **Payload includes:** * Token metadata (name, symbol, mint, image, description, socials) * Pool details (DEX, liquidity, initial price, market cap) * Creation info (creator wallet, creation tx, timestamp) ## Graduating tokens Subscribe to `graduating` for tokens approaching bonding curve completion. Filter the feed by market and threshold when you need a narrower set. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "graduating" })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools } = msg.data; const curve = pools[0]?.curvePercentage; console.log(`Graduating: ${token.name} — ${curve}% curve`); console.log(` MC: $${pools[0]?.marketCap?.usd?.toLocaleString()}`); }; ``` ### Filter by market and SOL threshold Narrow down graduating tokens by market and minimum SOL in the curve: ```javascript theme={null} // Only pump.fun tokens with at least 50 SOL ws.send(JSON.stringify({ type: "join", room: "graduating:pumpfun:50" })); // Only launchpad tokens with at least 100 SOL ws.send(JSON.stringify({ type: "join", room: "graduating:launchpad:100" })); ``` ## Graduated tokens Subscribe to `graduated` for token migration notifications. ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "graduated" })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools } = msg.data; console.log(`Graduated: ${token.name}`); console.log(` New pool: ${pools[0]?.poolId}`); console.log(` Liquidity: $${pools[0]?.liquidity?.usd?.toLocaleString()}`); }; ``` ## Curve percentage alerts Subscribe to `{market}:curve:{percentage}` to get alerted when any token on a specific market hits a bonding curve milestone. Supported markets: `pumpfun`, `launchpad`, `boop`, `meteora-curve`. ```javascript theme={null} // Alert when pump.fun tokens hit 30% curve ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:30" })); // Alert at 50% ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:50" })); // Alert at 80% ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:80" })); ``` Choose milestones that match the states you display, such as a watchlist threshold and a near-completion alert. ## Token metadata changes Subscribe to `metadata:{tokenAddress}` to get notified when a token updates its metadata (name, image, socials, etc.): ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: `metadata:${token}` })); ``` ## Example: new token scanner Filter the incoming launch feed before adding rows to the UI: ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "latest" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools } = msg.data; const pool = pools[0]; if (!pool) return; // Filter: only tokens with socials and decent liquidity const hasSocials = token.strictSocials?.twitter || token.strictSocials?.telegram; const hasLiquidity = pool.liquidity?.usd > 1000; if (hasSocials && hasLiquidity) { console.log(`✓ ${token.name} (${token.symbol})`); console.log(` MC: $${pool.marketCap?.usd?.toLocaleString()}`); console.log(` Liq: $${pool.liquidity?.usd?.toLocaleString()}`); console.log(` Twitter: ${token.strictSocials?.twitter || "—"}`); } }; ``` ## Example: graduation pipeline Watch tokens across their full lifecycle: ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { // Watch the full pipeline ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:50" })); ws.send(JSON.stringify({ type: "join", room: "graduating" })); ws.send(JSON.stringify({ type: "join", room: "graduated" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const room = msg.room; const name = msg.data?.token?.name || "Unknown"; if (room?.includes("curve:")) { console.log(`[50% CURVE] ${name} — halfway through bonding curve`); } else if (room === "graduating") { console.log(`[GRADUATING] ${name} — approaching completion`); } else if (room === "graduated") { console.log(`[GRADUATED] ${name} — now on DEX`); } }; ``` ## Room reference | Room | What you get | | - | - | | `latest` | Every new token/pool created | | `graduating` | Tokens approaching curve completion | | `graduating:{market}:{sol}` | Filtered by market and SOL threshold | | `graduated` | Tokens that just moved to DEX | | `{market}:curve:{pct}` | Tokens hitting a curve percentage milestone | | `metadata:{token}` | Metadata changes | REST endpoints for trending, volume leaders, and top performers. Track snipers, bundlers, insiders, and holder changes in real time. # Solana API guides Source: https://docs.solanatracker.io/guides/index Build with Solana Tracker APIs: query tokens and wallets, stream trades and liquidity, calculate PnL, and send swaps. Choose a guide for the data or transaction flow you need. Each guide includes requests you can adapt and links to the endpoint reference. Query metadata, prices, holders, and risk. Find launches and build token pages. Load holdings and trades, inspect positions, and compare wallet returns. Connect to Datastream for prices, swaps, liquidity, holder changes, and PnL. Follow launches and graduations, or decode bonding curve and PumpSwap instructions. Query Kalshi and Polymarket data, then subscribe to market updates. Build swaps with Raptor, resolve wallet names, and find address lookup tables. ## Start with your API key Create an API key in the [dashboard](https://www.solanatracker.io/account), then follow the [quickstart](/quickstart) for your first request. REST examples use the `x-api-key` header. Datastream uses the key in its WebSocket URL. ## Need a parameter or response schema? Open the [Data API reference](/data-api/search/token-search), [Datastream rooms](/datastream/websockets/latesttokens), or [Solana RPC reference](/solana-rpc/http/getaccountinfo). Guides explain how to use the endpoints together. # Track Solana KOL wallets and performance Source: https://docs.solanatracker.io/guides/kol-tracking Compare Solana KOL wallet PnL, view daily activity, and inspect positions. Connect performance analysis to live KOL trade feeds. The KOL endpoints cover tracked wallets with public identity labels. Start with the leaderboard, choose a time window, and open a wallet's positions to understand its results. KOLScan leaderboard showing KOL wallet PnL, volume, and active days ## List all KOLs The [KOL leaderboard](/data-api/pnl-v2/leaderboard/get-kol-leaderboard) returns the tracked KOL roster with performance metrics and available identity labels. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols?sort=realized&direction=desc&limit=25" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://data.solanatracker.io/v2/pnl/leaderboard/kols?sort=realized&direction=desc&limit=25", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); traders.forEach((kol, i) => { console.log(`#${i + 1} ${kol.identity.name} (@${kol.identity.twitter})`); console.log(` PnL: $${kol.pnl.realized.toLocaleString()}, Win Rate: ${kol.winRate}%`); }); ``` ```python Python theme={null} import requests res = requests.get( "https://data.solanatracker.io/v2/pnl/leaderboard/kols", params={"sort": "realized", "direction": "desc", "limit": 25}, headers={"x-api-key": "YOUR_API_KEY"} ) for i, kol in enumerate(res.json()["traders"], 1): print(f"#{i} {kol['identity']['name']}: ${kol['pnl']['realized']:,.2f}") ``` ### Sort options | Field | Description | | - | - | | `total` | Total PnL (realized + unrealized) | | `realized` | Locked-in profit | | `unrealized` | Paper profit on open positions. Open positions are tokens still held. | | `invested` | Total USD put in | | `roi` | Return on investment | | `win_percentage` | Win rate | | `trades` | Number of trades | | `tokens` | Number of tokens traded | | `last_trade` | Most recent activity | ## Compare KOLs over a time period Use the [period leaderboard](/data-api/pnl-v2/leaderboard/get-kol-leaderboard-for-a-period) to compare wallets over the same window. Lifetime totals and recent returns answer different questions. ```bash Last 7 days theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/period?period=7d&sort=realized&direction=desc" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash Custom range theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/period?start=2025-03-01&end=2025-03-31&sort=realized" \ -H "x-api-key: YOUR_API_KEY" ``` Supported `period` shortcuts: `1d`, `7d`, `14d`, `30d`, `90d`. ## KOL calendar (monthly heatmap) The [calendar endpoint](/data-api/pnl-v2/leaderboard/get-kol-calendar) returns daily aggregate performance for the tracked KOL set. ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/calendar?year=2025&month=3" \ -H "x-api-key: YOUR_API_KEY" ``` Each day includes total PnL, trade count, and active KOL count across the tracked set. Color days by aggregate PnL to spot market-wide trends at a glance. ## Single-day KOL breakdown The [daily breakdown](/data-api/pnl-v2/leaderboard/get-kol-daily-breakdown) shows every tracked KOL's activity for one specific day. ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/date?date=2025-03-15" \ -H "x-api-key: YOUR_API_KEY" ``` Use the daily breakdown to inspect which wallets traded and how their PnL changed on that date. ## Drill into a KOL's wallet Pass a leaderboard wallet address to the summary and position endpoints for the underlying holdings and returns: ```javascript theme={null} // Get the KOL's full wallet summary const wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o"; // from leaderboard const summary = await fetch( `https://data.solanatracker.io/v2/pnl/wallets/${wallet}`, { headers: { "x-api-key": "YOUR_API_KEY" } } ).then(r => r.json()); console.log(`Total PnL: $${summary.summary.pnl.total.toFixed(2)}`); console.log(`Win Rate: ${summary.analysis.winRate}%`); console.log(`Tokens Traded: ${summary.summary.counts.tokensTraded}`); // Then get their current positions const positions = await fetch( `https://data.solanatracker.io/v2/pnl/wallets/${wallet}/positions?sort=value&direction=desc&limit=10`, { headers: { "x-api-key": "YOUR_API_KEY" } } ).then(r => r.json()); positions.data.forEach(p => { console.log(`${p.meta.symbol}: $${p.pnl.total.toFixed(2)} PnL, holding $${p.position.valueUsd.toFixed(2)}`); }); ``` ## Follow new KOL trades Use the [whale and KOL trade feed](/guides/whale-kol) for new swaps. `GET /trades/kols` loads recent activity; the `transaction:kol` Datastream room keeps it current. Use the leaderboard for performance comparisons and the trade feed for alerts. Full guide for inspecting any wallet's PnL, positions, and risk. KOL and top trader rankings with all sort and filter options. # Compare Solana DEX and launchpad activity Source: https://docs.solanatracker.io/guides/lighthouse Compare Solana DEX and launchpad volume, transactions, active wallets, token launches, and migrations across rolling windows with Lighthouse. Lighthouse returns market-wide activity in one request. Compare volume, transactions, wallets, launches, and migrations across `5m`, `1h`, `6h`, and `24h` windows. * Market overview dashboards * DEX and launchpad leaderboards * “What is moving right now?” discovery pages * Volume and transaction trend cards * Pump.fun, Raydium, Meteora, and other venue comparisons ## Fetch market stats ```bash theme={null} curl "https://data.solanatracker.io/lighthouse" \ -H "x-api-key: YOUR_API_KEY" ``` Read each array entry as one market or market-family rollup: ```json theme={null} { "market": "pumpfun", "label": "Pump.fun", "icon": "https://...", "url": "https://pump.fun", "stats": { "5m": { "transactions": { "total": 120, "buys": 72, "sells": 48, "changePct": 18.4 }, "wallets": { "total": 96, "changePct": 11.2 }, "volume": { "total": 185000, "buys": 112000, "sells": 73000, "changePct": 24.7 }, "tokensCreated": { "total": 34, "changePct": 8.1 }, "migrations": { "total": 5, "changePct": 25 } } } } ``` Every market includes the same four windows: ```text theme={null} 5m 1h 6h 24h ``` `changePct` compares the current window with the previous window of the same length. For example, the `1h` change compares the latest hour with the hour immediately before it. ## Build a market leaderboard Sort markets by a metric such as recent volume: ```javascript theme={null} const response = await fetch( "https://data.solanatracker.io/lighthouse", { headers: { "x-api-key": process.env.SOLANA_TRACKER_API_KEY, }, } ); const markets = await response.json(); const byRecentVolume = markets .filter((market) => market.stats?.["1h"]) .sort( (a, b) => b.stats["1h"].volume.total - a.stats["1h"].volume.total ); for (const market of byRecentVolume.slice(0, 10)) { const stats = market.stats["1h"]; console.log( `${market.label}: $${stats.volume.total.toLocaleString()} ` + `(${stats.volume.changePct >= 0 ? "+" : ""}${stats.volume.changePct}%)` ); } ``` ## Create a market overview card Use the `all` market for a site-wide summary, then compare individual markets: ```javascript theme={null} const all = markets.find((market) => market.market === "all"); const pumpfun = markets.find((market) => market.market === "pumpfun"); function overview(market) { const stats = market?.stats?.["5m"]; if (!stats) return null; return { label: market.label, volumeUsd: stats.volume.total, transactions: stats.transactions.total, wallets: stats.wallets.total, tokensCreated: stats.tokensCreated.total, migrations: stats.migrations.total, volumeChangePct: stats.volume.changePct, }; } console.log(overview(all)); console.log(overview(pumpfun)); ``` ## Understand market IDs Use `market` as the identifier and `label` as the display name. Entries can represent a venue, a family of markets, or a launchpad within a family: | Market ID | Meaning | | - | - | | `all` | All indexed markets | | `pumpfun` | Pump.fun activity | | `raydium-all` | Raydium family rollup | | `meteora-curve:bags` | A discovered launchpad under a market family | Each entry also includes: * `label` — display name * `icon` — branding URL when available * `url` — project or venue URL when available * `parent` — parent market for a launchpad child Treat `icon` and `url` as optional presentation data; they may be empty when branding is unavailable. ## Handle zero-activity windows A window with no activity contains zero-valued metrics. When there is no previous activity to compare, `changePct` is `0`: ```javascript theme={null} const volume = market.stats["5m"].volume; if (volume.total === 0) { console.log(`${market.label} is quiet right now`); } else { console.log(`${market.label} has $${volume.total} in recent volume`); } ``` Browse the endpoint, response schema, time windows, and market fields. Move from market-level signals to token-level research. Track Pump.fun launches, curves, graduations, and swaps. Follow the wallets driving high-value activity. # Track Solana liquidity additions and removals Source: https://docs.solanatracker.io/guides/liquidity Query Solana liquidity history and stream LP additions and removals by token, pool, or wallet. Combine liquidity with swaps and wallet identity. Load LP activity with the trade-history API, then subscribe to a liquidity room for live additions and removals. Keep token amounts as strings and reconcile live events with confirmed history. Combine swaps and liquidity, or request only liquidity transactions. Follow a token, a pool, or a liquidity provider with five room scopes. ## Query liquidity history The four token trade-history routes accept `events` and `enrich`. Choose the scope you need: ```http theme={null} GET /trades/{token}?events=all GET /trades/{token}/{pool}?events=liquidity GET /trades/{token}/by-wallet/{wallet}?events=all&enrich=identity GET /trades/{token}/{pool}/{wallet}?events=liquidity&sortDirection=ASC ``` * **`events=trades`** is the default: buys and sells only. * **`events=all`** returns swaps, liquidity additions, and liquidity removals in one chronological feed. * **`events=liquidity`** returns only `add_liquidity` and `remove_liquidity` events. * **`enrich=identity`** adds current wallet identity to each returned row, including available KOL profiles, tags, trading platforms, developer/pool labels, and SNS names. Unknown wallets return `identity: null`. Every mode returns a **`trades` array**. These filters apply to the four token-scoped routes above, not the wallet-wide, whale/KOL, or perpetual endpoints. ```bash Liquidity only theme={null} curl --get "https://data.solanatracker.io/trades/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" \ --header "x-api-key: YOUR_API_KEY" \ --data-urlencode "events=liquidity" \ --data-urlencode "enrich=identity" \ --data-urlencode "limit=50" ``` ```javascript Swaps and liquidity theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const url = new URL(`https://data.solanatracker.io/trades/${token}`); url.search = new URLSearchParams({ events: "all", limit: "50" }); const response = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" }, }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); const page = await response.json(); for (const event of page.trades) { if (event.type === "add_liquidity" || event.type === "remove_liquidity") { console.log(event.type, event.pool, event.tokens); } else { console.log(event.type, event.amount, event.priceUsd); } } ``` ### Use the TypeScript SDK Install `@solana-tracker/data-api` version **0.5.0 or later**. The history methods accept `events`, `enrich`, `limit`, and `sortDirection`; pass `nextCursor` back unchanged to load more activity. ```typescript theme={null} import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const token = '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'; const filters = { events: 'all', enrich: 'identity', limit: 100, sortDirection: 'DESC', } as const; const page = await client.getTokenTradeHistory(token, filters); for (const event of page.trades) { if (event.type === 'add_liquidity' || event.type === 'remove_liquidity') { console.log(event.type, event.pool, event.tokens, event.identity); } else if (event.type === 'buy' || event.type === 'sell') { console.log(event.type, event.amount, event.volume); } } if (page.hasNextPage && page.nextCursor != null) { const nextPage = await client.getTokenTradeHistory(token, { ...filters, cursor: page.nextCursor, }); console.log(nextPage.trades); } ``` ### Load the next page Use `limit` from `1` to `500` (default `250`) and `sortDirection=DESC` for newest first or `ASC` for oldest first. For `events=all` and `events=liquidity`, `nextCursor` is an **opaque string**. Pass it back unchanged with the same token, pool, wallet, `events`, and `sortDirection`. ```javascript theme={null} if (page.hasNextPage && page.nextCursor !== null) { url.searchParams.set("cursor", String(page.nextCursor)); const nextResponse = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" }, }); if (!nextResponse.ok) throw new Error(`Request failed: ${nextResponse.status}`); const nextPage = await nextResponse.json(); console.log(nextPage.trades); } ``` The cursor preserves multiple actions at the same timestamp. Do not replace it with the last event's time or reuse it after changing filters. Default trades-only requests retain their timestamp cursor; opt-in feeds also accept a numeric timestamp as an exclusive initial boundary. `showMeta=true` adds token metadata to the **swap rows** only. Liquidity rows keep exact token amounts without swap prices, USD volume, or PnL. `hideArb` does not remove liquidity actions. Omit `enrich` when you do not need wallet identity. ## Stream liquidity live Connect to `wss://datastream.solanatracker.io/{apiKey}` with your Data API key. Datastream is available on Premium, Business, and Enterprise plans. ### Choose a room * **`liquidity:{mint}`** — all liquidity actions involving a token. * **`liquidity:{mint}:{pool}`** — a token's activity in one pool. * **`liquidity:{mint}:{pool}:{wallet}`** — one wallet's activity for that token and pool. * **`liquidity:pool:{pool}`** — all liquidity actions in a pool. * **`liquidity:wallet:{wallet}`** — a liquidity provider's activity across pools and tokens. Replace the placeholders with Solana addresses. Join and leave use the same protocol as other Datastream rooms: ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const room = `liquidity:${token}`; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room })); }; ws.onmessage = ({ data }) => { const message = JSON.parse(data); if (message.type === "ping") { ws.send(JSON.stringify({ type: "pong" })); return; } if (message.type === "error") { console.error("Datastream error", message); return; } if (message.type !== "message" || message.room !== room) return; for (const event of message.data) { const action = event.type === "add_liquidity" ? "Added" : "Removed"; for (const token of event.tokens) { console.log(`${action} ${token.amount} of ${token.address}`, event.pool); } } }; // To unsubscribe while keeping the connection open: // ws.send(JSON.stringify({ type: "leave", room })); ``` ### Subscribe with the SDK The SDK handles heartbeats and reconnects. Set `{ enriched: true }` for wallet labels, or omit it for the base room. Liquidity callbacks receive one event at a time. ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const stream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); stream.on('error', console.error); await stream.connect(); const sub = stream.subscribe.liquidity .token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { enriched: true }) .on((event) => { console.log(event.type, event.pool, event.tokens, event.identity); }); // sub.unsubscribe(); // stream.disconnect(); ``` See the [Datastream protocol guide](/guides/datastream-protocol) for authentication errors, heartbeat handling, reconnecting, and resubscribing. Existing `transaction:*` rooms contain swaps; subscribe to liquidity rooms separately to show both kinds of activity. ### Add wallet identity to live events Append **`:enriched`** to any liquidity room. The same suffix works on transaction, wallet, and whale/KOL rooms: ```json theme={null} { "type": "join", "room": "liquidity:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN:enriched" } ``` With enrichment, events include `identity`. Unknown wallets return `null`. An incomplete lookup adds `identityStatus: "partial"`; that notification does not receive a later identity correction. Enriched notifications can arrive later or in a different order. Identity reflects current, cached labels, not labels at the event's historical time. Token rooms use the requested token's identity context; pool and wallet liquidity rooms use the first non-quote token, or the first token if both are quote tokens. ## Read a liquidity event The following is an illustrative payload. WebSocket messages wrap these events in `{ "type": "message", "room": "...", "data": [...] }`; REST returns them in `trades`. ```json theme={null} { "tx": "TRANSACTION_SIGNATURE", "type": "add_liquidity", "program": "pumpfun-amm", "programId": "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA", "instruction": "deposit", "pool": "POOL_ADDRESS", "wallet": "LIQUIDITY_PROVIDER_ADDRESS", "time": 1789722000000, "slot": 370000000, "amountBasis": "transfer", "tokens": [ { "address": "TOKEN_MINT", "amount": "123.000001", "amountRaw": "123000001", "decimals": 6 }, { "address": "So11111111111111111111111111111111111111112", "amount": "9.000000001", "amountRaw": "9000000001", "decimals": 9 } ] } ``` * **`type`** distinguishes `add_liquidity` and `remove_liquidity`. A rebalance can produce a separate removal and addition. * **`pool`** is a single pool address. **`wallet`** is the owner or authority identified by the instruction, which can be a delegate or program-derived address. * **`tokens[]`** contains the participating mints. One-sided operations can have one entry; zero amounts are omitted. * **`amount`** is an exact decimal string; **`amountRaw`** is an integer string. Keep them as strings, or use decimal arithmetic and `BigInt`, to preserve precision. * **`time`** is Unix milliseconds. **`slot`** identifies the Solana slot. * **`amountBasis: "transfer"`** means gross token transfers across the pool vault, before Token-2022 withholding. It does not promise the net amount credited to a recipient. * **`amountBasis: "principal"`** separates liquidity principal from fees or internal reallocations. Raydium CLMM removals can also include `feeAmountRaw` and `transferredAmountRaw` on each token. Multiple actions can share a transaction signature, pool, and wallet. Do not collapse a feed to one event per signature. Internal event IDs are not exposed; use the returned cursor for REST pagination. ## Live events and confirmed history Live liquidity events are **provisional at processed commitment**. REST history contains confirmed/finalized activity using canonical block time, so its timestamp can differ from the live event. Provisional activity can disappear on a fork, and there is no rollback notification. Overlapping subscriptions deliver activity through each matching room. A two-token action can appear in both token rooms and both token history feeds. Subscribe to the narrowest scope you need, and use REST history to reconcile your display after reconnecting. ## Supported liquidity activity Supported instruction families include Raydium AMM v4, CPMM and CLMM; Orca Whirlpool; Pump AMM; Meteora DAMM v1/v2 and DLMM; Liquid Swap; and Futarchy. Coverage depends on the instruction and available on-chain data, rather than every funding action on every DEX. Standalone fee/reward claims, LP token minting/burning, rent, and unrelated transfers are excluded. Bonding-curve swaps remain trades. Liquidity activity does not contribute to swap volume, price candles, or swap PnL. ## API reference * [Liquidity room reference](/datastream/websockets/liquiditytoken) * [Token trades](/data-api/trades/get-token-trades) * [Pool-specific trades](/data-api/trades/get-pool-specific-trades) * [Wallet-specific token trades](/data-api/trades/get-user-specific-token-trades) * [Wallet-specific pool trades](/data-api/trades/get-user-specific-pool-trades) * [Stream swaps alongside liquidity](/guides/live-transactions) # Stream Solana holder counts and concentration Source: https://docs.solanatracker.io/guides/live-holder-updates Subscribe to Solana token holder counts and top-10 concentration updates. Combine live events with holder snapshots from the Data API. Use `holders:{token}` for holder-count changes and `top10:{token}` for concentration updates. Load the initial holder snapshot from REST, then use these rooms to keep the display current. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Available on Premium, Business, and Enterprise plans. ## Live holder count Subscribe to `holders:{tokenAddress}` to receive a message every time the total number of unique holders changes. Use this value for the holder-count display or a count-change alert. ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `holders:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; console.log(`Holders: ${msg.data.total}`); }; ``` **Payload:** ```json theme={null} { "type": "message", "room": "holders:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", "data": { "total": 14823 } } ``` ## Top 10 holder concentration Subscribe to `top10:{tokenAddress}` for updates to top-10 holder concentration. Use the percentage for concentration alerts. Query holder snapshots when you need the underlying wallet rows. ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `top10:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { holders } = msg.data; const totalConcentration = holders.reduce((sum, h) => sum + h.percentage, 0); console.log(`Top 10 hold ${totalConcentration.toFixed(1)}% of supply`); holders.forEach((h, i) => { console.log(` #${i + 1} ${h.address}: ${h.percentage.toFixed(2)}%`); }); // Risk warning: top 10 suddenly hold a much larger share if (totalConcentration > 50) { console.log("🚨 Top 10 concentration above 50% — high risk"); } }; ``` **Payload:** ```json theme={null} { "type": "message", "room": "top10:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", "data": { "holders": [ { "address": "4Rz5xqikxtZ2s7wE9uQ6n2oLXQi6K65XGoYpKxf24Hqo", "percentage": 12.5 }, { "address": "FV1r15rbNKkJanXLheoJA7fXEq6NDuMJ3bukXuhJWyV1", "percentage": 8.3 } ] } } ``` ## Watch both signals together Join both rooms on the same connection to track count and concentration together: ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); let holderCount = 0; let top10Pct = 0; ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `holders:${token}` })); ws.send(JSON.stringify({ type: "join", room: `top10:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const room = msg.room ?? ""; if (room.startsWith("holders:")) { holderCount = msg.data.total; console.log(`[HOLDERS] Total: ${holderCount}`); } if (room.startsWith("top10:")) { top10Pct = msg.data.holders.reduce((sum, h) => sum + h.percentage, 0); console.log(`[TOP10] Concentration: ${top10Pct.toFixed(1)}%`); } }; ``` ## Auto-reconnect pattern Reconnect after an interrupted connection and rejoin the rooms. Refresh the REST snapshot if the disconnect may have left a gap: ```javascript theme={null} function connectHolderStream(token, onHolderUpdate, onTop10Update) { let ws; let reconnectTimeout; function connect() { ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { console.log("Connected — subscribing to holder streams"); ws.send(JSON.stringify({ type: "join", room: `holders:${token}` })); ws.send(JSON.stringify({ type: "join", room: `top10:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; if (msg.room?.startsWith("holders:")) onHolderUpdate(msg.data); if (msg.room?.startsWith("top10:")) onTop10Update(msg.data); }; ws.onclose = () => { console.log("Disconnected — reconnecting in 3s"); reconnectTimeout = setTimeout(connect, 3000); }; ws.onerror = (err) => { console.error("WebSocket error:", err); ws.close(); }; } connect(); return () => { clearTimeout(reconnectTimeout); ws?.close(); }; } // Usage const stopWatching = connectHolderStream( "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", (data) => console.log("Holders:", data.total), (data) => { const pct = data.holders.reduce((s, h) => s + h.percentage, 0); if (pct > 50) console.log("🚨 Risk warning: top 10 hold", pct.toFixed(1) + "%"); } ); ``` ## Room reference | Room | Updates when | | - | - | | `holders:{token}` | Total holder count changes | | `top10:{token}` | Any top 10 wallet buys, sells, or exits | ## Related guides * [Get All Holders (REST)](/guides/token-holders) — fetch a full snapshot of the holder list * [Safety Streams](/guides/datastream-safety) — also covers sniper, bundler, insider, and dev holding changes * [Token Safety & Rugcheck](/guides/token-safety) — use the risk score API for a point-in-time safety check # Stream Solana token swaps over WebSocket Source: https://docs.solanatracker.io/guides/live-transactions Build a Solana trade feed with Datastream token and pool subscriptions. Filter swaps by size or wallet and handle reconnects. Subscribe to `transaction:{tokenAddress}` for a token's live swap feed. Narrow the room to a pool or wallet when needed. Liquidity additions and removals use separate rooms. **Track liquidity too.** Subscribe to `liquidity:{mint}` for additions and removals, or use `events=all` on the token trade API to combine them with swaps. [Follow the liquidity guide](/guides/liquidity). Append `:enriched` to transaction or liquidity rooms for wallet identity. **URL:** `wss://datastream.solanatracker.io/{apiKey}`\ Available on Premium, Business, and Enterprise plans. ## Subscribe to a token's trades Join the `transaction:{tokenAddress}` room to receive all swaps for a token: ```javascript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: `transaction:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; // msg.data is an array of transactions msg.data.forEach(tx => { const side = tx.type === "buy" ? "BUY " : "SELL"; const usd = tx.volume.toFixed(2); const price = tx.priceUsd.toFixed(6); console.log(`${side} $${usd} @ $${price} — ${tx.wallet.slice(0, 8)}... via ${tx.program}`); }); }; ``` **Transaction payload:** ```json theme={null} { "tx": "5V4apVkgHf49J5acYPiuh5rB89EGsF8ocSysgnD9vFfZsTtDamhN3MFDKJSq7Dn7Z6Y5XhjghuVYuvvYWnSFpnvW", "amount": 90, "priceUsd": 6.002467911111111, "solVolume": 2.956, "volume": 540.22, "type": "sell", "wallet": "F7R61te4Ac8xZ4pfkJUdF6iaaHy9tnM8nVRUPv8H8EMi", "time": 1760201288835, "program": "raydium", "token": { "from": { "name": "OFFICIAL TRUMP", "symbol": "TRUMP", "amount": 90 }, "to": { "name": "USD Coin", "symbol": "USDC", "amount": 540.22 } } } ``` ## Whale alerts Filter incoming trades by USD volume to fire a whale alert when a large buy or sell hits: ```javascript theme={null} const WHALE_THRESHOLD_USD = 10000; // $10k+ ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; msg.data.forEach(tx => { if (tx.volume >= WHALE_THRESHOLD_USD) { const side = tx.type === "buy" ? "🟢 WHALE BUY" : "🔴 WHALE SELL"; console.log(`${side} — $${tx.volume.toLocaleString()} by ${tx.wallet}`); // trigger your alert: push notification, Discord webhook, etc. } }); }; ``` ## Detect sniper buys at launch A launch feed can highlight early buys by combining trade time, token creation time, and trade size. Treat this as an activity filter, not a bot classification: ```javascript theme={null} let launchTime = null; // First message sets the starting time. const SNIPER_WINDOW_MS = 10_000; // first 10 seconds ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; msg.data.forEach(tx => { if (!launchTime) launchTime = tx.time; const ageMs = tx.time - launchTime; const isEarly = ageMs < SNIPER_WINDOW_MS; if (isEarly && tx.type === "buy") { console.log(`🎯 Early buy (${(ageMs / 1000).toFixed(1)}s after launch)`); console.log(` Wallet: ${tx.wallet}`); console.log(` Amount: $${tx.volume.toFixed(2)}`); } }); }; ``` ## Copy-trading trigger Filter for a set of wallet addresses to send activity to an alert handler: ```javascript theme={null} // Wallets you want to copy-trade const WATCHED_WALLETS = new Set([ "FV1r15rbNKkJanXLheoJA7fXEq6NDuMJ3bukXuhJWyV1", "4Rz5xqikxtZ2s7wE9uQ6n2oLXQi6K65XGoYpKxf24Hqo" ]); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; msg.data.forEach(tx => { if (WATCHED_WALLETS.has(tx.wallet) && tx.type === "buy") { console.log(`📡 Copy-trade trigger: ${tx.wallet.slice(0, 8)}... bought $${tx.volume.toFixed(2)}`); // → call your swap API here } }); }; ``` ## Full live trade feed with reconnect This example reconnects and rejoins the token room. Use the [connection guide](/guides/datastream-protocol) for heartbeat and authentication handling: ```javascript theme={null} function startTradeFeed(token, onTrade) { let ws; let reconnectTimeout; function connect() { ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { console.log(`Subscribed to trades for ${token}`); ws.send(JSON.stringify({ type: "join", room: `transaction:${token}` })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "message") { msg.data.forEach(onTrade); } }; ws.onclose = () => { console.log("Disconnected — reconnecting in 3s"); reconnectTimeout = setTimeout(connect, 3000); }; ws.onerror = (err) => { console.error("Stream error:", err.message); ws.close(); }; } connect(); return () => { clearTimeout(reconnectTimeout); ws?.close(); }; } // Usage const stop = startTradeFeed( "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", (tx) => { const side = tx.type === "buy" ? "BUY " : "SELL"; console.log(`${side} $${tx.volume.toFixed(2)} — ${tx.wallet.slice(0, 8)}...`); } ); // Stop later: stop() ``` ## Transaction fields reference | Field | Type | Description | | - | - | - | | `tx` | string | Transaction signature | | `type` | `"buy"` \| `"sell"` | Trade direction | | `volume` | number | Trade size in USD | | `solVolume` | number | Trade size in SOL | | `priceUsd` | number | Token price at time of trade | | `amount` | number | Token amount traded | | `wallet` | string | Trader's wallet address | | `time` | number | Unix timestamp (ms) | | `program` | string | DEX used (`raydium`, `pumpfun`, `okx`, etc.) | | `token.from` | object | Token sold | | `token.to` | object | Token received | ## Related guides * [Sniper & Bundler Detection](/guides/sniper-detection) — identify sniper wallets from historical data * [Wallet Tracking](/guides/wallet-tracking) — track all trades across every token for a wallet * [KOL Tracking](/guides/kol-tracking) — find top traders and build copy-trading feeds * [Live Prices & Charts](/guides/datastream-prices) — stream price updates alongside trade data # Query wallet and token PnL in batches Source: https://docs.solanatracker.io/guides/pnl-v2/batch-operations Fetch Solana wallet summaries and token positions in batches. Choose the right endpoint, respect request limits, and handle missing results. Batch known wallet addresses and token mints to reduce the number of requests. Position batches return token-level rows; wallet-summary batches return totals and identity labels. ## When to use batch endpoints Choose the request shape that matches your input list: Fetch a wallet's positions across 50+ tokens in one call Get how 200 wallets performed on a specific token Look up specific wallet+token pairs from leaderboard results Batch endpoints return either positions or wallet summaries: * **Position batches** return token-level position rows and support `pnlMode`. * **Wallet summary batch** returns wallet-level summaries and wallet tags for up to 100 wallets. It does not accept `pnlMode`. ## One wallet, many tokens Use [wallet batch positions](/data-api/pnl-v2/wallet/get-wallet-batch-positions) for one wallet and a list of mints. ```bash cURL theme={null} curl -X POST "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions/batch" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tokens": [ "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump", "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump", "CMx7yon2cLzHcXqgHsKJhuU3MmME6noWLQk2rAycBAGS" ] }' ``` ```javascript JavaScript theme={null} const wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o"; const tokens = [ "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump", "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump" ]; const res = await fetch( `https://data.solanatracker.io/v2/pnl/wallets/${wallet}/positions/batch`, { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ tokens }) } ); const { positions, notFound } = await res.json(); positions.forEach(p => { console.log(`${p.meta.symbol}: $${p.pnl.total.toFixed(2)} PnL`); }); if (notFound.length) { console.log(`Not traded: ${notFound.join(", ")}`); } ``` ```python Python theme={null} import requests wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o" tokens = [ "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump", "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump" ] res = requests.post( f"https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions/batch", json={"tokens": tokens}, headers={"x-api-key": "YOUR_API_KEY"} ) data = res.json() for p in data["positions"]: print(f"{p['meta']['symbol']}: ${p['pnl']['total']:.2f}") ``` **Limit:** 100 tokens per request. Tokens the wallet never traded show up in the `notFound` array. Missing items are listed there; they are not request errors. ## Many wallet summaries Use `POST /v2/pnl/wallets/batch` when you only need wallet-level summaries and tags, not per-token positions. The request accepts up to 100 unique wallet addresses. Invalid addresses are returned in `invalid`, wallets without a PnL summary are returned in `notFound`, and requests with more than 100 unique valid wallets include a `truncated` object. ```bash theme={null} curl -X POST "https://data.solanatracker.io/v2/pnl/wallets/batch" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "wallets": [ "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o", "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg" ] }' ``` Each returned wallet mirrors the wallet-summary shape: `wallet`, `identity`, `summary`, `tags`, and `updatedAt`. The batch response includes `summary` only. The `analysis` block from the single-wallet endpoint — including `analysis.winRate`, `analysis.tokens.profitable`, `analysis.tokens.losing`, `analysis.maxSinglePnl`, and the `ending` / `pnlAdjustments` fields — is **not** returned by `POST /v2/pnl/wallets/batch`. If you need `winRate` or any other `analysis.*` field for multiple wallets, call [`GET /v2/pnl/wallets/{wallet}`](/data-api/pnl-v2/wallet/get-wallet-summary) once per wallet. ## One token, many wallets Use [token batch positions](/data-api/pnl-v2/token/get-token-batch-positions) to compare how multiple wallets performed on the same token. ```bash cURL theme={null} curl -X POST "https://data.solanatracker.io/v2/pnl/tokens/{token}/positions/batch" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "wallets": [ "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o", "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg" ] }' ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const wallets = [ "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o", "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg" ]; const res = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/positions/batch`, { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ wallets }) } ); const { positions, notFound } = await res.json(); positions.forEach(p => { console.log(`${p.wallet}: $${p.pnl.token.total.toFixed(2)} on this token, ${p.counts.total} trades`); }); ``` **Limit:** 200 wallets per request. ## Any wallet-token pairs Use [position batch lookup](/data-api/pnl-v2/batch/get-position-batch-lookup) for a list of wallet-token pairs. ```bash cURL theme={null} curl -X POST "https://data.solanatracker.io/v2/pnl/positions/batch" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "pairs": [ { "wallet": "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o", "token": "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump" }, { "wallet": "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o", "token": "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump" } ] }' ``` ```javascript JavaScript theme={null} const pairs = [ { wallet: "CyaE1...", token: "38Pgz..." }, { wallet: "CyaE1...", token: "84cAE..." }, { wallet: "vines...", token: "38Pgz..." } ]; const res = await fetch("https://data.solanatracker.io/v2/pnl/positions/batch", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ pairs }) }); const { positions, notFound } = await res.json(); console.log(`Found ${positions.length} positions, ${notFound.length} not found`); ``` **Limit:** 200 pairs per request. ## Which endpoint to use | You want... | Endpoint | Limit | | - | - | - | | One wallet's PnL across 50 tokens | [Wallet Batch](/data-api/pnl-v2/wallet/get-wallet-batch-positions) | 100 tokens | | 100 wallets' PnL on one token | [Token Batch](/data-api/pnl-v2/token/get-token-batch-positions) | 200 wallets | | Specific wallet+token combos | [Pair Batch](/data-api/pnl-v2/batch/get-position-batch-lookup) | 200 pairs | | Wallet summaries and tags | `POST /v2/pnl/wallets/batch` | 100 wallets | Unmatched inputs come back in a `notFound` array instead of causing errors. Always check it. ## PnL mode All three **position** batch endpoints accept `?pnlMode=strict|adjusted|raw` as a query parameter. Default is `strict`. The wallet-summary batch endpoint does not accept `pnlMode`. See the [Essentials](/guides/pnl-v2/overview#essentials) for what each mode does. ```bash theme={null} curl -X POST "https://data.solanatracker.io/v2/pnl/positions/batch?pnlMode=adjusted" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "pairs": [ ... ] }' ``` Build a shortlist of wallets to batch-enrich. Drill into a single wallet from your batch results. # Build Solana trader and KOL leaderboards Source: https://docs.solanatracker.io/guides/pnl-v2/leaderboards Rank Solana traders and KOLs by PnL, ROI, or activity. Apply time windows, platform filters, and minimum trade thresholds. Choose the KOL leaderboard for the tracked public-wallet roster or the top-trader leaderboard for broader Solana rankings. Keep the period and filters consistent when comparing results. ## KOL leaderboards KOLs are tracked wallets with a public identity. Each entry can include a name, Twitter handle, and avatar. KOLScan leaderboard with KOL activity calendar and ranked wallet performance ### All-time The [KOL leaderboard](/data-api/pnl-v2/leaderboard/get-kol-leaderboard) ranks KOL wallets by lifetime performance. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols?sort=realized&direction=desc&limit=25" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://data.solanatracker.io/v2/pnl/leaderboard/kols?sort=realized&direction=desc&limit=25", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); traders.forEach((kol, i) => { console.log(`#${i + 1} ${kol.identity.name} (@${kol.identity.twitter})`); console.log(` Realized: $${kol.pnl.realized.toLocaleString()}`); console.log(` Win Rate: ${kol.winRate}%`); }); ``` ```python Python theme={null} import requests res = requests.get( "https://data.solanatracker.io/v2/pnl/leaderboard/kols", params={"sort": "realized", "direction": "desc", "limit": 25}, headers={"x-api-key": "YOUR_API_KEY"} ) for i, kol in enumerate(res.json()["traders"], 1): name = kol["identity"]["name"] pnl = kol["pnl"]["realized"] print(f"#{i} {name}: ${pnl:,.2f}") ``` #### Sort options | Field | Description | | - | - | | `total` | Total PnL (realized + unrealized) | | `realized` | Realized PnL | | `unrealized` | Unrealized PnL | | `invested` | Total invested | | `proceeds` | Total proceeds from sells | | `trades` | Number of trades | | `tokens` | Number of tokens traded | | `roi` | Return on investment | | `win_percentage` | Win rate | | `last_trade` | Most recent trade | ### By time period The [period leaderboard](/data-api/pnl-v2/leaderboard/get-kol-leaderboard-for-a-period) ranks KOLs within a specific window. Use shortcuts like `7d`, `30d`, or set explicit `start`/`end` dates. ```bash theme={null} # Last 7 days curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/period?period=7d&sort=realized" \ -H "x-api-key: YOUR_API_KEY" # Custom range curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/period?start=2025-03-01&end=2025-03-31" \ -H "x-api-key: YOUR_API_KEY" ``` Best when identity matters and you want to compare public figures. Better when you care about results regardless of reputation. ### Monthly calendar The [calendar endpoint](/data-api/pnl-v2/leaderboard/get-kol-calendar) returns daily totals for the tracked KOL set in a month. ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/calendar?year=2025&month=3" \ -H "x-api-key: YOUR_API_KEY" ``` Color each day by total KOL PnL to quickly spot market-wide trends. ### Single day The [daily breakdown endpoint](/data-api/pnl-v2/leaderboard/get-kol-daily-breakdown) shows each KOL's trades and PnL for one specific day. ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/kols/date?date=2025-03-15" \ -H "x-api-key: YOUR_API_KEY" ``` ## Solana traders leaderboard The [top-trader leaderboard](/data-api/pnl-v2/leaderboard/solana-traders-leaderboard) ranks wallets over a `1`, `7`, `30`, or `90` day window. It is not limited to the KOL roster; coverage is capped at the top 500,000 wallets per period. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/top?days=30&sort=realized&direction=desc&limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://data.solanatracker.io/v2/pnl/leaderboard/top?days=30&sort=realized&direction=desc&limit=50", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); traders.forEach((t, i) => { console.log(`#${i + 1} ${t.wallet}`); console.log(` Realized: $${t.period.realized.toLocaleString()}, ROI: ${t.period.roi}%`); }); ``` ### Filters Filter by trade count, active days, platform, or concentration to define the ranked set: Photon leaderboard filtered to wallets trading through Photon Bloom leaderboard filtered to wallets trading through Bloom | Parameter | Default | Description | | - | - | - | | `days` | `90` | Rolling window in days. Use `1`, `7`, `30`, or `90` for exact supported windows. | | `sort` | `realized` | `realized`, `volume`, `days`, `roi`, `win_percentage`, `trades`, `tokens` | | `minTrades` | `20` | Minimum number of trades | | `minInvested` | `1` | Minimum total USD invested | | `minDays` | `3` | Minimum active trading days | | `minWinRate` | — | Minimum win percentage | | `minRoi` | — | Minimum ROI percentage | | `minClosedTokens` | — | Minimum number of closed positions | | `maxSingleTokenPct` | — | Maximum % of PnL from a single token (filters one-hit wonders) | | `excludeArbitrage` | `true` | Arbitrage wallets are excluded by default. Set to `false` to include them. | | `platform` | — | Filter by platform (`axiom`, `bloom`, `photon`). Comma-separated for multiple. `axiom-flash` is accepted as an `axiom` alias. | | `pnlMode` | `strict` | `strict`, `adjusted`, or `raw`. See [Essentials](/guides/pnl-v2/overview#essentials). | **Coverage:** the top-traders leaderboard ranks the **top 500k wallets** per period. A wallet can trade and still not appear in this ranked list. To inspect any wallet directly, call `/v2/pnl/wallets/:wallet`. For example, combine `maxSingleTokenPct=30`, `minDays=10`, and `minTrades=50` to limit single-token concentration and require a minimum activity history. These filters do not predict future returns. After you shortlist wallets, use batch endpoints to enrich them in bulk. Drill into a single wallet's full history and risk profile. # How Solana wallet PnL works Source: https://docs.solanatracker.io/guides/pnl-v2/overview Understand Solana Tracker PnL V2 coverage, calculation modes, currencies, pagination, wallet identity, and live updates. PnL V2 measures wallet returns from indexed Solana trades. Before comparing wallets, choose the same calculation mode, currency, and time window. This page explains those choices and links to the query guides. **Base URL:** `https://data.solanatracker.io`\ **Auth:** Pass your API key in the `x-api-key` header.\ **Values:** Monetary amounts default to USD. Wallet summary, history, and performance accept `?currency=usd|sol|eur`. Timestamps are Unix milliseconds unless noted. ## Essentials ### What PnL V2 includes * **Token coverage.** Every SPL token is supported **except stablecoins and SOL**. * **Wallet endpoints.** Use wallet endpoints for any wallet, even if it is not on a leaderboard. * **Identity tags.** Wallets can include an `identity` object with labels such as KOL, bot, exchange, pool, developer, trading platform, or SNS primary `.sol` domain. ### What PnL V2 excludes SOL and stablecoins serve as quote assets and are excluded from PnL positions. `excludeArbitrage=true` is the default on endpoints that expose this filter. Set it to `false` when your analysis needs arbitrage wallets. The top-traders leaderboard covers the **top 500k wallets** per period. If a wallet is outside that ranked set, query it directly with the wallet endpoints. ### Identity tags An `identity` object can contain several labels: * **Bots and MEV** — `potential_bot` (heuristic), `bot` (curated named bots like Mayhem Bot), and `arbitrage` (confirmed MEV). * **Platforms** — `axiom`, `bloom`, and `photon`. The API also accepts `axiom-flash` as an `axiom` alias. * **Safety / infrastructure tags** — curated `hacker`, `spam_dusting`, and `exchange` labels when known. * **Pool and developer** roles are automatically resolved on token-scoped endpoints. * **SNS:** primary `.sol` domain via Ridge (`identity.sns`, `sns` tag). See [SNS Primary Domain](/guides/pnl-v2/sns-identity). ### PnL modes Wallet-summary, positions, single-position, top-trader leaderboard, and position batch endpoints accept `?pnlMode=`. | Mode | Behavior | | - | - | | `strict` (default) | Excludes positions with recorded sells greater than recorded buys. | | `adjusted` | Keeps those positions but recalculates realized PnL with an adjusted cost basis. Useful when strict mode hides positions you still want to show. | | `raw` | No filtering. Realized PnL is returned exactly as calculated. Use this when you need the unfiltered numbers. | Supported endpoints echo `pnlMode` in the response. Position rows expose mode-aware `pnl.realized` and unfiltered `pnl.realizedRaw`; read the selected mode when comparing results. The KOL leaderboards, history, chart, performance, highlights, risk, token-traders, first-buyers, and wallet-summary batch endpoints do not take `pnlMode`; they return the API's fixed server-side view for that dataset. ### Currency denomination Wallet summary, history, and performance accept an optional `?currency=` query parameter: | Value | Behavior | | - | - | | `usd` (default) | Monetary fields are returned in USD. The `currency` field is omitted. | | `sol` | USD snapshot values are converted at read time using SOL/USD reference prices. Response includes `"currency": "sol"`. | | `eur` | USD snapshot values are converted at read time using EUR/USD reference prices. Response includes `"currency": "eur"`. | Conversion rules: * **History** and **performance** — each day's USD values are divided by that day's historical reference rate. * **Wallet summary** — converted with current spot (`getSolanaPrice()` for SOL; latest 1m candle for EUR). * Counts, percentages, timestamps, and ROI are **not** converted. * Field names stay the same (e.g. `activity.volume.costUsd`); check the top-level `currency` field for denomination. * Invalid values (e.g. `?currency=btc`) return **400**: `{ "error": "Invalid currency. Options: usd, sol, eur" }`. ## Endpoint groups ### Wallet endpoints | Endpoint | What it returns | | - | - | | [GET /v2/pnl/wallets/\{wallet}](/data-api/pnl-v2/wallet/get-wallet-summary) | PnL summary, win rate, token counts | | [GET /v2/pnl/wallets/\{wallet}/positions](/data-api/pnl-v2/wallet/get-wallet-positions) | All positions with sorting and filters | | [GET /v2/pnl/wallets/\{wallet}/tokens/\{token}](/data-api/pnl-v2/wallet/get-wallet-token-position) | Single position detail | | [GET /v2/pnl/wallets/\{wallet}/history](/data-api/pnl-v2/wallet/get-wallet-pnl-calendar) | Daily PnL snapshots | | [GET /v2/pnl/wallets/\{wallet}/chart](/data-api/pnl-v2/wallet/get-wallet-chart) | Chart data points | | [GET /v2/pnl/wallets/\{wallet}/performance](/data-api/pnl-v2/wallet/get-wallet-performance) | Streaks, drawdown, best/worst days | | [GET /v2/pnl/wallets/\{wallet}/highlights](/data-api/pnl-v2/wallet/get-wallet-highlights) | Biggest winners, losers, flips | | [GET /v2/pnl/wallets/\{wallet}/risk](/data-api/pnl-v2/wallet/get-wallet-risk) | Concentration and open exposure | ### Token endpoints | Endpoint | What it returns | | - | - | | [GET /v2/pnl/tokens/\{token}/traders](/data-api/pnl-v2/token/get-token-traders) | Every wallet that traded this token | | [GET /v2/pnl/tokens/\{token}/first-buyers](/data-api/pnl-v2/token/get-token-first-buyers) | Earliest buyers only (`sort=first_trade`, `direction=asc`) | ### Leaderboard endpoints | Endpoint | What it returns | | - | - | | [GET /v2/pnl/leaderboard/kols](/data-api/pnl-v2/leaderboard/get-kol-leaderboard) | KOL rankings (all-time) | | [GET /v2/pnl/leaderboard/kols/period](/data-api/pnl-v2/leaderboard/get-kol-leaderboard-for-a-period) | KOL rankings for a time window | | [GET /v2/pnl/leaderboard/kols/calendar](/data-api/pnl-v2/leaderboard/get-kol-calendar) | Daily KOL performance for a month | | [GET /v2/pnl/leaderboard/kols/date](/data-api/pnl-v2/leaderboard/get-kol-daily-breakdown) | Per-KOL breakdown for one day | | [GET /v2/pnl/leaderboard/top](/data-api/pnl-v2/leaderboard/solana-traders-leaderboard) | Solana Traders Leaderboard over a rolling window | ### Batch endpoints | Endpoint | What it returns | | - | - | | [POST /v2/pnl/wallets/\{wallet}/positions/batch](/data-api/pnl-v2/wallet/get-wallet-batch-positions) | One wallet → many tokens | | [POST /v2/pnl/tokens/\{token}/positions/batch](/data-api/pnl-v2/token/get-token-batch-positions) | One token → many wallets | | [POST /v2/pnl/positions/batch](/data-api/pnl-v2/batch/get-position-batch-lookup) | Any wallet-token pairs | | POST /v2/pnl/wallets/batch | Wallet summaries + tags for up to 100 wallets | ## Key concepts ### Realized vs unrealized PnL Profit or loss attributed to completed sales. The current value of open positions minus their remaining cost basis. `realized + unrealized`. ### Wallet coverage PnL V2 covers all Solana wallets from **December 2023 onward**. Wallets are not indexed on request. ### Pagination For paginated responses, pass `pagination.nextCursor` unchanged as `cursor` in the next request. Keep the other filters the same. ```bash theme={null} # First page curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions?limit=50" \ -H "x-api-key: YOUR_API_KEY" # Next page (use cursor from previous response) curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions?limit=50&cursor=eyJ..." \ -H "x-api-key: YOUR_API_KEY" ``` ### Wallet identity When available, `identity` combines wallet labels from multiple sources. For example, a wallet may have `["kol", "developer", "axiom"]`. Only populated fields are returned: | Tag | Meaning | | - | - | | `kol` | Tracked KOL wallet. Includes `name`, `twitter`, `avatar`. | | `bot` | Curated named bot (e.g. Mayhem Bot). | | `potential_bot` | Heuristically detected bot — softer signal. | | `arbitrage` | Confirmed MEV / arbitrage operator. | | `hacker` | Curated exploit / scam wallet label. Includes `hacker.label`. | | `spam_dusting` | Curated spam-dusting wallet label. Includes `spamDusting.label`. | | `exchange` | Known centralized exchange hot wallet. Includes `exchange.name`. | | `pool` | Wallet is a pool vault, authority, LP mint, or bonding curve account. Includes `program` and `poolAddress`. | | `developer` | Wallet is a token creator, pool deployer, or mint authority. Includes `via`, `pools`, `creationTx`, `createdAt`. | | Platform tags | `axiom`, `bloom`, `photon`. `axiom-flash` is accepted as a query alias and surfaces as `axiom`. | | `sns` | Primary `.sol` domain for the wallet (Solana Name Service). Includes `sns.domain`. | On token-scoped endpoints (`/tokens/:token/traders`, `/first-buyers`, `/tokens/:token/positions/batch`) the `pool` and `developer` roles are resolved for the exact token in the path, so you can spot devs, LPs, and snipers inline without extra requests. See the [Solana Wallet Tags guide](/guides/pnl-v2/wallet-tags) for the full supported tag list. ### Enrichment on `/tokens/:tokenAddress/holders` The classic holders endpoint accepts an optional `?enrich=` parameter: * `?enrich=identity` — adds pool / developer / platform identity per holder. * `?enrich=walletPnl` — adds lifetime wallet PnL plus per-token PnL per holder. * `?enrich=all` — both. Omit `enrich` when you only need the base holder response. ### Real-time via Datastream Pair these REST endpoints with the Datastream PnL V2 WebSocket rooms for live updates. Available on Premium, Business, and Enterprise plans: | Room | Emits | Scope | | - | - | - | | `pnl:{wallet}:{token}` | `tradeUpdate`, `balanceUpdate` | One token position | | `pnl:{wallet}` | `tradeUpdate`, `balanceUpdate` | Every token the wallet trades | | `pnl:{wallet}:summary` | Total wallet PnL summary | Aggregated realized/unrealized PnL, ROI, counts, averages, and open-position totals | Typical pattern: call `GET /v2/pnl/wallets/:wallet` once to seed state, then subscribe to `pnl:{wallet}:summary` to keep it in sync. For valuations between position events, combine a PnL room with `price:aggregated:{token}` or `price-by-token:{token}`. Use PnL events for balances and cost basis, and price events for the displayed market value. Follow the [live PnL guide](/guides/datastream-pnl#fastest-live-unrealized-pnl-combining-rooms). # Show Solana wallet names with SNS identity Source: https://docs.solanatracker.io/guides/pnl-v2/sns-identity Read primary .sol domains from Solana wallet identity. Learn how SNS names appear alongside KOL, exchange, bot, and platform labels. PnL V2 can add a wallet's primary `.sol` domain to `identity.sns.domain`. Use it as a display label while keeping the wallet address available for links and lookups. Higher-priority labels (KOL, exchange, bot, and so on) keep `identity.name`. SNS is attached alongside when a primary domain exists. See [Solana Wallet Tags](/guides/pnl-v2/wallet-tags) for the full tag list. ## What clients see ### Wallet with only a primary domain When no curated label exists, the primary domain becomes `identity.name` and `identity.type` is `sns`: ```json theme={null} { "wallet": "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "identity": { "name": "solanatracker.sol", "sns": { "domain": "solanatracker.sol" }, "tags": ["sns"], "type": "sns" } } ``` ### Wallet that already has a label A curated label keeps `identity.name`. The primary domain is returned separately in `identity.sns`: ```json theme={null} { "identity": { "name": "SomeKolName", "sns": { "domain": "solanatracker.sol" }, "tags": ["kol", "sns"], "type": "kol" } } ``` ### No primary domain set If no primary domain is set, there is no `sns` field or tag. Any other known identity labels remain available. ## Fields | Field | Description | | - | - | | `identity.sns.domain` | Primary `.sol` domain for the wallet | | `identity.tags` | Includes `"sns"` when a primary domain is resolved | | `identity.type` | `"sns"` when SNS is the highest-priority label; otherwise the primary tag (e.g. `kol`, `bot`) | | `identity.name` | Curated label when present; otherwise the primary domain | ## Where it appears Look for SNS fields in identity objects from these endpoint groups: * `GET /v2/pnl/wallets/:wallet` and related wallet endpoints * `GET /v2/pnl/tokens/:token/traders` and `/first-buyers` * Leaderboard and KOL endpoints * `POST /v2/pnl/wallets/batch` and position batch endpoints * `GET /tokens/:tokenAddress/holders?enrich=identity` (and `?enrich=all`) ## UI tips * Show `identity.sns.domain` as a secondary label when `identity.type` is not `sns` (e.g. display KOL name with `.sol` domain underneath). * When `identity.type` is `sns`, treat `identity.name` as the human-readable wallet label. * Always read `identity.tags` as an array. A wallet can be both `kol` and `sns`. Resolve a wallet's primary `.sol` domain directly via RPC. Full supported tag list, platform filters, and FAQ. Endpoint groups, identity tags, and enrichment on holders. # Query Solana token traders and first buyers Source: https://docs.solanatracker.io/guides/pnl-v2/token-intelligence Query traders and first buyers for a Solana token. Compare token PnL, wallet PnL, current holdings, trade timing, and identity labels. Use token traders to rank or filter wallets that traded a mint. Use first buyers when order matters: that endpoint returns the earliest trades first. Both expose positions, PnL, and wallet identity. ## Token traders The [token traders endpoint](/data-api/pnl-v2/token/get-token-traders) returns paginated trader rows with current positions and PnL. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/tokens/{token}/traders?sort=pnl&direction=desc&limit=20" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/traders?sort=pnl&direction=desc&limit=20`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); traders.forEach(t => { // pnl.token = this token's PnL, pnl.wallet = the wallet's lifetime PnL across all tokens console.log(`${t.wallet}: $${t.pnl.token.total.toFixed(2)} on this token, lifetime $${t.pnl.wallet?.total?.toFixed(2) ?? "n/a"}`); }); ``` ```python Python theme={null} import requests token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump" res = requests.get( f"https://data.solanatracker.io/v2/pnl/tokens/{token}/traders", params={"sort": "pnl", "direction": "desc", "limit": 20}, headers={"x-api-key": "YOUR_API_KEY"} ) for t in res.json()["traders"]: print(f"{t['wallet']}: ${t['pnl']['token']['total']:.2f} on this token, {t['counts']['total']} trades") ``` ### Sorting options | Sort Field | Description | | - | - | | `pnl` | Total PnL | | `realized` | Realized PnL only | | `unrealized` | Unrealized PnL only | | `invested` | Total USD invested | | `roi` | Return on investment percentage | | `holding` | Current token balance | | `value` | Current USD value of the remaining position | | `first_trade` | Time of first trade | | `last_trade` | Time of most recent trade | ### Filtering options | Parameter | Description | | - | - | | `activeOnly` | Only show wallets currently holding the token | | `minTrades` | Minimum number of trades | | `excludeArbitrage` | Exclude wallets flagged as arbitrage bots. **Default: `true`** — arbitrage PnL is noisy and the goal is tracking real traders. Pass `false` to include them. | | `excludeZeroBuys` | Exclude wallets that received tokens without buying (airdrops, transfers). **Default: `true`.** | | `platform` | Filter by trading platform (`axiom`, `bloom`, `photon`). Comma-separated for multiple. `axiom-flash` is accepted as an `axiom` alias. | **Getting an empty `traders` array on a high-volume token?** The defaults above are filters, not safety rails — `excludeArbitrage=true`, `excludeZeroBuys=true`, and (if you set it) `activeOnly=true` are all applied before the response is built. On bot-heavy tokens this can hide every wallet. Re-run with `excludeArbitrage=false&excludeZeroBuys=false`, drop `activeOnly`, and lower `minTrades` to confirm whether the dataset itself is empty (`pagination.total: 0`) or just filtered down to zero. This endpoint does not accept `pnlMode`. The wallet-level PnL it returns (`pnl.wallet`) reflects the API's wallet-summary view. ### Response shape: pnl.token vs pnl.wallet Each trader carries **two** PnL objects: * `pnl.token` — realized / unrealized / total for this exact token only. * `pnl.wallet` — lifetime realized / unrealized / total across every token the wallet has traded. Compare the two objects to separate performance on this mint from the wallet's wider trading history. | Question | Field to use | | - | - | | Did this wallet profit on this token? | `pnl.token` | | Is this wallet profitable overall? | `pnl.wallet` | | Is the wallet still holding this token? | `position.balance` | | When did the wallet first buy? | `timing.firstTrade` | ### Inline identity Each trader in the response includes a structured `identity` object. On token endpoints this is resolved against the token in the URL, so `pool` and `developer` tags automatically reflect the right token: ```json theme={null} "identity": { "tags": ["kol", "developer"], "kol": { "name": "Ansem", "twitter": "blknoiz06" }, "developer": { "via": "creator", "creationTx": "5x7Y...", "createdAt": 1713600000000 } } ``` Use the returned tags to label or filter trader rows. A primary `.sol` domain appears in `identity.sns.domain` when available; see [SNS wallet names](/guides/pnl-v2/sns-identity). Combine `minTrades`, `activeOnly`, and `excludeArbitrage` to set an activity threshold, require open positions, or exclude labeled arbitrage wallets. Use a trader's wallet address to inspect its other positions and returns. ## First buyers The [first-buyers endpoint](/data-api/pnl-v2/token/get-token-first-buyers) returns trader data in chronological order: `sort=first_trade` and `direction=asc`. `first-buyers` rejects leaderboard-style sorting. For ROI, PnL, position size, latest trade, or descending order, use [`/v2/pnl/tokens/:token/traders`](/data-api/pnl-v2/token/get-token-traders). ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/tokens/{token}/first-buyers?limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` Use the [wallet summary](/data-api/pnl-v2/wallet/get-wallet-summary) to inspect a first buyer's wider trading history and available identity labels. ### Example: first buyers who closed a position ```javascript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/first-buyers?limit=50`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); // Early buyers who are fully out of the position const closedPositions = traders.filter(t => t.position.balance === 0 && t.pnl.token.realized > 0 ); console.log(`${closedPositions.length} early buyers already sold at a profit`); closedPositions.forEach(t => { const holdMins = (t.timing.lastTrade - t.timing.firstTrade) / 60000; console.log(` ${t.wallet}: +$${t.pnl.token.realized.toFixed(2)}, held ${holdMins.toFixed(0)} minutes`); }); ``` Compare `pnl.token` with `pnl.wallet` before ranking a trader by results on a single mint. Drill into a single wallet's full PnL, positions, and risk profile. More tools for finding early buyers, bundlers, and suspicious activity. # Query Solana wallet PnL and token positions Source: https://docs.solanatracker.io/guides/pnl-v2/wallet-analysis Get wallet PnL summaries, token positions, daily history, charts, performance, and exposure with Solana Tracker PnL V2. Fetch a wallet summary for total returns, then query positions for the tokens behind those numbers. Use history for daily changes, charts for a time series, and risk data for current exposure. ## Wallet summary The [wallet summary](/data-api/pnl-v2/wallet/get-wallet-summary) returns total PnL, win rate, token counts, and ROI distribution. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o"; const res = await fetch(`https://data.solanatracker.io/v2/pnl/wallets/${wallet}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const data = await res.json(); console.log(`Total PnL: $${data.summary.pnl.total.toFixed(2)}`); console.log(`Win Rate: ${data.analysis.winRate}%`); console.log(`Tokens Traded: ${data.summary.counts.tokensTraded}`); ``` ```python Python theme={null} import requests wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o" res = requests.get( f"https://data.solanatracker.io/v2/pnl/wallets/{wallet}", headers={"x-api-key": "YOUR_API_KEY"} ) data = res.json() print(f"Total PnL: ${data['summary']['pnl']['total']:.2f}") print(f"Win Rate: {data['analysis']['winRate']}%") ``` ## Currency denomination Wallet summary, history, and performance support `?currency=usd|sol|eur` (default `usd`). When you pass `sol` or `eur`, monetary values are converted at read time and the response includes a top-level `"currency"` field. ```bash SOL denomination theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}?currency=sol" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash EUR denomination (30-day history) theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/history?period=30d¤cy=eur" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash Performance in SOL theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/performance?period=30d¤cy=sol" \ -H "x-api-key: YOUR_API_KEY" ``` Historical SOL/EUR values are approximate — each day uses that day's reference rate, so cumulative converted values won't chain perfectly across days. Field names stay USD-oriented in some places (e.g. `activity.volume.costUsd`); use the top-level `currency` field to determine denomination. ## Token positions The [positions endpoint](/data-api/pnl-v2/wallet/get-wallet-positions) lists every token a wallet has traded. Sort by PnL, ROI, or value. Filter by holding state, market, minimum invested amount, and more. ### PnL mode The wallet summary, positions, and single-position endpoints support `?pnlMode=strict|adjusted|raw`. Default is `strict`, which filters out positions with sell amounts greater than buy amounts (usually invalid). Switch to `adjusted` for a cost-basis-corrected view, or `raw` to see everything unfiltered. See the [Essentials](/guides/pnl-v2/overview#essentials) for details. ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions?pnlMode=adjusted" \ -H "x-api-key: YOUR_API_KEY" ``` ### Common filters ```bash theme={null} GET /v2/pnl/wallets/{wallet}/positions?filter=profit&sort=total&direction=desc ``` ```bash theme={null} GET /v2/pnl/wallets/{wallet}/positions?filter=holding&sort=value&direction=desc ``` ```bash theme={null} GET /v2/pnl/wallets/{wallet}/positions?minInvested=100&sort=roi&direction=desc ``` ```bash theme={null} GET /v2/pnl/wallets/{wallet}/positions?market=pumpfun&sort=total&direction=desc ``` ### Single position Use the [wallet token position](/data-api/pnl-v2/wallet/get-wallet-token-position) endpoint for one mint: ```bash theme={null} GET /v2/pnl/wallets/{wallet}/tokens/{token} ``` Returns the full position: realized/unrealized PnL, cost basis, current value, buy/sell counts, trade timing, and token metadata. ## PnL calendar The [PnL calendar endpoint](/data-api/pnl-v2/wallet/get-wallet-pnl-calendar) shows how a wallet's PnL changed day by day. PnL calendar showing daily green and red profit and loss cells ```bash Last 30 days theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/history?period=30d" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash Custom date range theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/history?start=2025-01-01&end=2025-01-31" \ -H "x-api-key: YOUR_API_KEY" ``` Each day includes: * **Running totals** — PnL, invested, and proceeds as of that day * **Daily activity** — that day's realized PnL, volume, and trade counts Use **history** when you need to explain what changed each day. Use **chart** when you need a visual equity curve. ### Choosing a time window Time-range parameters vary by endpoint. Use the following options for history, performance, charts, and KOL period queries: | Parameter | Where it works | Notes | | - | - | - | | `period` | history, performance, KOL period | Shorthand enum: `1d`, `7d`, `14d`, `30d`, `90d`, `all`. Ignored when `start`/`end` are set. | | `days` | performance | Integer number of days (default `30`, max `365`). Use this to ask for non-standard windows like `45` or `120`. | | `start` / `end` | history, KOL period | Explicit `YYYY-MM-DD` calendar range. When either is set, `period` is ignored. Defaults: `start` = 30 days ago, `end` = today. | | `time_from` / `time_to` | chart | Unix seconds. Pass `pagination.nextTimeTo` as `time_to` to load older points. | Use `period` or `days` only where the endpoint supports it. Pass `start` and `end` for an explicit date range on history and KOL period queries. ## Chart data The [chart endpoint](/data-api/pnl-v2/wallet/get-wallet-chart) returns up to 180 daily data points for plotting equity, realized PnL, and activity. PnL chart showing realized profit over time, volume, win rate, and drawdown ```javascript theme={null} const wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o"; const res = await fetch(`https://data.solanatracker.io/v2/pnl/wallets/${wallet}/chart`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const { points, summary } = await res.json(); // points is an array of daily chart rows // summary contains streaks, drawdown, and win-rate style aggregates console.log(points.length, summary.winRate); ``` Use `time_from` and `time_to` (Unix seconds) to page through older data. ## Performance The [performance endpoint](/data-api/pnl-v2/wallet/get-wallet-performance) summarizes activity over the requested window: Wallet performance panel showing best day, worst day, streaks, and drawdown | Metric | Description | | - | - | | Total realized PnL | Sum of realized PnL in the window | | Total trades | Sum of daily buy/sell activity within the window (`day_buys + day_sells`), not lifetime cumulative counts | | Win/Loss streaks | Current and maximum consecutive winning/losing days | | Maximum drawdown | Largest drop from the highest value to the lowest dip | | Best/Worst days | The single best and worst trading days | | Daily breakdown | Day-by-day PnL, volume, and trade counts | ```bash theme={null} # Last 90 days performance curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/performance?days=90" \ -H "x-api-key: YOUR_API_KEY" ``` ## Highlights The [highlights endpoint](/data-api/pnl-v2/wallet/get-wallet-highlights) returns a wallet's most notable positions: PnL highlights panel showing biggest winner, loser, bag, and fastest flip The position with the highest realized PnL The position with the worst realized loss Shortest hold time with a profit The position held for the most time Current holding with the highest USD value The token with the most buy/sell transactions ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/highlights" \ -H "x-api-key: YOUR_API_KEY" ``` ## Risk The [risk endpoint](/data-api/pnl-v2/wallet/get-wallet-risk) evaluates current portfolio exposure: Wallet exposure panel showing open positions, cost basis, current value, and PnL mix * **Portfolio concentration** — how much is in the top 1 and top 5 positions * **Realized vs unrealized split** — is the wallet sitting on paper gains or locked-in profits? * **Open position value** — total USD value of current holdings * **Risky holdings** — list of tokens with low liquidity or high concentration risk ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/risk" \ -H "x-api-key: YOUR_API_KEY" ``` Risk only covers **current holdings**. Sold positions aren't included. ## Live updates Keep a wallet in sync with the Datastream PnL V2 rooms instead of polling: * `pnl:{wallet}:summary` — total wallet PnL summary with realized/unrealized PnL, ROI, counts, averages, and open-position totals. * `pnl:{wallet}` — every token the wallet touches, `tradeUpdate` / `balanceUpdate`. * `pnl:{wallet}:{token}` — a single position. Seed your UI with `GET /v2/pnl/wallets/:wallet`, then subscribe to the summary room. See the [Datastream PnL guide](/guides/datastream-pnl) for the full event payloads. See how a specific token was traded across wallets. Full schema details for the wallet summary response. # Identify Solana wallets with tags and labels Source: https://docs.solanatracker.io/guides/pnl-v2/wallet-tags Read Solana wallet identity tags for KOLs, bots, exchanges, developers, pools, and trading platforms. Handle multiple labels and unknown wallets. Use `identity` to label wallets in holder tables, trade feeds, and leaderboards. A wallet can have several tags, and token-specific roles such as developer or pool depend on the token being queried. Wallet tags are returned through the `identity` object. A wallet can have multiple tags at once, so always read `identity.tags` as an array instead of assuming one label. ## Quick start Wallet identity appears across PnL V2 wallet, token, leaderboard, and batch responses when a label is known. Wallet profile showing identity tags next to a wallet name ```json theme={null} { "identity": { "name": "Mayhem Bot", "avatar": "https://kol-avatar.solanatracker.io/...", "bot": { "name": "Mayhem Bot", "avatar": "https://kol-avatar.solanatracker.io/..." }, "type": "bot", "tags": ["bot"] } } ``` If a wallet has no known tags, `identity` can be `null`. `identity.type` is the primary tag for single-badge UIs. `identity.tags` is the complete tag list and should be used when you need every label. For a single badge, read `identity.type`. For filters or multiple badges, read the full `identity.tags` array. ## Raw wallet signals Some wallet endpoints also return a raw `tags` object with lower-level arbitrage and platform signals: ```json theme={null} { "tags": { "isArbitrage": false, "platforms": ["axiom", "bloom"] } } ``` Use `identity.tags` for UI labels and filtering logic. Use the raw `tags` object when you specifically need the underlying arbitrage/platform signals. ## Supported wallet tags | Tag | Meaning | Extra fields | | - | - | - | | `kol` | Tracked KOL wallet. | `name`, `twitter`, `avatar` | | `bot` | Curated named bot wallet, such as Mayhem Bot or other known automated traders. | `bot.name`, `bot.avatar` | | `potential_bot` | Heuristic bot / arbitrage-like signal from wallet activity. Softer signal than `bot` or `arbitrage`. | none | | `arbitrage` | Confirmed MEV / arbitrage wallet from the curated arbitrage list. | none | | `hacker` | Curated exploit, scam, or attacker wallet label. | `hacker.label`, often promoted to `name` | | `spam_dusting` | Curated spam-dusting wallet label. | `spamDusting.label`, often promoted to `name` | | `exchange` | Known centralized exchange hot wallet. | `exchange.name`, often promoted to `name` | | `developer` | Token creator, pool deployer, mint authority, or wallet linked to token creation. | `developer.token`, `developer.via`, `developer.pools`, `developer.creationTx`, `developer.createdAt`, or `developer.tokens` | | `pool` | AMM pool, vault, authority, LP mint, bonding curve, or related pool account. | `pool.program`, `pool.poolAddress`, `pool.tokenA`, `pool.tokenB` | | `axiom` | Wallet activity associated with Axiom. | `platforms` includes `axiom` | | `bloom` | Wallet activity associated with Bloom. | `platforms` includes `bloom` | | `photon` | Wallet activity associated with Photon. | `platforms` includes `photon` | | `sns` | Primary `.sol` domain for the wallet (Solana Name Service). | `sns.domain` | `axiom-flash` is accepted as a `platform` query value, but identity responses normalize it to the `axiom` tag. ## Tag categories ### People and bots These tags distinguish the tracked KOL roster, named bots, heuristic bot signals, and curated arbitrage labels. `potential_bot` is a softer heuristic signal. `bot` and `arbitrage` are stronger curated labels. ### Safety and infrastructure Use `hacker`, `spam_dusting`, and `exchange` for safety warnings and infrastructure labels. These tags are curated and may also promote a readable label into `identity.name`, for example an exchange name or spam-dusting label. ### Token context Use `developer` and `pool` on token-scoped endpoints to find token creators, pool deployers, mint authorities, LP accounts, pool vaults, and bonding curve accounts. Developer and pool roles are resolved against the mint in the request. The same wallet can have a different role for another token. ## Platform filters The endpoints below accept `platform=axiom`, `platform=bloom`, `platform=photon`, or comma-separated combinations. Axiom leaderboard filtered to wallets trading through Axiom * `GET /v2/pnl/leaderboard/top` * `GET /v2/pnl/tokens/:token/traders` * `GET /v2/pnl/tokens/:token/first-buyers` ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/tokens/{token}/traders?platform=axiom,bloom" \ -H "x-api-key: YOUR_API_KEY" ``` `platform=axiom-flash` is also accepted and is treated as `axiom`. ## Where tags appear Wallet identity is returned on PnL V2 wallet, token, leaderboard, and batch responses when the API can resolve a label. * Wallet summary and wallet positions return top-level `identity`. * Token trader endpoints return `identity` per trader. * Token-scoped endpoints resolve `developer` and `pool` for the token in the URL. * Position batch endpoints return `identity` per wallet or position. * `POST /v2/pnl/wallets/batch` returns both `identity` and raw `tags` per wallet. ## Common use cases | Goal | Tags to check | | - | - | | Hide noisy wallets | `bot`, `potential_bot`, `arbitrage`, `spam_dusting` | | Show known people | `kol` | | Flag token insiders | `developer`, `pool` | | Surface safety warnings | `hacker`, `spam_dusting` | | Identify exchange flows | `exchange` | | Filter by trading frontend | `axiom`, `bloom`, `photon` | ## Faq Yes. For example, a wallet can be both `kol` and `axiom`, or `developer` and `pool` depending on the token context. Always read `identity.tags` as an array. `bot` is a curated named bot label. `potential_bot` is a softer heuristic signal from wallet behavior. `arbitrage` is a confirmed MEV or arbitrage wallet label. `axiom-flash` is accepted for platform filtering, but identity responses normalize platform aliases so clients only need to handle the canonical `axiom` tag. Use `identity.tags` for labels, badges, and filtering in most apps. Use the raw `tags` object when you specifically need `isArbitrage` or the original platform array. SNS adds `identity.sns.domain` and the `sns` tag when a primary `.sol` domain exists. Curated labels keep `identity.name`; SNS is attached in parallel (for example `tags: ["kol", "sns"]`). See [SNS Primary Domain](/guides/pnl-v2/sns-identity). # Query Kalshi and Polymarket market data Source: https://docs.solanatracker.io/guides/prediction-markets Query Kalshi and Polymarket markets, trades, candles, orderbooks, and wallet analytics with the Solana Tracker Prediction Markets API. Use the Prediction Markets API for Kalshi and Polymarket data. Start by finding a market and its exchange-specific ID, then request history, prices, books, or wallet analytics. **Public Beta** — Unified Kalshi + Polymarket market data with full history. Join [Discord](https://discord.gg/JH2e9rR9fc) for support. **Base URL:** `https://prediction-market-api.solanatracker.io`\ **Auth:** `x-api-key: YOUR_API_KEY` (same Data API key)\ **Realtime:** [Datastream prediction rooms](/guides/datastream-prediction-markets) ## First request ```bash cURL theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/trending?limit=5" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://prediction-market-api.solanatracker.io/v1/markets/trending?limit=5", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const data = await res.json(); console.log(data); ``` ```python Python theme={null} import requests res = requests.get( "https://prediction-market-api.solanatracker.io/v1/markets/trending", params={"limit": 5}, headers={"x-api-key": "YOUR_API_KEY"}, ) print(res.json()) ``` ## Exchanges Set `exchange` on endpoints that support it. `poly` is an alias for `polymarket`. | Value | Platform | | - | - | | `kalshi` | Kalshi | | `polymarket` / `poly` | Polymarket | | omit | Both (where supported) | ## Discover markets | Endpoint | Use for | | - | - | | `GET /v1/markets/trending` | Hot markets | | `GET /v1/markets/new` | Recently listed | | `GET /v1/markets/search` | Text by text | | `GET /v1/browse` | Browse / filter | | `GET /v1/events` | Event groupings with nested markets | | `GET /v1/categories`, `/v1/series`, `/v1/sports` | Taxonomy | ```bash theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/search?q=bitcoin&exchange=polymarket" \ -H "x-api-key: YOUR_API_KEY" ``` Fetch a single market with the identifier expected by its exchange, or use a market slug: ```bash theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/{ticker}" \ -H "x-api-key: YOUR_API_KEY" curl "https://prediction-market-api.solanatracker.io/v1/markets/slug/{slug}" \ -H "x-api-key: YOUR_API_KEY" ``` ## Historical data Use these endpoints for historical trades and candles: | Endpoint | Returns | | - | - | | `GET /v1/markets/{ticker}/trades` | Trade tape for one market | | `GET /v1/markets/trades` | Cross-market trades | | `GET /v1/markets/{ticker}/candlesticks` | OHLCV for one market | | `GET /v1/events/{event_id}/candlesticks` | Event-level candles | | `GET /v1/markets/candlesticks/batch` | Batch candles | ```bash theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/{ticker}/candlesticks?interval=1h" \ -H "x-api-key: YOUR_API_KEY" ``` ## Live market state (REST) | Endpoint | Returns | | - | - | | `GET /v1/markets/{ticker}/price` | Latest price | | `GET /v1/markets/{ticker}/midpoint` | Mid | | `GET /v1/markets/{ticker}/spread` | Spread | | `GET /v1/markets/{ticker}/orderbook` | Full book | | `GET /v1/markets/{ticker}/quote` | Size-aware VWAP ladder | | `GET /v1/markets/books` | Batch books | For continuous updates, subscribe on Datastream instead of polling — see the [realtime guide](/guides/datastream-prediction-markets). ## Crypto up/down (polymarket) | Endpoint | Returns | | - | - | | `GET /v1/crypto/events` | Active / recent crypto windows | | `GET /v1/crypto/price` | Live underlying | | `GET /v1/crypto/price-history` | Historical underlying | | `GET /v1/events/{event_id}/crypto` | Price-to-beat / final for a window | | `GET /v1/crypto/traders` | Window traders | Underlying Chainlink ticks also stream on `pm:crypto:{asset}` rooms. Outcome chance uses market price rooms (`pm:market:polymarket:{tokenId}:prices`). ## Wallet analytics (polymarket) Kalshi has no public wallets. Polymarket account endpoints use an Ethereum address: | Endpoint | Returns | | - | - | | `GET /v1/accounts/{address}/overview` | Summary | | `GET /v1/accounts/{address}/positions` | Open positions | | `GET /v1/accounts/{address}/closed-positions` | Closed / resolved | | `GET /v1/accounts/{address}/pnl` | FIFO PnL | | `GET /v1/accounts/{address}/pnl/chart` | PnL chart | | `GET /v1/accounts/{address}/trades` | Fills | | `GET /v1/accounts/{address}/activity` | Ledger activity | Leaderboards: `GET /v1/leaderboard/pnl`, `GET /v1/leaderboard/traders`, plus event-scoped variants under `/v1/events/{event_id}/...`. ## Batch helpers | Endpoint | Notes | | - | - | | `GET` / `POST /v1/markets/batch` | Many markets in one call | | `GET /v1/events/batch` | Many events | | `GET /v1/markets/candlesticks/batch` | Many candle series | | `GET /v1/markets/books` | Many orderbooks | ## Next steps Scope, IDs, and conventions. Live trades, prices, books, and volume rooms. # Get Solana token prices and OHLCV charts Source: https://docs.solanatracker.io/guides/price-and-charts Query Solana token prices, historical OHLCV candles, timestamp prices, and batch price snapshots with the Solana Tracker Data API. Use a price snapshot for the current value and OHLCV candles for chart history. For a live chart, load the history first, then update it with a Datastream price subscription. ## Live price The [price endpoint](/data-api/price/get-token-price) returns the current price for any token. ```bash cURL theme={null} curl "https://data.solanatracker.io/price?token=So11111111111111111111111111111111111111112" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://data.solanatracker.io/price?token=So11111111111111111111111111111111111111112", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { price } = await res.json(); console.log(`SOL: $${price}`); ``` ## Multiple token prices Use the [multi-price endpoint](/data-api/price/get-multiple-token-prices) to fetch several price snapshots in one request. ```bash GET (comma-separated) theme={null} curl "https://data.solanatracker.io/price/multi?tokens=So111...112,38Pgz...pump" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash POST (JSON body) theme={null} curl -X POST "https://data.solanatracker.io/price/multi" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tokens": ["So111...112", "38Pgz...pump"] }' ``` ## OHLCV chart data The [OHLCV endpoint](/data-api/chart/get-ohlcv-data-for-a-token) returns candlestick data for charting. OHLCV means open, high, low, close, and volume. Example Solana token chart with price candles, volume bars, and holder data ```bash cURL theme={null} curl "https://data.solanatracker.io/chart/{token}?type=1h&time_from=1710000000&time_to=1710086400" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch( `https://data.solanatracker.io/chart/${token}?type=1h&time_from=1710000000&time_to=1710086400`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const candles = await res.json(); candles.forEach(c => { console.log(`${new Date(c.time * 1000).toISOString()}: O=${c.open} H=${c.high} L=${c.low} C=${c.close} V=${c.volume}`); }); ``` ### Candle intervals | `type` value | Interval | | - | - | | `1s` | 1 second | | `5s` | 5 seconds | | `15s` | 15 seconds | | `1m` | 1 minute | | `3m` | 3 minutes | | `5m` | 5 minutes | | `15m` | 15 minutes | | `30m` | 30 minutes | | `1h` | 1 hour | | `2h` | 2 hours | | `4h` | 4 hours | | `6h` | 6 hours | | `8h` | 8 hours | | `12h` | 12 hours | | `1d` | 1 day | | `3d` | 3 days | | `1w` | 1 week | | `1mn` | 1 month | ### Outlier removal OHLCV responses remove extreme outliers by default. Set `removeOutliers=false` when you need the unfiltered series: ```bash theme={null} curl "https://data.solanatracker.io/chart/{token}?type=1h&removeOutliers=false" \ -H "x-api-key: YOUR_API_KEY" ``` Keep the same outlier setting across requests so adjacent chart windows use the same filtering rules. ### Pool-specific charts For tokens with multiple pools, use the [pool-specific OHLCV endpoint](/data-api/chart/get-ohlcv-data-for-a-tokenpool-pair) to get candles from a specific pool: ```bash theme={null} curl "https://data.solanatracker.io/chart/{token}/{pool}?type=1h" \ -H "x-api-key: YOUR_API_KEY" ``` ## Historical prices ### Price at a specific time Use the [timestamp price endpoint](/data-api/price/get-price-at-specific-timestamp) to request a historical price near a given time. ```bash theme={null} curl "https://data.solanatracker.io/price/history/timestamp?token={token}×tamp=1710000000" \ -H "x-api-key: YOUR_API_KEY" ``` ### Price history (time series) The [price history endpoint](/data-api/price/get-historic-price-information) returns historical price data points. ```bash theme={null} curl "https://data.solanatracker.io/price/history?token={token}" \ -H "x-api-key: YOUR_API_KEY" ``` ### Price range (high/low) The [price range endpoint](/data-api/price/get-lowest-and-highest-price-in-time-range) returns the minimum and maximum price within a time window. ```bash theme={null} curl "https://data.solanatracker.io/price/history/range?token={token}&time_from=1710000000&time_to=1710086400" \ -H "x-api-key: YOUR_API_KEY" ``` ## Example: build a price dashboard ```javascript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const headers = { "x-api-key": "YOUR_API_KEY" }; // Current price const { price } = await fetch( `https://data.solanatracker.io/price?token=${token}`, { headers } ).then(r => r.json()); // Last 24h candles (1 hour intervals) const now = Math.floor(Date.now() / 1000); const candles = await fetch( `https://data.solanatracker.io/chart/${token}?type=1h&time_from=${now - 86400}&time_to=${now}`, { headers } ).then(r => r.json()); // ATH const ath = await fetch( `https://data.solanatracker.io/tokens/${token}/ath`, { headers } ).then(r => r.json()); console.log(`Current: $${price}`); console.log(`24h candles: ${candles.length}`); console.log(`ATH: $${ath.highest}`); ``` ### Open-source chart examples Minimal real-time line chart using the Datastream WebSocket. Full TradingView integration with real-time candle updates. Stream real-time prices and build live updating charts. Full token lookup: stats, holders, trades, and events. # Track Pump.fun launches, curves, and graduations Source: https://docs.solanatracker.io/guides/pumpfun Find Pump.fun tokens, follow bonding curve progress, detect graduation, and query post-migration pools with Solana Tracker APIs. Follow a Pump.fun token from its first indexed pool through curve completion and migration. Use REST to load a snapshot and Datastream to receive new launches and graduation events. ## Lifecycle overview The API separates creation, curve progress, and migration: 1. **Created** — the token launches on the bonding curve. 2. **Graduating** — the bonding curve fills up from 0–100%. 3. **Graduated** — the curve is complete, and liquidity moves to a DEX pool. You can track each stage with REST endpoints, real-time WebSocket streams, or both. ## Find new Pump.fun tokens ### REST: latest tokens ```bash theme={null} curl "https://data.solanatracker.io/tokens/latest" \ -H "x-api-key: YOUR_API_KEY" ``` Filter the response by `pools[0].market` to isolate Pump.fun tokens: ```javascript theme={null} const headers = { "x-api-key": "YOUR_API_KEY" }; const latest = await fetch( "https://data.solanatracker.io/tokens/latest", { headers } ).then(r => r.json()); const pumpfun = latest.filter(t => t.pools?.[0]?.market === "pumpfun"); console.log(`${pumpfun.length} new Pump.fun tokens`); ``` ### REST: search with filters Use the [search endpoint](/data-api/search/token-search) to find Pump.fun tokens with specific criteria: ```bash theme={null} # Pump.fun tokens with >50% curve, has socials, >$1k liquidity curl "https://data.solanatracker.io/search?launchpad=pumpfun&minCurvePercentage=50&hasSocials=true&minLiquidity=1000" \ -H "x-api-key: YOUR_API_KEY" ``` Key search filters for Pump.fun: | Parameter | Description | | - | - | | `launchpad` | `pumpfun`, or comma-separated for multiple | | `market` | `pumpfun` for bonding curve, `pumpfun-amm` for graduated | | `status` | `graduating` or `graduated` | | `minCurvePercentage` | Minimum bonding curve % (0–100) | | `maxCurvePercentage` | Maximum bonding curve % (0–100) | | `minGraduatedAt` | Only tokens graduated after this timestamp (ms) | | `maxGraduatedAt` | Only tokens graduated before this timestamp (ms) | ### REST: tokens by deployer Find all tokens launched by a specific wallet: ```bash theme={null} curl "https://data.solanatracker.io/deployer/{wallet}?launchpad=pumpfun" \ -H "x-api-key: YOUR_API_KEY" ``` ### WebSocket: live feed Subscribe to new indexed tokens, then keep Pump.fun rows: ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "latest" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools } = msg.data; if (pools[0]?.market !== "pumpfun") return; console.log(`New Pump.fun: ${token.name} (${token.symbol})`); console.log(` Mint: ${token.mint}`); console.log(` Deployer: ${pools[0]?.deployer}`); }; ``` ## Track bonding curve progress ### REST: graduating tokens Query tokens approaching bonding curve completion: ```bash theme={null} # Tokens with curve > 60%, at least 20 holders curl "https://data.solanatracker.io/tokens/multi/graduating?minCurve=60&minHolders=20" \ -H "x-api-key: YOUR_API_KEY" ``` | Parameter | Description | Default | | - | - | - | | `limit` | Number of tokens (max 500) | 100 | | `minCurve` | Minimum curve % | 40 | | `maxCurve` | Maximum curve % | 100 | | `minHolders` | Minimum holder count | 20 | | `markets` | Filter by market (comma-separated) | all | | `minLiquidity` | Minimum liquidity (USD) | — | | `minMarketCap` | Minimum market cap (USD) | — | | `reduceSpam` | Filter out quick-graduated spam | — | ### WebSocket: graduating stream ```javascript theme={null} // All graduating tokens ws.send(JSON.stringify({ type: "join", room: "graduating" })); // Only Pump.fun tokens with at least 50 SOL in the curve ws.send(JSON.stringify({ type: "join", room: "graduating:pumpfun:50" })); ``` ### WebSocket: curve percentage alerts Get notified when any token hits a specific bonding curve milestone: ```javascript theme={null} // Alert at 30% — early signal ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:30" })); // Alert at 50% — halfway ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:50" })); // Alert at 80% — approaching graduation ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:80" })); ``` Supported markets for curve alerts: `pumpfun`, `launchpad`, `boop`, `meteora-curve`. ## Detect graduation ### REST: recently graduated ```bash theme={null} curl "https://data.solanatracker.io/tokens/multi/graduated?limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` | Parameter | Description | | - | - | | `limit` | Number of tokens (max 500) | | `page` | Pagination page number | | `reduceSpam` | Filter out quick-graduated tokens | | `markets` | Filter by market | | `minLiquidity` | Minimum post-graduation liquidity | ### WebSocket: graduated stream ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "graduated" })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const { token, pools, graduationTx, graduationTime } = msg.data; console.log(`Graduated: ${token.name}`); console.log(` Pool: ${pools[0]?.poolId}`); console.log(` Liquidity: $${pools[0]?.liquidity?.usd?.toLocaleString()}`); console.log(` Tx: ${graduationTx}`); }; ``` ### REST: graduation timestamp for a specific token `GET /tokens/{tokenAddress}` and `POST /tokens/multi` do not include a graduation timestamp field. To fetch **when** a specific token graduated, use the [search endpoint](/data-api/search/token-search) — it returns a `graduatedAt` field (Unix ms, `null` if the token has not graduated). ```bash theme={null} curl "https://data.solanatracker.io/search?query=&status=graduated" \ -H "x-api-key: YOUR_API_KEY" ``` The response includes `data[].graduatedAt`. You can also filter by graduation window using `minGraduatedAt` / `maxGraduatedAt`. ## Example: graduation pipeline Watch tokens across their full Pump.fun lifecycle: ```javascript theme={null} const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY"); ws.onopen = () => { ws.send(JSON.stringify({ type: "join", room: "pumpfun:curve:50" })); ws.send(JSON.stringify({ type: "join", room: "graduating:pumpfun:50" })); ws.send(JSON.stringify({ type: "join", room: "graduated" })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type !== "message") return; const room = msg.room; const name = msg.data?.token?.name || "Unknown"; if (room?.includes("curve:")) { console.log(`[50% CURVE] ${name}`); } else if (room === "graduating") { console.log(`[GRADUATING] ${name}`); } else if (room === "graduated") { console.log(`[GRADUATED] ${name} — now on DEX`); } }; ``` ## Swap Pump.fun tokens Use the [Raptor Swap API](/raptor/overview) to buy and sell Pump.fun tokens. It handles bonding curve swaps and post-graduation DEX swaps automatically. ```javascript theme={null} const headers = { "Content-Type": "application/json" }; // Buy a Pump.fun token with 0.1 SOL const response = await fetch("https://swap-v2.solanatracker.io/swap", { method: "POST", headers, body: JSON.stringify({ wallet: "YOUR_WALLET_ADDRESS", from: "So11111111111111111111111111111111111111112", to: "TOKEN_MINT_ADDRESS", amount: 0.1, slippage: 15, priorityFee: 0.0005 }) }); const { txn } = await response.json(); // Sign and send the transaction ``` Raptor selects supported routes for the token's current pools, including bonding curve and migrated liquidity. See the full [Swap API guide](/guides/swap-api) for sending transactions and WebSocket streaming. ## Risk signals Pump.fun tokens carry specific risks you can monitor: | Risk Factor | Score | Meaning | | - | - | - | | Pump.fun contract risks | 10 | Pump.fun contracts can be changed by Pump.fun at any time | | Incomplete bonding curve | 4000 | No DEX liquidity yet, still on the curve | Use these Datastream rooms to monitor safety signals on any Pump.fun token: | Room | What it tracks | | - | - | | `sniper:{token}` | Sniper wallet balance changes | | `bundlers:{token}` | Bundled transaction wallets | | `insider:{token}` | Insider wallet movements | | `dev_holding:{token}` | Creator/deployer holdings | | `holders:{token}` | Total holder count | | `top10:{token}` | Top 10 holder concentration | See the [Safety Streams guide](/guides/datastream-safety) for full examples. ## Program IDs & instructions For instruction construction or transaction parsing, use these program references: | Program | ID | Docs | | - | - | - | | Bonding curve | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` | [Program ID, IDL, buy/sell](/guides/pumpfun-program) | | Pump.fun AMM (PumpSwap) | `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` | [AMM ID, IDL, buy/sell](/guides/pumpfun-amm) | IDL downloads: [/idl/pump.json](/idl/pump.json), [/idl/pump\_amm.json](/idl/pump_amm.json). ## Yellowstone grpc (advanced) For low-level transaction parsing, use Yellowstone gRPC to stream raw Pump.fun transactions directly from Solana: * [Pump.fun Buy/Sell Detection](/yellowstone-grpc/examples/pumpfun-transactions) — parse buy/sell events with full IDL decoding * [Pump.fun Account Streaming](/yellowstone-grpc/examples/pumpfun-accounts) — monitor bonding curve account state changes ## Room reference | Room | What you get | | - | - | | `latest` | All new tokens (filter by `market === "pumpfun"`) | | `graduating` | All tokens approaching curve completion | | `graduating:pumpfun:{sol}` | Pump.fun tokens with minimum SOL in curve | | `graduated` | All tokens that just migrated to DEX | | `pumpfun:curve:{pct}` | Tokens hitting a specific curve % | ## API endpoints | Endpoint | Description | | - | - | | [GET /tokens/multi/graduating](/data-api/tokens/get-graduating-tokens) | Tokens on bonding curve | | [GET /tokens/multi/graduated](/data-api/tokens/get-graduated-tokens) | Recently graduated tokens | | [GET /tokens/latest](/data-api/tokens/get-latest-tokens) | Newest tokens | | [GET /search](/data-api/search/token-search) | Search with `launchpad=pumpfun` filter | | [GET /deployer/](/data-api/tokens/get-tokens-by-deployer) | Tokens by deployer wallet | Program ID, Anchor IDL, and buy/sell discriminators for web3.js. PumpSwap program ID, IDL, and post-graduation buy/sell instructions. Trending, volume leaders, and top performers across all markets. Real-time graduating, graduated, and curve percentage streams. Sniper, bundler, insider, and holder monitoring. Buy and sell tokens through Raptor with automatic routing. # PumpSwap program ID, IDL, and swap instructions Source: https://docs.solanatracker.io/guides/pumpfun-amm Find the PumpSwap AMM program ID, Anchor IDL, account layouts, and buy/sell instruction examples for Solana developers. PumpSwap uses a separate AMM program from the Pump.fun bonding curve. Use this reference to identify its program, decode trades, or construct buy/sell instructions from the IDL. Need swaps without assembling AMM accounts? Use the [Raptor Swap API](/raptor/overview) — it routes graduated Pump.fun tokens through PumpSwap and other DEXes. ## Official program IDs | Program | Address | Role | | - | - | - | | **Pump.fun AMM (PumpSwap)** | `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` | Buy/sell, create\_pool, deposit, withdraw | | **Pump.fun (bonding curve)** | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` | Pre-graduation curve + `migrate` into AMM | | **Pump Fees** | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | Fee config for buy/sell | ### Well-known accounts | Account | Notes | | - | - | | `global_config` | PDA with seeds `["global_config"]` — commonly `ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw` | | `event_authority` | PDA seeds `["__event_authority"]` on the AMM program | | `pool` | Per-market pool account (passed into buy/sell) | | Quote mint (typical) | `So11111111111111111111111111111111111111112` (WSOL) | After curve completion, the bonding curve program's `migrate` instruction creates the AMM pool. ## Anchor IDL Use the bundled IDL or compare it with the upstream Pump.fun repository: * **JSON IDL:** [/idl/pump\_amm.json](/idl/pump_amm.json) * Upstream: [idl/pump\_amm.json](https://github.com/pump-fun/pump-public-docs/blob/main/idl/pump_amm.json) ```javascript theme={null} import idl from "./idl/pump_amm.json" assert { type: "json" }; console.log(idl.address); // pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA ``` ## Instruction discriminators | Instruction | Discriminator (bytes) | Hex | | - | - | - | | `buy` | `[102, 6, 61, 18, 1, 218, 235, 234]` | `0x66063d1201daebea` | | `sell` | `[51, 230, 133, 164, 1, 127, 131, 173]` | `0x33e685a4017f83ad` | | `buy_exact_quote_in` | `[198, 46, 21, 82, 180, 217, 232, 112]` | `0xc62e1552b4d9e870` | | `create_pool` | `[233, 146, 209, 142, 207, 104, 64, 188]` | `0xe992d18ecf6840bc` | | `deposit` | `[242, 35, 198, 137, 82, 225, 242, 182]` | `0xf223c68952e1f2b6` | | `withdraw` | `[183, 18, 70, 156, 148, 109, 161, 34]` | `0xb712469c946da122` | AMM `buy` / `sell` use the **same** Anchor sighashes as bonding-curve `buy` / `sell`. Disambiguate by program ID: `pAMMBay…` (AMM) vs `6EF8rrecth…` (curve). ### Detect amm buy vs sell in Rust ```rust theme={null} const PUMP_AMM: &str = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"; const BUY: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234]; const SELL: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173]; fn is_amm_buy(program_id: &str, data: &[u8]) -> bool { program_id == PUMP_AMM && data.get(..8) == Some(&BUY) } ``` ## `buy` instruction **Args** | Arg | Type | Meaning | | - | - | - | | `base_amount_out` | `u64` | Tokens to receive | | `max_quote_amount_in` | `u64` | Max quote (e.g. WSOL lamports) to spend | | `track_volume` | `OptionBool` | `{ 0 }` / `{ 1 }` | **Accounts** | # | Account | Writable | Signer | | - | - | - | - | | 0 | `pool` | ✓ | | | 1 | `user` | ✓ | ✓ | | 2 | `global_config` | | | | 3 | `base_mint` | | | | 4 | `quote_mint` | | | | 5 | `user_base_token_account` | ✓ | | | 6 | `user_quote_token_account` | ✓ | | | 7 | `pool_base_token_account` | ✓ | | | 8 | `pool_quote_token_account` | ✓ | | | 9 | `protocol_fee_recipient` | | | | 10 | `protocol_fee_recipient_token_account` | ✓ | | | 11 | `base_token_program` | | | | 12 | `quote_token_program` | | | | 13 | `system_program` | | | | 14 | `associated_token_program` | | | | 15 | `event_authority` | | | | 16 | `program` | | | | 17 | `coin_creator_vault_ata` | ✓ | | | 18 | `coin_creator_vault_authority` | | | | 19 | `global_volume_accumulator` | | | | 20 | `user_volume_accumulator` | ✓ | | | 21 | `fee_config` | | | | 22 | `fee_program` | | | ## `sell` instruction **Args** | Arg | Type | Meaning | | - | - | - | | `base_amount_in` | `u64` | Tokens to sell | | `min_quote_amount_out` | `u64` | Min quote out (slippage) | **Accounts** — same shape as `buy` through `coin_creator_vault_authority` (indices 0–18), then `fee_config` (19) and `fee_program` (20). Sell does **not** pass the volume accumulator accounts. ## Buy / sell with `@solana/web3.js` ```javascript theme={null} import { PublicKey, TransactionInstruction, SystemProgram, } from "@solana/web3.js"; import { TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, } from "@solana/spl-token"; export const PUMP_AMM_PROGRAM_ID = new PublicKey( "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA" ); export const PUMP_FEE_PROGRAM_ID = new PublicKey( "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ" ); export const GLOBAL_CONFIG = new PublicKey( "ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw" ); const BUY_DISC = Buffer.from([102, 6, 61, 18, 1, 218, 235, 234]); const SELL_DISC = Buffer.from([51, 230, 133, 164, 1, 127, 131, 173]); function u64le(n) { const b = Buffer.alloc(8); b.writeBigUInt64LE(BigInt(n)); return b; } export function ammEventAuthority() { return PublicKey.findProgramAddressSync( [Buffer.from("__event_authority")], PUMP_AMM_PROGRAM_ID )[0]; } export function ammFeeConfigPda() { return PublicKey.findProgramAddressSync( [Buffer.from("fee_config"), PUMP_AMM_PROGRAM_ID.toBuffer()], PUMP_FEE_PROGRAM_ID )[0]; } export function coinCreatorVaultAuthority(coinCreator) { return PublicKey.findProgramAddressSync( [Buffer.from("creator_vault"), coinCreator.toBuffer()], PUMP_AMM_PROGRAM_ID )[0]; } /** * Minimal PumpSwap buy. Resolve pool vaults, fee recipient, and coin_creator * from the pool account / a recent mainnet tx before production use. */ export function buildAmmBuyIx({ pool, user, baseMint, quoteMint, poolBaseTokenAccount, poolQuoteTokenAccount, protocolFeeRecipient, coinCreator, baseAmountOut, maxQuoteAmountIn, trackVolume = false, baseTokenProgram = TOKEN_PROGRAM_ID, quoteTokenProgram = TOKEN_PROGRAM_ID, }) { const userBase = getAssociatedTokenAddressSync( baseMint, user, false, baseTokenProgram ); const userQuote = getAssociatedTokenAddressSync( quoteMint, user, false, quoteTokenProgram ); const protocolFeeAta = getAssociatedTokenAddressSync( quoteMint, protocolFeeRecipient, true, quoteTokenProgram ); const creatorAuthority = coinCreatorVaultAuthority(coinCreator); const creatorAta = getAssociatedTokenAddressSync( quoteMint, creatorAuthority, true, quoteTokenProgram ); const [globalVolume] = PublicKey.findProgramAddressSync( [Buffer.from("global_volume_accumulator")], PUMP_AMM_PROGRAM_ID ); const [userVolume] = PublicKey.findProgramAddressSync( [Buffer.from("user_volume_accumulator"), user.toBuffer()], PUMP_AMM_PROGRAM_ID ); const data = Buffer.concat([ BUY_DISC, u64le(baseAmountOut), u64le(maxQuoteAmountIn), Buffer.from([trackVolume ? 1 : 0]), ]); return new TransactionInstruction({ programId: PUMP_AMM_PROGRAM_ID, keys: [ { pubkey: pool, isSigner: false, isWritable: true }, { pubkey: user, isSigner: true, isWritable: true }, { pubkey: GLOBAL_CONFIG, isSigner: false, isWritable: false }, { pubkey: baseMint, isSigner: false, isWritable: false }, { pubkey: quoteMint, isSigner: false, isWritable: false }, { pubkey: userBase, isSigner: false, isWritable: true }, { pubkey: userQuote, isSigner: false, isWritable: true }, { pubkey: poolBaseTokenAccount, isSigner: false, isWritable: true }, { pubkey: poolQuoteTokenAccount, isSigner: false, isWritable: true }, { pubkey: protocolFeeRecipient, isSigner: false, isWritable: false }, { pubkey: protocolFeeAta, isSigner: false, isWritable: true }, { pubkey: baseTokenProgram, isSigner: false, isWritable: false }, { pubkey: quoteTokenProgram, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: ammEventAuthority(), isSigner: false, isWritable: false }, { pubkey: PUMP_AMM_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: creatorAta, isSigner: false, isWritable: true }, { pubkey: creatorAuthority, isSigner: false, isWritable: false }, { pubkey: globalVolume, isSigner: false, isWritable: false }, { pubkey: userVolume, isSigner: false, isWritable: true }, { pubkey: ammFeeConfigPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false }, ], data, }); } export function buildAmmSellIx({ pool, user, baseMint, quoteMint, poolBaseTokenAccount, poolQuoteTokenAccount, protocolFeeRecipient, coinCreator, baseAmountIn, minQuoteAmountOut, baseTokenProgram = TOKEN_PROGRAM_ID, quoteTokenProgram = TOKEN_PROGRAM_ID, }) { const userBase = getAssociatedTokenAddressSync( baseMint, user, false, baseTokenProgram ); const userQuote = getAssociatedTokenAddressSync( quoteMint, user, false, quoteTokenProgram ); const protocolFeeAta = getAssociatedTokenAddressSync( quoteMint, protocolFeeRecipient, true, quoteTokenProgram ); const creatorAuthority = coinCreatorVaultAuthority(coinCreator); const creatorAta = getAssociatedTokenAddressSync( quoteMint, creatorAuthority, true, quoteTokenProgram ); const data = Buffer.concat([ SELL_DISC, u64le(baseAmountIn), u64le(minQuoteAmountOut), ]); return new TransactionInstruction({ programId: PUMP_AMM_PROGRAM_ID, keys: [ { pubkey: pool, isSigner: false, isWritable: true }, { pubkey: user, isSigner: true, isWritable: true }, { pubkey: GLOBAL_CONFIG, isSigner: false, isWritable: false }, { pubkey: baseMint, isSigner: false, isWritable: false }, { pubkey: quoteMint, isSigner: false, isWritable: false }, { pubkey: userBase, isSigner: false, isWritable: true }, { pubkey: userQuote, isSigner: false, isWritable: true }, { pubkey: poolBaseTokenAccount, isSigner: false, isWritable: true }, { pubkey: poolQuoteTokenAccount, isSigner: false, isWritable: true }, { pubkey: protocolFeeRecipient, isSigner: false, isWritable: false }, { pubkey: protocolFeeAta, isSigner: false, isWritable: true }, { pubkey: baseTokenProgram, isSigner: false, isWritable: false }, { pubkey: quoteTokenProgram, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: ammEventAuthority(), isSigner: false, isWritable: false }, { pubkey: PUMP_AMM_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: creatorAta, isSigner: false, isWritable: true }, { pubkey: creatorAuthority, isSigner: false, isWritable: false }, { pubkey: ammFeeConfigPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false }, ], data, }); } ``` Live PumpSwap `buy` instructions often append **remaining accounts** after the 23 IDL accounts (observed +3 on mainnet). `sell` may append +2. Base mints are frequently Token-2022 (`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`) while quote is WSOL on the legacy token program. Decode the pool with [/idl/pump\_amm.json](/idl/pump_amm.json) or copy accounts from a recent successful swap before mainnet use. ### Easier path: Raptor + data API ```bash theme={null} # Find graduated Pump.fun / PumpSwap markets curl "https://data.solanatracker.io/search?market=pumpfun-amm&limit=20" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript theme={null} // Swap a graduated token (Raptor picks PumpSwap / best route) await fetch("https://swap-v2.solanatracker.io/swap", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ wallet: "YOUR_WALLET_ADDRESS", from: "TOKEN_MINT_ADDRESS", to: "So11111111111111111111111111111111111111112", amount: 1000000, slippage: 15, }), }); ``` ## Stream & index with Solana tracker | Product | Use for | | - | - | | [Pump.fun API](https://www.solanatracker.io/pumpfun-api) | Graduated token data, trades, OHLCV | | [Data API](https://www.solanatracker.io/data-api) | `market=pumpfun-amm`, `/tokens/multi/graduated` | | [Datastream](https://www.solanatracker.io/data-api) | `graduated` room + per-token trade streams | | [Memescope](https://www.solanatracker.io/memescope) | Migrated / PumpSwap column in the live feed | | [Raptor](https://www.solanatracker.io/raptor) | Execute sells/buys on PumpSwap pools | | [Yellowstone gRPC](https://www.solanatracker.io/yellowstone-grpc) | Subscribe to `pAMMBay…` program transactions | | [Solana RPC](https://www.solanatracker.io/solana-rpc) | Fetch pool accounts and confirm swaps | Docs: * [Pump.fun bonding curve program](/guides/pumpfun-program) — `6EF8rrecth…` buy/sell/create * [Pump.fun lifecycle](/guides/pumpfun) — discover → curve → graduate → swap * [Token discovery](/guides/token-discovery) — graduating / graduated endpoints * [gRPC buy/sell detection](/yellowstone-grpc/examples/pumpfun-transactions) Bonding curve program ID, IDL, create/buy/sell discriminators. Track launches and graduations with Solana Tracker APIs. Buy and sell without building AMM instructions. Live migrated / PumpSwap token feed. # Pump.fun program ID, IDL, and instructions Source: https://docs.solanatracker.io/guides/pumpfun-program Find the Pump.fun bonding curve program ID, Anchor IDL, instruction discriminators, and buy/sell examples for Solana transaction parsers. Use this reference when building or decoding Pump.fun bonding curve instructions. It covers the program ID, accounts, discriminators, and buy/sell layout. For post-graduation trades, use the PumpSwap program reference. Prefer not to hand-build instructions? [Raptor Swap API](/raptor/overview) routes buys and sells across Pump.fun bonding curves and PumpSwap automatically. ## Official program IDs | Program | Address | Role | | - | - | - | | **Pump.fun (bonding curve)** | `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` | Create tokens, buy/sell on the curve, migrate | | **Pump.fun AMM (PumpSwap)** | `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` | Post-graduation constant-product pools | | **Pump Fees** | `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` | Fee config used by buy/sell | Copy the program ID exactly. Base58 addresses are case-sensitive; the `r` after `6EF8` is lowercase. ### Well-known pdas | Account | Seeds | Address | | - | - | - | | `global` | `["global"]` | `4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf` | | `event_authority` | `["__event_authority"]` | PDA of the Pump program | | `bonding_curve` | `["bonding-curve", mint]` | Per-token curve account | Solana Tracker market filters: `pumpfun` (bonding curve), `pumpfun-amm` (graduated / PumpSwap). ## Anchor IDL Download the official Anchor IDL (mirrored from [pump-fun/pump-public-docs](https://github.com/pump-fun/pump-public-docs)): * **JSON IDL:** [/idl/pump.json](/idl/pump.json) * Upstream: [idl/pump.json](https://github.com/pump-fun/pump-public-docs/blob/main/idl/pump.json) ```javascript theme={null} import idl from "./idl/pump.json" assert { type: "json" }; // or: const idl = require("./idl/pump.json"); console.log(idl.address); // 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P ``` Load the IDL with Anchor's `Program` or `BorshInstructionCoder`, or use the discriminators below when parsing raw instructions. ## Instruction discriminators Anchor discriminators are the first **8 bytes** of `sha256("global:")`. Match these when parsing transactions or building instructions manually. | Instruction | Discriminator (bytes) | Hex | | - | - | - | | `buy` | `[102, 6, 61, 18, 1, 218, 235, 234]` | `0x66063d1201daebea` | | `sell` | `[51, 230, 133, 164, 1, 127, 131, 173]` | `0x33e685a4017f83ad` | | `create` | `[24, 30, 200, 40, 5, 28, 7, 119]` | `0x181ec828051c0777` | | `create_v2` | `[214, 144, 76, 236, 95, 139, 49, 180]` | `0xd6904cec5f8b31b4` | | `buy_exact_sol_in` | `[56, 252, 116, 8, 158, 223, 205, 95]` | `0x38fc74089edfcd5f` | | `buy_v2` | `[184, 23, 238, 97, 103, 197, 211, 61]` | `0xb817ee6167c5d33d` | | `sell_v2` | `[93, 246, 130, 60, 231, 233, 64, 178]` | `0x5df6823ce7e940b2` | | `migrate` | `[155, 234, 231, 146, 236, 158, 162, 30]` | `0x9beae792ec9ea21e` | `buy` / `sell` on the **AMM** reuse the same sighashes — always check the **program ID** (`6EF8rrecth…` vs `pAMMBay…`) when classifying trades. On mainnet, many curve swaps use `buy_exact_sol_in` (`0x38fc74089edfcd5f`) rather than classic `buy`. Parsers should handle both. ### Detect buy vs sell in Rust ```rust theme={null} const BUY: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234]; const SELL: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173]; const CREATE: [u8; 8] = [24, 30, 200, 40, 5, 28, 7, 119]; fn classify(data: &[u8]) -> Option<&'static str> { let disc = data.get(..8)?; if disc == BUY { Some("buy") } else if disc == SELL { Some("sell") } else if disc == CREATE { Some("create") } else { None } } ``` ## `buy` instruction **Args** | Arg | Type | Meaning | | - | - | - | | `amount` | `u64` | Token amount out (base units) | | `max_sol_cost` | `u64` | Slippage cap in lamports | | `track_volume` | `OptionBool` | `{ 0 }` = false, `{ 1 }` = true | **Accounts** | # | Account | Writable | Signer | | - | - | - | - | | 0 | `global` | | | | 1 | `fee_recipient` | ✓ | | | 2 | `mint` | | | | 3 | `bonding_curve` | ✓ | | | 4 | `associated_bonding_curve` | ✓ | | | 5 | `associated_user` | ✓ | | | 6 | `user` | ✓ | ✓ | | 7 | `system_program` | | | | 8 | `token_program` | | | | 9 | `creator_vault` | ✓ | | | 10 | `event_authority` | | | | 11 | `program` | | | | 12 | `global_volume_accumulator` | | | | 13 | `user_volume_accumulator` | ✓ | | | 14 | `fee_config` | | | | 15 | `fee_program` | | | Read `fee_recipient` (and the `fee_recipients` array) from the `global` account. Pass `fee_program` = `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ`. ## `sell` instruction **Args** | Arg | Type | Meaning | | - | - | - | | `amount` | `u64` | Token amount in (base units) | | `min_sol_output` | `u64` | Slippage floor in lamports | **Accounts** | # | Account | Writable | Signer | | - | - | - | - | | 0 | `global` | | | | 1 | `fee_recipient` | ✓ | | | 2 | `mint` | | | | 3 | `bonding_curve` | ✓ | | | 4 | `associated_bonding_curve` | ✓ | | | 5 | `associated_user` | ✓ | | | 6 | `user` | ✓ | ✓ | | 7 | `system_program` | | | | 8 | `creator_vault` | ✓ | | | 9 | `token_program` | | | | 10 | `event_authority` | | | | 11 | `program` | | | | 12 | `fee_config` | | | | 13 | `fee_program` | | | ## `create` instruction **Args:** `name: string`, `symbol: string`, `uri: string`, `creator: pubkey`\ **Discriminator:** `[24, 30, 200, 40, 5, 28, 7, 119]` Newer launches often use `create_v2` (Token-2022 / Mayhem / cashback fields). Prefer matching live transactions or the IDL when integrating creation flows. ## Buy / sell with `@solana/web3.js` Encode the Anchor discriminator, then little-endian `u64` args. `OptionBool` is a single byte (`0` or `1`). ```javascript theme={null} import { PublicKey, TransactionInstruction, SystemProgram, } from "@solana/web3.js"; import { TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from "@solana/spl-token"; import bs58 from "bs58"; export const PUMP_PROGRAM_ID = new PublicKey( "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" ); export const PUMP_FEE_PROGRAM_ID = new PublicKey( "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ" ); export const GLOBAL = new PublicKey( "4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf" ); const BUY_DISC = Buffer.from([102, 6, 61, 18, 1, 218, 235, 234]); const SELL_DISC = Buffer.from([51, 230, 133, 164, 1, 127, 131, 173]); function u64le(n) { const b = Buffer.alloc(8); b.writeBigUInt64LE(BigInt(n)); return b; } export function bondingCurvePda(mint) { return PublicKey.findProgramAddressSync( [Buffer.from("bonding-curve"), mint.toBuffer()], PUMP_PROGRAM_ID )[0]; } export function eventAuthorityPda() { return PublicKey.findProgramAddressSync( [Buffer.from("__event_authority")], PUMP_PROGRAM_ID )[0]; } export function creatorVaultPda(creator) { return PublicKey.findProgramAddressSync( [Buffer.from("creator-vault"), creator.toBuffer()], PUMP_PROGRAM_ID )[0]; } export function feeConfigPda() { // seeds: ["fee_config", pump_program_id] on the fee program return PublicKey.findProgramAddressSync( [Buffer.from("fee_config"), PUMP_PROGRAM_ID.toBuffer()], PUMP_FEE_PROGRAM_ID )[0]; } /** Build a Pump.fun bonding-curve buy instruction */ export function buildBuyIx({ mint, user, feeRecipient, creator, // bonding_curve.creator amount, // tokens out maxSolCost, // lamports trackVolume = false, }) { const bondingCurve = bondingCurvePda(mint); const associatedBondingCurve = getAssociatedTokenAddressSync( mint, bondingCurve, true ); const associatedUser = getAssociatedTokenAddressSync(mint, user); const [globalVolume] = PublicKey.findProgramAddressSync( [Buffer.from("global_volume_accumulator")], PUMP_PROGRAM_ID ); const [userVolume] = PublicKey.findProgramAddressSync( [Buffer.from("user_volume_accumulator"), user.toBuffer()], PUMP_PROGRAM_ID ); const data = Buffer.concat([ BUY_DISC, u64le(amount), u64le(maxSolCost), Buffer.from([trackVolume ? 1 : 0]), ]); return new TransactionInstruction({ programId: PUMP_PROGRAM_ID, keys: [ { pubkey: GLOBAL, isSigner: false, isWritable: false }, { pubkey: feeRecipient, isSigner: false, isWritable: true }, { pubkey: mint, isSigner: false, isWritable: false }, { pubkey: bondingCurve, isSigner: false, isWritable: true }, { pubkey: associatedBondingCurve, isSigner: false, isWritable: true }, { pubkey: associatedUser, isSigner: false, isWritable: true }, { pubkey: user, isSigner: true, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: creatorVaultPda(creator), isSigner: false, isWritable: true }, { pubkey: eventAuthorityPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: globalVolume, isSigner: false, isWritable: false }, { pubkey: userVolume, isSigner: false, isWritable: true }, { pubkey: feeConfigPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false }, ], data, }); } /** Build a Pump.fun bonding-curve sell instruction */ export function buildSellIx({ mint, user, feeRecipient, creator, amount, minSolOutput, }) { const bondingCurve = bondingCurvePda(mint); const associatedBondingCurve = getAssociatedTokenAddressSync( mint, bondingCurve, true ); const associatedUser = getAssociatedTokenAddressSync(mint, user); const data = Buffer.concat([SELL_DISC, u64le(amount), u64le(minSolOutput)]); return new TransactionInstruction({ programId: PUMP_PROGRAM_ID, keys: [ { pubkey: GLOBAL, isSigner: false, isWritable: false }, { pubkey: feeRecipient, isSigner: false, isWritable: true }, { pubkey: mint, isSigner: false, isWritable: false }, { pubkey: bondingCurve, isSigner: false, isWritable: true }, { pubkey: associatedBondingCurve, isSigner: false, isWritable: true }, { pubkey: associatedUser, isSigner: false, isWritable: true }, { pubkey: user, isSigner: true, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: creatorVaultPda(creator), isSigner: false, isWritable: true }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: eventAuthorityPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: feeConfigPda(), isSigner: false, isWritable: false }, { pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false }, ], data, }); } // Identify buy/sell from a confirmed transaction export function parsePumpInstructionData(dataBase58) { const data = Buffer.from(bs58.decode(dataBase58)); const disc = data.subarray(0, 8); if (disc.equals(BUY_DISC)) { return { name: "buy", amount: data.readBigUInt64LE(8), maxSolCost: data.readBigUInt64LE(16), }; } if (disc.equals(SELL_DISC)) { return { name: "sell", amount: data.readBigUInt64LE(8), minSolOutput: data.readBigUInt64LE(16), }; } return null; } ``` Live mainnet instructions often append **remaining accounts** after the IDL list (commonly +2 on `buy` / `buy_exact_sol_in` / `sell` for cashback or bonding-curve-v2 flows). Token-2022 mints use `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` instead of the legacy token program. Always cross-check a recent successful transaction and the latest [/idl/pump.json](/idl/pump.json) before shipping. For Token-2022 / multi-quote flows, prefer `buy_v2` / `sell_v2` from the IDL. ### Easier path: Raptor swap API ```javascript theme={null} const res = await fetch("https://swap-v2.solanatracker.io/swap", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ wallet: "YOUR_WALLET_ADDRESS", from: "So11111111111111111111111111111111111111112", to: "TOKEN_MINT_ADDRESS", amount: 0.1, slippage: 15, priorityFee: 0.0005, }), }); const { txn } = await res.json(); // Sign and send txn ``` See [Swap API](/guides/swap-api) and [Raptor overview](/raptor/overview). ## Stream & index with Solana tracker Choose the interface that matches the level of data you need: | Product | Use for | | - | - | | [Pump.fun API](https://www.solanatracker.io/pumpfun-api) | Indexed launches, curves, trades, holders | | [Data API](https://www.solanatracker.io/data-api) | REST: `/tokens/latest`, `/search?launchpad=pumpfun`, graduating/graduated | | [Datastream](https://www.solanatracker.io/data-api) | WebSocket rooms: `latest`, `graduating:pumpfun:50`, `pumpfun:curve:50` | | [Memescope](https://www.solanatracker.io/memescope) | Live launch / final-stretch / migrated UI | | [Raptor](https://www.solanatracker.io/raptor) | Buy/sell routing on curve + AMM | | [Yellowstone gRPC](https://www.solanatracker.io/yellowstone-grpc) | Raw program tx/account streams | | [Solana RPC](https://www.solanatracker.io/solana-rpc) | `getTransaction` / `getProgramAccounts` against these program IDs | Docs: * [Pump.fun & bonding curves](/guides/pumpfun) — lifecycle with Data API + Datastream * [gRPC buy/sell detection](/yellowstone-grpc/examples/pumpfun-transactions) — decode with the IDL * [gRPC account streaming](/yellowstone-grpc/examples/pumpfun-accounts) — bonding curve state * [Pump.fun AMM program](/guides/pumpfun-amm) — PumpSwap `buy` / `sell` PumpSwap program ID, IDL, and buy/sell discriminators. Discover, track curves, graduations, and swap via Solana Tracker. Real-time instruction parsing over gRPC. Execute Pump.fun and PumpSwap swaps without building IXs. # Find Solana tokens by community activity Source: https://docs.solanatracker.io/guides/search-coin-communities Filter Solana tokens by Coin Communities message counts, combine activity with liquidity filters, and sort search results by communityMessages. The token search API includes Coin Communities message counts. Use them to filter tokens with observed chat activity or sort a watchlist by message count. ## Response fields Search results include the following community fields: | Field | Type | Description | | - | - | - | | `hasCoinCommunity` | `boolean` | `true` when `communityMessages > 0` | | `communityMessages` | `integer` | Live message count from Coin Communities | ```json theme={null} { "mint": "7sGdNQSvUGpahh6qyXB3g5gsdK9FAzZM299KyCXspump", "hasCoinCommunity": true, "communityMessages": 12 } ``` Counts reflect messages observed since monitoring started for that token. Tokens with no monitored activity return `hasCoinCommunity: false` and `communityMessages: 0`. ## Filters Combine these optional parameters with the other `/search` filters. | Parameter | Type | Example | Description | | - | - | - | - | | `hasCoinCommunity` | boolean | `true` | Only tokens with at least one monitored community message | | `hasCoinCommunity` | boolean | `false` | Tokens with zero monitored community messages | | `minCommunityMessages` | integer | `5` | Minimum live message count (inclusive) | | `maxCommunityMessages` | integer | `100` | Maximum live message count (inclusive) | Use `minCommunityMessages` and `maxCommunityMessages` together for a range filter. ## Sorting Set `sortBy=communityMessages` and choose `sortOrder`: ```bash theme={null} curl "https://data.solanatracker.io/search?sortBy=communityMessages&sortOrder=desc&hasCoinCommunity=true" \ -H "x-api-key: YOUR_API_KEY" ``` ## Examples **Tokens with any community activity, sorted by most messages:** ```bash theme={null} curl "https://data.solanatracker.io/search?hasCoinCommunity=true&sortBy=communityMessages&sortOrder=desc&limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` **Tokens with at least 10 community messages and min \$20k liquidity:** ```bash theme={null} curl "https://data.solanatracker.io/search?hasCoinCommunity=true&minCommunityMessages=10&minLiquidity=20000" \ -H "x-api-key: YOUR_API_KEY" ``` **Active pump.fun tokens with community chat:** ```bash theme={null} curl "https://data.solanatracker.io/search?market=pumpfun&hasCoinCommunity=true&sortBy=communityMessages&sortOrder=desc" \ -H "x-api-key: YOUR_API_KEY" ``` Full parameter reference for `/search`. Valid `market` and `launchpad` values for search. # Solana token search: market and launchpad filters Source: https://docs.solanatracker.io/guides/search-filter-options Choose market and launchpad filters for Solana token search. Find supported values and examples for Pump.fun, Raydium, Meteora, and other venues. Use `market` to filter where a token trades and `launchpad` to filter where it launched. These are separate fields: a token can launch on one platform and trade on another. ## `market` vs `launchpad` Both filters narrow a search to a specific platform, but they target different concepts: * **`market`** — the DEX or AMM where the token's pool currently lives (where it trades). Use this when you want, for example, every token currently trading on `raydium-clmm` or `meteora-dyn-v2`. Use a value from the market list below. * **`launchpad`** — the platform that originally launched the token (Pump.fun, Bonk.fun, Jupiter Studio, Bags, and hundreds more). Use this when you want every token that was minted through a specific launchpad, regardless of where it trades today. A token can move from `pumpfun` to `pumpfun-amm` after graduation while retaining its launchpad. Pass both filters to find tokens from a launchpad trading on a specific market. Launchpad values are matched exactly as written below — note that some include spaces (e.g. `jupiter studio`) rather than hyphens. ## Filter a search Use `--data-urlencode` so values with spaces are sent correctly: ```bash theme={null} curl --get "https://data.solanatracker.io/search" \ --header "x-api-key: YOUR_API_KEY" \ --data-urlencode "market=pumpfun-amm" \ --data-urlencode "launchpad=pumpfun" \ --data-urlencode "limit=20" ``` See [token discovery](/guides/token-discovery) for liquidity, volume, and age filters. ## Markets | # | Market | | - | - | | 1 | `bisonfi` | | 2 | `boop` | | 3 | `heaven` | | 4 | `humidifi` | | 5 | `meteora-curve` | | 6 | `meteora-dlmm` | | 7 | `meteora-dyn` | | 8 | `meteora-dyn-v2` | | 9 | `moonshot` | | 10 | `orca` | | 11 | `pumpfun` | | 12 | `pumpfun-amm` | | 13 | `raydium` | | 14 | `raydium-clmm` | | 15 | `raydium-cpmm` | | 16 | `raydium-launchpad` | | 17 | `solfi-v1` | | 18 | `solfi-v2` | | 19 | `tessera` | ## Launchpads | # | Launchpad | | - | - | | 1 | @cointhispost | | 2 | 10k | | 3 | 1edge | | 4 | 1king.meme | | 5 | 21shares | | 6 | 2d.fun | | 7 | 333.fun | | 8 | 3flabs | | 9 | 4chad.xyz | | 10 | a | | 11 | access | | 12 | access intelligence | | 13 | access protocol | | 14 | addressable | | 15 | aes | | 16 | agent one | | 17 | agents land | | 18 | agents.land | | 19 | agentscore | | 20 | akrux.fun | | 21 | akuma | | 22 | alicewins.fun | | 23 | allfees | | 24 | alt fun | | 25 | america | | 26 | america dot fun | | 27 | america dot fun test | | 28 | america fun | | 29 | america fun | | 30 | america launchpad | | 31 | america.fun | | 32 | americadotfun | | 33 | americausa | | 34 | animal fun | | 35 | anoncoin | | 36 | anti.fun | | 37 | antifun | | 38 | antifun.fun | | 39 | aolcoin.fun | | 40 | ape good | | 41 | ape so good | | 42 | apefuel | | 43 | aquarium.fun | | 44 | arcterminal.ai | | 45 | asdf launch | | 46 | ass.cool | | 47 | aureobitcoin | | 48 | avatar | | 49 | axon launch | | 50 | bags | | 51 | bankmefun | | 52 | bankr | | 53 | bantr.fun | | 54 | base | | 55 | basedfarms | | 56 | basefun.org | | 57 | bastion finance agents | | 58 | bayc vault - ca | | 59 | beezie | | 60 | believe | | 61 | best | | 62 | betless.fun | | 63 | bett | | 64 | binder protocol | | 65 | bion | | 66 | birbpad | | 67 | bl4nk | | 68 | bltestdev | | 69 | bltestdev1 | | 70 | bluefun | | 71 | bluup | | 72 | bluup.fun | | 73 | bonk 2.0 | | 74 | bonk.fun | | 75 | bonk2.fun | | 76 | bonkfun | | 77 | bonkfun 2.0 | | 78 | bonkos | | 79 | boomp.fun | | 80 | boomz | | 81 | boop.fun | | 82 | bora | | 83 | bruvlauncher | | 84 | bscscan.com | | 85 | bubblegum | | 86 | ca - milady | | 87 | caesar data | | 88 | candle | | 89 | candle exclusive | | 90 | candle v2 | | 91 | cash city | | 92 | centrifuge | | 93 | cerbagent.xyz | | 94 | cerberus | | 95 | ceshi | | 96 | chad.fo | | 97 | charity.fun | | 98 | cheftx | | 99 | cherry.fun | | 100 | chosen.fun | | 101 | claim | | 102 | clawd.bot | | 103 | clawdlaunch | | 104 | clawnk | | 105 | clawpad | | 106 | clawsend | | 107 | clawtto | | 108 | clawtto.fun | | 109 | click to launch | | 110 | clikr | | 111 | clipzzz.fun | | 112 | clod.fun | | 113 | cnfigjn | | 114 | coinbarrel | | 115 | coinbase launch | | 116 | coindat | | 117 | collaterize | | 118 | compute finance | | 119 | contractaddress | | 120 | contrib.fun | | 121 | control | | 122 | control.deploy | | 123 | cook.meme | | 124 | cooker cooking | | 125 | cooking.city | | 126 | corpus | | 127 | cortex | | 128 | cracked.fun | | 129 | craftr.fun | | 130 | create with pact | | 131 | creator.fun | | 132 | creatorfi | | 133 | crxcible | | 134 | crypto fantasy league | | 135 | cta.fun | | 136 | ctafun | | 137 | ctrl | | 138 | cults | | 139 | danfodog | | 140 | daoszn.fun | | 141 | dare | | 142 | dare maket | | 143 | dare market | | 144 | deez | | 145 | degencubator | | 146 | degenin | | 147 | degensafe | | 148 | degensafe v2 | | 149 | degensafe.fun | | 150 | deployr | | 151 | dextoro | | 152 | dicot | | 153 | distribute | | 154 | dlab | | 155 | dm.fum | | 156 | dm.fun | | 157 | dmdotfun | | 158 | dndtt | | 159 | do | | 160 | do1 | | 161 | dog.fun | | 162 | dogelon mars | | 163 | dolion agents | | 164 | doma.xyz | | 165 | doomsday.fun | | 166 | doppler | | 167 | doppler protocol | | 168 | doppler single curve | | 169 | doppler.lol | | 170 | dotfunlabs | | 171 | downbad.xyz | | 172 | drafted.fun | | 173 | dreamnet | | 174 | dripster | | 175 | duck.fun | | 176 | dumbmoney.win | | 177 | escape hub | | 178 | etoro | | 179 | every.meme | | 180 | evolute.fun | | 181 | evolvpad | | 182 | example | | 183 | exit liq | | 184 | expand.network | | 185 | fartlaunch.com | | 186 | fee.fun | | 187 | fees.fun | | 188 | fifadotfun | | 189 | fifawc.fun | | 190 | figuremarkets | | 191 | finz | | 192 | flap.sol | | 193 | flipcash | | 194 | flipn | | 195 | followfour.fun | | 196 | fomo.family | | 197 | fomo.fun | | 198 | forge | | 199 | forge swap | | 200 | forgepad | | 201 | forgepad.fun | | 202 | fountaindigital | | 203 | four | | 204 | four.meme | | 205 | fourtune ai | | 206 | fuck soo good | | 207 | fundl | | 208 | fuzz.land | | 209 | gamba mamba | | 210 | gatenox | | 211 | gays | | 212 | gaysfun | | 213 | gemhunt.fun | | 214 | genesis | | 215 | genesis pad | | 216 | genesyum | | 217 | geng | | 218 | geng one launchpad | | 219 | getgoated | | 220 | getgoated.xyz | | 221 | geys | | 222 | ghostpool | | 223 | git fish | | 224 | gmgn.lol | | 225 | goal | | 226 | goal26.fun | | 227 | google | | 228 | gormeme.fun | | 229 | greaseburger | | 230 | guess.meme | | 231 | gun.fun | | 232 | guru.fun | | 233 | hack.fun | | 234 | heaven | | 235 | hehe | | 236 | heisted.fun | | 237 | help.fun | | 238 | helpdotfun | | 239 | helptheworld | | 240 | here. | | 241 | here.fun | | 242 | hey anon | | 243 | heyanon | | 244 | heyanon.ai | | 245 | heyoplanet | | 246 | hot | | 247 | hotfunsaga | | 248 | http | | 249 | http.fun | | 250 | [https://ore402.fun](https://ore402.fun) | | 251 | iamstar | | 252 | ibuy.fun | | 253 | ignore | | 254 | inc.fun | | 255 | incinerator | | 256 | its4dot | | 257 | jailed.fun | | 258 | janusdefi | | 259 | jitojio | | 260 | jtx | | 261 | jupiter studio | | 262 | justdoit | | 263 | justmemes | | 264 | kalshi | | 265 | kast.xyz | | 266 | kenny | | 267 | kinesis | | 268 | klout | | 269 | kotofi | | 270 | kotofi.fun | | 271 | krazy | | 272 | krux | | 273 | kukapay | | 274 | landlock | | 275 | launch on dextoro | | 276 | launch on soar | | 277 | launch on usd1 | | 278 | launch with gold | | 279 | launch.lol | | 280 | launch/contra | | 281 | launchai.fun | | 282 | launchcontrol.fun | | 283 | launcher | | 284 | launchiab | | 285 | launching soon | | 286 | launchly | | 287 | launchonnusd1 | | 288 | launchonsoar | | 289 | launchonusd1 | | 290 | launchpad | | 291 | launchusd1 | | 292 | layerbrett | | 293 | lefi | | 294 | leftcurvedotai | | 295 | lessful | | 296 | lets launch | | 297 | lets send it | | 298 | letsbonk | | 299 | letsbonk.fun | | 300 | letsboom.fun | | 301 | letsburn.fun | | 302 | letsfomo.fun | | 303 | letsjulia.fun | | 304 | letsmolt.fun | | 305 | lift | | 306 | liftoff | | 307 | ligma | | 308 | link3dotfun | | 309 | liport.fun | | 310 | liquid | | 311 | liz | | 312 | liz.fun | | 313 | liz.fun/ | | 314 | lizfun | | 315 | localpay | | 316 | loldotfun | | 317 | lookhu watch launchpad | | 318 | loop | | 319 | love a coin | | 320 | lp | | 321 | lulubit | | 322 | luma | | 323 | lumen.layer | | 324 | lumenlayer | | 325 | lumos | | 326 | makenow\.meme | | 327 | makenow\.meme test | | 328 | makewave.fun | | 329 | mava | | 330 | megarun | | 331 | meleemarkets | | 332 | memecoin bubble | | 333 | memecoin factory | | 334 | memecoin supercycle | | 335 | memefast | | 336 | memefast launchpad | | 337 | memefi | | 338 | memepad | | 339 | memerush | | 340 | memoo ai-d | | 341 | memoo.fun | | 342 | merp.fun | | 343 | metaplex | | 344 | metaplex genesis | | 345 | metawin.com | | 346 | meteora-curve | | 347 | mew launchpad | | 348 | mewniverse | | 349 | milady vault - ca | | 350 | mim | | 351 | minchia | | 352 | mini.fun | | 353 | mintcraft | | 354 | mintjob | | 355 | mintjobs | | 356 | mintjobs.fun | | 357 | mintjobsdotfun | | 358 | mintsy.fun | | 359 | moltexe.fun | | 360 | moonbirds | | 361 | moonit | | 362 | moonpad | | 363 | moonpaws | | 364 | moonrush | | 365 | moonsend.fun | | 366 | moonshot | | 367 | moonstar | | 368 | morals.fun | | 369 | motocard | | 370 | mss protocol | | 371 | mt newlauncher | | 372 | multiplier | | 373 | multiplier.fun | | 374 | my launchlab | | 375 | my new ray plat | | 376 | mydefi platform | | 377 | mynt.fun | | 378 | myplatform | | 379 | mytakes.fun | | 380 | mytakesfun | | 381 | mythe | | 382 | mythe.fun | | 383 | nakamigos vault - ca | | 384 | name | | 385 | namedao.app | | 386 | nasdaq.fun | | 387 | nautilus | | 388 | need a runner | | 389 | neptun.fun | | 390 | neu | | 391 | neuko.ai | | 392 | neura | | 393 | neurix.sh | | 394 | new launchlab | | 395 | newtest | | 396 | nibble.fun | | 397 | nigaga.fun | | 398 | niggalaunch | | 399 | nina | | 400 | ninja launchpad | | 401 | nofees | | 402 | normie | | 403 | not a ninja launchpad | | 404 | nyc | | 405 | nyc token | | 406 | oh fuck | | 407 | oh fuck testing | | 408 | ohfuck | | 409 | ohfuck.fun | | 410 | oksend | | 411 | oksend.fun | | 412 | okxsol | | 413 | oldtownbot | | 414 | onememe | | 415 | onepad | | 416 | only.meme | | 417 | onlyhonk | | 418 | onlyone | | 419 | onyx | | 420 | opad | | 421 | orangefin | | 422 | orbyt | | 423 | orbyt.fun | | 424 | oshi no ko | | 425 | otcm.io | | 426 | ouroboros | | 427 | pandoradotgame | | 428 | pantheon | | 429 | parabolic | | 430 | parle.id | | 431 | pawn | | 432 | pawn.bet | | 433 | pawsfund | | 434 | peek fun | | 435 | pepememe.fun | | 436 | perpolator | | 437 | phantom studio | | 438 | pick.trade | | 439 | pickle | | 440 | pigeonhouse | | 441 | pigeonhouse.fun | | 442 | pinata.fun | | 443 | piratehood | | 444 | platform | | 445 | platform.wise.art | | 446 | play.fun | | 447 | play.pixels.xyz | | 448 | pledgepad | | 449 | pnl.fun | | 450 | pokã¨mon.fun | | 451 | pokemon.fun | | 452 | polypad.fun | | 453 | ponzi | | 454 | ponzi pad | | 455 | poochain ecosystem | | 456 | popscandle | | 457 | possumlabs | | 458 | predictit.markets | | 459 | prehigh | | 460 | printr | | 461 | printr.money | | 462 | projectsolo | | 463 | projectsolo.xyz | | 464 | ptoken | | 465 | pump | | 466 | pump fun robinhood | | 467 | pump.fun | | 468 | pumpchange.fun | | 469 | pumpfun | | 470 | pumphub | | 471 | pumpkin.fun | | 472 | pumpmeme | | 473 | pumptracks | | 474 | pussy | | 475 | pussy cat | | 476 | pve.win | | 477 | queen sherex | | 478 | quest | | 479 | quote mint test | | 480 | quvex.xyz | | 481 | racer.fun | | 482 | rayball | | 483 | rayball.xyz | | 484 | raydium | | 485 | raydium eco | | 486 | raydium-launchpad | | 487 | raydiumeco | | 488 | rayfi | | 489 | raypad | | 490 | reape.fun | | 491 | red hope crew | | 492 | reely.one | | 493 | refi hub | | 494 | remittix.io | | 495 | revolutionpad | | 496 | revshare | | 497 | rewards.fun | | 498 | rewards.sol | | 499 | right | | 500 | right fun | | 501 | right.fun | | 502 | rise | | 503 | rise.rich | | 504 | riser.fun | | 505 | rizz platform | | 506 | robolaunch | | 507 | robotxpress | | 508 | rockawayx | | 509 | rocketverse | | 510 | rooms | | 511 | rug registry | | 512 | rugged registry | | 513 | rugs.fun | | 514 | rule34.meme | | 515 | rush.fun | | 516 | sadcat | | 517 | sampump | | 518 | sapien.gg | | 519 | sato | | 520 | say.fun | | 521 | say.fun launchpad | | 522 | scratcher.fun | | 523 | scrypt.swiss | | 524 | sea.codes | | 525 | send | | 526 | send.fun | | 527 | sendor.gg | | 528 | separated authority platform | | 529 | seyra launchpad | | 530 | sharps technology | | 531 | sherexfun | | 532 | shitpad | | 533 | shoot.fun | | 534 | shweep.fun | | 535 | shyft | | 536 | shyp | | 537 | signed | | 538 | skr.fun | | 539 | smoothie | | 540 | smoothie.fun | | 541 | snake solana | | 542 | snicky | | 543 | sns | | 544 | soar | | 545 | sol furnace | | 546 | sol-incinerator | | 547 | sol.incinerator | | 548 | solace | | 549 | solana the hippo | | 550 | solananinjaheros | | 551 | solclaw\.ai | | 552 | soldegen | | 553 | solforge launchpad | | 554 | sollaunch | | 555 | solnav | | 556 | solplayden | | 557 | solstice | | 558 | sorted wallet | | 559 | spinz.cash | | 560 | splyce finance | | 561 | spots | | 562 | spots | | 563 | spots.fun | | 564 | src.fun | | 565 | ssi | | 566 | ssi fun | | 567 | ssi.fun | | 568 | stake | | 569 | stake.com | | 570 | stalkfun agent program | | 571 | star | | 572 | star.fun | | 573 | stealf | | 574 | storex | | 575 | streamer | | 576 | streamtok | | 577 | sug.dev | | 578 | sugar.money | | 579 | summon | | 580 | summon.fun | | 581 | sunrise | | 582 | sunrise agents | | 583 | sunrisedefi.com | | 584 | surge | | 585 | surge gated | | 586 | surge ignition | | 587 | surge.xyz | | 588 | sushi | | 589 | swap.cow\.fi | | 590 | swap.fail | | 591 | swarmbet | | 592 | swarmpad.xyz | | 593 | t | | 594 | taichi | | 595 | takes.fun | | 596 | tako | | 597 | talonos | | 598 | tap | | 599 | tap.fun | | 600 | tardfi | | 601 | taxsplit | | 602 | teaeat1 launch | | 603 | tectonic | | 604 | tendr.bid | | 605 | tenge | | 606 | terminusbet | | 607 | test | | 608 | test launchpad | | 609 | test plat | | 610 | test platform | | 611 | test1 | | 612 | testagain | | 613 | testlaunch | | 614 | testpad | | 615 | testplatform | | 616 | thedungeon.wtf | | 617 | theros | | 618 | thiq.fun | | 619 | tigerbro | | 620 | tiptap | | 621 | tit | | 622 | tokenbois | | 623 | tokenize your car | | 624 | tokenize your pet | | 625 | tokenized fart | | 626 | tokens.xyz | | 627 | tokensð¯us | | 628 | trade vala | | 629 | tread.fi | | 630 | tren.ch | | 631 | trends.fun | | 632 | trepa.io | | 633 | trix | | 634 | trix.meme | | 635 | trumpmemes | | 636 | trustfun | | 637 | truth | | 638 | truth predict | | 639 | try modl | | 640 | tst | | 641 | tt | | 642 | turc.fun | | 643 | tvt fun | | 644 | twst | | 645 | ugit | | 646 | ultimate flypad | | 647 | ultimate flywheel | | 648 | ultra-cheap launch platform | | 649 | usa fun | | 650 | usd1 fun | | 651 | usd1 pad | | 652 | usd1bond | | 653 | usd1fly | | 654 | usd1fun | | 655 | usd1pad | | 656 | usd1pad.fun | | 657 | usdc.fun | | 658 | uxento.io | | 659 | v4mp.fun | | 660 | vala | | 661 | valhalla | | 662 | vanish | | 663 | vanish.trade | | 664 | vantixa | | 665 | vantixa test | | 666 | vayen.app | | 667 | vector | | 668 | vega.fun | | 669 | vestor.fun | | 670 | veta.finance | | 671 | vibe | | 672 | vibe launch | | 673 | vibelabs | | 674 | vimix | | 675 | voidex launchlab | | 676 | wallstreetpepe | | 677 | wallstreetpepe.com | | 678 | wally launchpad | | 679 | waveit | | 680 | wavetrade.fun | | 681 | wavz.fun | | 682 | wayy.art | | 683 | wdtp | | 684 | wejump | | 685 | wejustape | | 686 | wen.dev | | 687 | wendotdev | | 688 | wetodd.it | | 689 | whale.io | | 690 | why buy | | 691 | whybuy.fun | | 692 | win only | | 693 | withparallax | | 694 | wlfi | | 695 | wlfi rewards | | 696 | womp womp | | 697 | world cup | | 698 | world liberty financial | | 699 | worldcupdotfun | | 700 | worldlibertyfi | | 701 | wow | | 702 | wrld | | 703 | wtfo | | 704 | x | | 705 | x402fun | | 706 | xcashdotfun | | 707 | xd.fun | | 708 | xfractal | | 709 | xfractal.fun | | 710 | xitadel | | 711 | xp | | 712 | yeezy money | | 713 | your platform name | | 714 | your.fun | | 715 | yourdotfun | | 716 | youtube | | 717 | yutocoin.fun | | 718 | yutocoin.online | | 719 | yutopad | | 720 | zapzy | | 721 | zcoin | | 722 | zer0 | | 723 | zerg.app | | 724 | zkagi.ai | | 725 | zods run | | 726 | zqlc-platform | | 727 | 中国发射台 | # Find early token buyers, snipers, and bundlers Source: https://docs.solanatracker.io/guides/sniper-detection Find early Solana token buyers, inspect their positions and PnL, and query bundler, sniper, and insider activity with Solana Tracker APIs. Use first-buyer data to inspect launch activity and the bundler endpoint to check related wallet holdings. Timing and wallet labels help narrow a review; they do not establish a trader's intent. ## First buyers The [first-buyers endpoint](/data-api/pnl-v2/token/get-token-first-buyers) returns buyers in chronological order, with positions, PnL, and available identity labels. ```bash cURL theme={null} curl "https://data.solanatracker.io/v2/pnl/tokens/{token}/first-buyers?limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/first-buyers?limit=50`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); traders.forEach((t, i) => { console.log(`#${i + 1} ${t.wallet} — first trade ${new Date(t.timing.firstTrade).toISOString()}`); console.log(`Token PnL: $${t.pnl.token.total.toFixed(2)}, balance: ${t.position.balance}`); }); ``` ## Find snipers who already sold Compare current balance with realized PnL to find first buyers who have already closed a position. ```javascript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/first-buyers?limit=50`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const { traders } = await res.json(); // Find snipers who already sold const sold = traders.filter(t => t.position.balance === 0 && t.pnl.token.realized > 0); console.log(`${sold.length} early buyers already sold at a profit`); sold.forEach(t => { const holdMins = (t.timing.lastTrade - t.timing.firstTrade) / 60000; console.log(` ${t.wallet}: +$${t.pnl.token.realized.toFixed(2)}, held ${holdMins.toFixed(0)} minutes`); }); ``` ### What to look for | Signal | What it means | | - | - | | Balance = 0, profit > 0 | No remaining balance and positive realized PnL | | Hold time \< 5 minutes | Short holding period; review the trades and wallet labels | | Multiple first-buyer appearances | Same wallet sniping many launches | | Large buy size relative to pool | Whale entry that moved the price | ## Bundler detection The [bundlers endpoint](/data-api/tokens/get-token-bundlers) identifies wallets involved in bundled transactions on a token. ```bash theme={null} curl "https://data.solanatracker.io/tokens/{token}/bundlers" \ -H "x-api-key: YOUR_API_KEY" ``` Bundle labels describe detected transaction activity. Inspect the associated balances and trades before interpreting that activity. * Launch sniping (buy in the same block as liquidity add) * Sandwich attacks * Coordinated wallet clusters ## Chart-based detection Use the chart endpoints to compare how detected wallet groups changed their holdings over time. ### Sniper activity chart The [snipers chart](/data-api/chart/get-snipers-chart-data) shows sniper activity over time for a token. ```bash theme={null} curl "https://data.solanatracker.io/snipers/chart/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` ### Bundler activity chart The [bundlers chart](/data-api/chart/get-bundlers-chart-data) tracks bundled transaction activity over time. ```bash theme={null} curl "https://data.solanatracker.io/bundlers/chart/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` ### Insider activity chart The [insiders chart](/data-api/chart/get-insiders-chart-data) shows insider wallet activity patterns. ```bash theme={null} curl "https://data.solanatracker.io/insiders/chart/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` ## Example: full sniper report Build a quick sniper report for any token: ```javascript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const headers = { "x-api-key": "YOUR_API_KEY" }; // 1. Get first buyers with PnL data const { traders } = await fetch( `https://data.solanatracker.io/v2/pnl/tokens/${token}/first-buyers?limit=50`, { headers } ).then(r => r.json()); // 2. Get bundler data const bundlers = await fetch( `https://data.solanatracker.io/tokens/${token}/bundlers`, { headers } ).then(r => r.json()); // 3. Analyze const snipers = traders.filter(t => { const holdMins = (t.timing.lastTrade - t.timing.firstTrade) / 60000; return holdMins < 10 && t.pnl.token.realized > 0; }); const bundlerWallets = new Set(bundlers.wallets.map(b => b.wallet)); const sniperBundlers = snipers.filter(s => bundlerWallets.has(s.wallet)); console.log(`First 50 buyers: ${traders.length}`); console.log(`Quick-flip snipers (< 10 min hold, profitable): ${snipers.length}`); console.log(`Bundler wallets: ${bundlers.wallets.length}`); console.log(`Snipers who also bundled: ${sniperBundlers.length}`); ``` Full token lookup: stats, holders, trades, and events. All traders on a token with PnL, sorting, and filtering. Track snipers, bundlers, and insiders in real time via WebSocket. Spot new tokens before the crowd and filter by graduation status. # Find Solana address lookup tables with RPC Source: https://docs.solanatracker.io/guides/solana-rpc-lookup-tables Find Solana address lookup tables by authority, account, or mint. Select tables for a transaction and inspect account coverage and estimated savings. Address lookup tables let a Solana transaction reference accounts by table index. Use the Ridge RPC methods to find tables containing your transaction's accounts and select a set before building the message. * LUTs owned by a wallet authority. * LUTs that contain one account or token mint. * LUTs that contain every account in a set. * A best-effort LUT set for reducing transaction size. Each Lookup Table RPC method costs **1 credit** per call. ## When to use these methods Use these methods before building a versioned transaction, or to inspect where an account appears in existing tables. | Goal | Method | | - | - | | Inspect LUTs controlled by a wallet | [`getLookupTablesByAuthority`](/solana-rpc/http/getlookuptablesbyauthority) | | Find LUTs that contain an account | [`getLookupTablesByAccount`](/solana-rpc/http/getlookuptablesbyaccount) | | Find LUTs that contain a token mint | [`getLookupTablesByMint`](/solana-rpc/http/getlookuptablesbymint) | | Find LUTs that cover multiple accounts | [`getLookupTablesByAccounts`](/solana-rpc/http/getlookuptablesbyaccounts) | Start with `getLookupTablesByAccounts` when your goal is transaction optimization. Use the single-account methods when you are exploring where a specific account or mint appears. ## RPC endpoint All examples use JSON-RPC 2.0 over HTTP: ```bash theme={null} https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY ``` ## Find luts by authority Query `getLookupTablesByAuthority` for tables controlled by a wallet authority. ```bash cURL theme={null} curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "getLookupTablesByAuthority", "params": [{ "authority": "WalletPubkey...", "limit": 100, "cursor": null, "mintsOnly": false, "includeDeactivated": false }] }' ``` ```javascript JavaScript theme={null} const rpcUrl = "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY"; const res = await fetch(rpcUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getLookupTablesByAuthority", params: [{ authority: "WalletPubkey...", limit: 100, cursor: null, mintsOnly: false, includeDeactivated: false }] }) }); const { result } = await res.json(); for (const lut of result.lookupTables) { console.log(`${lut.pubkey}: ${lut.addressCount} addresses`); } ``` The response is paginated: ```json theme={null} { "lookupTables": [ { "pubkey": "LUTPubkey...", "authority": "WalletPubkey...", "deactivationSlot": 18446744073709551615, "addressCount": 12, "addresses": ["Account1...", "Account2..."], "mints": ["Mint1..."], "slot": 423867852 } ], "nextCursor": "LUTPubkey...", "hasMore": false, "count": 1 } ``` `deactivationSlot` uses `18446744073709551615` to represent an active LUT. ## Find luts containing one account Use `getLookupTablesByAccount` when you already know an account that will appear in a transaction and want to find LUTs that contain it. ```bash theme={null} curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "getLookupTablesByAccount", "params": [{ "account": "SomeAccountPubkey...", "owner": null, "limit": 100, "cursor": null }] }' ``` Matched results include transaction-optimization metadata: | Field | Meaning | | - | - | | `addressIndex` | Position of the matched account in the LUT | | `matchedAccounts` | Accounts from your query found in this LUT | | `matchedAddressIndices` | LUT indexes for the matched accounts | | `estimatedBytesSaved` | Approximate bytes saved by referencing matched accounts through the LUT | ## Find luts containing a mint `getLookupTablesByMint` is the same lookup pattern as `getLookupTablesByAccount`, but the parameter name is `mint`. ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getLookupTablesByMint", "params": [{ "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "limit": 100 }] } ``` Use this when a transaction is token-centric and you want to discover LUTs that already contain the mint address. ## Find luts for a full account set `getLookupTablesByAccounts` has two modes: intersection mode and best-set mode. ### Intersection mode Intersection mode returns LUTs that contain **every** account you provide. Use it when you need one table that covers the full set. ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getLookupTablesByAccounts", "params": [{ "accounts": ["AccountA...", "AccountB..."], "owner": null, "limit": 100, "cursor": null }] } ``` ### Best-set mode Best-set mode selects tables to cover the supplied accounts and reduce the transaction message size. Set `bestSet: true` and pass the full account list your transaction needs: ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getLookupTablesByAccounts", "params": [{ "accounts": ["AccountA...", "AccountB...", "AccountC..."], "bestSet": true, "maxLookupTables": 8, "candidateLimit": 5000, "perAccountLimit": 500 }] } ``` The response tells you what the selected LUTs cover: ```json theme={null} { "lookupTables": [ { "pubkey": "LUT1...", "matchedAccounts": ["AccountA...", "AccountB..."], "matchedAddressIndices": [3, 17], "estimatedBytesSaved": 62 } ], "coveredAccounts": ["AccountA...", "AccountB..."], "uncoveredAccounts": ["AccountC..."], "estimatedBytesSaved": 62, "count": 1 } ``` ### Best-set tuning | Parameter | Default | Use it when | | - | - | - | | `maxLookupTables` | `8` | You want to cap how many LUTs your transaction uses | | `candidateLimit` | `5000` | You need to limit total candidate tables considered | | `perAccountLimit` | `500` | One account appears in too many LUTs and candidate search is too broad | Start with the defaults. Tune only after measuring the returned coverage, estimated savings, and request time. ## Example: choose luts before building a transaction The typical flow is: 1. Collect the accounts your transaction will reference. 2. Call `getLookupTablesByAccounts` with `bestSet: true`. 3. Attach returned LUTs to your transaction builder. 4. Keep `uncoveredAccounts` as normal account keys. ```javascript theme={null} const accounts = [ "AccountA...", "AccountB...", "AccountC..." ]; const { result } = await fetch( "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getLookupTablesByAccounts", params: [{ accounts, bestSet: true, maxLookupTables: 8 }] }) } ).then(r => r.json()); console.log("Use LUTs:", result.lookupTables.map(lut => lut.pubkey)); console.log("Covered:", result.coveredAccounts); console.log("Still inline:", result.uncoveredAccounts); console.log("Estimated bytes saved:", result.estimatedBytesSaved); ``` ## Practical tips * Use `bestSet: true` for transaction-size optimization, not for exhaustive discovery. * Use `owner` when you only trust or care about LUTs controlled by a specific authority. * Use `mintsOnly` on authority lookups when you are building token-oriented UX and do not need every stored address. * Treat `estimatedBytesSaved` as a planning signal, then still simulate the final transaction. * Keep pagination logic for authority, account, and mint searches. Popular accounts can appear in many LUTs. Find LUTs for multiple accounts or get a best-fit LUT set. Review credit costs and plan limits for RPC calls. # Resolve Solana .sol domains with SNS RPC methods Source: https://docs.solanatracker.io/guides/solana-rpc-sns-domains Resolve primary .sol domains, look up wallet names in batches, list owned domains, and find domain owners with Solana Tracker RPC. Use the SNS RPC methods to turn wallet addresses into `.sol` display names or resolve a domain to its owner. Batch primary-domain lookups when rendering a holder list or leaderboard. Each SNS RPC method costs **1 credit** per call. Twitter/X handles (`.twitter`) are not supported. | Goal | Method | | - | - | | Get one wallet's primary `.sol` domain | [`getPrimaryDomain`](/solana-rpc/http/getprimarydomain) | | Resolve primary domains for many wallets | [`getMultiplePrimaryDomains`](/solana-rpc/http/getmultipleprimarydomains) | | List all `.sol` domains owned by a wallet | [`getAllDomains`](/solana-rpc/http/getalldomains) | | Resolve `name.sol` to an owner wallet | [`resolveSolDomain`](/solana-rpc/http/resolvesoldomain) | ## RPC endpoint All examples use JSON-RPC 2.0 over HTTP: ```bash theme={null} https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY ``` ## Get a wallet's primary domain Use `getPrimaryDomain` for the wallet's primary `.sol` display name. ```bash cURL theme={null} curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "getPrimaryDomain", "params": ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] }' ``` ```javascript JavaScript theme={null} const rpcUrl = "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY"; const { result } = await fetch(rpcUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getPrimaryDomain", params: ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] }) }).then(r => r.json()); const label = result.value.domain ?? result.value.wallet; console.log(label); ``` ```python Python theme={null} import requests res = requests.post( "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY", json={ "jsonrpc": "2.0", "id": 1, "method": "getPrimaryDomain", "params": ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] } ) result = res.json()["result"]["value"] print(result["domain"] or result["wallet"]) ``` When a domain exists: ```json theme={null} { "context": { "slot": 423867852, "apiVersion": "3.0.0" }, "value": { "wallet": "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "domain": "solanatracker.sol" } } ``` When no primary domain exists, `domain` is `null`: ```json theme={null} { "context": { "slot": 423867852, "apiVersion": "3.0.0" }, "value": { "wallet": "FMmaHPDL47V1gXsfh9WjgAT7Er3dfDvarQubTU1Jxc1r", "domain": null } } ``` In UI, use the domain as the label when present, and fall back to a shortened wallet address when `domain` is `null`. ## Batch primary domains Use `getMultiplePrimaryDomains` for a list of wallets: The method accepts up to **100 wallets** and returns results in the same order as the input list. ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getMultiplePrimaryDomains", "params": [ [ "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "FMmaHPDL47V1gXsfh9WjgAT7Er3dfDvarQubTU1Jxc1r" ] ] } ``` Example response: ```json theme={null} { "context": { "slot": 423867852, "apiVersion": "3.0.0" }, "value": { "results": [ { "wallet": "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "domain": "solanatracker.sol" }, { "wallet": "FMmaHPDL47V1gXsfh9WjgAT7Er3dfDvarQubTU1Jxc1r", "domain": null } ] } } ``` Because the response preserves input order, you can merge it back into a wallet list by array index: ```javascript theme={null} const wallets = [ "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "FMmaHPDL47V1gXsfh9WjgAT7Er3dfDvarQubTU1Jxc1r" ]; const { result } = await fetch(rpcUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getMultiplePrimaryDomains", params: [wallets] }) }).then(r => r.json()); const rows = wallets.map((wallet, i) => ({ wallet, displayName: result.value.results[i].domain ?? `${wallet.slice(0, 4)}...${wallet.slice(-4)}` })); ``` ## Get all domains owned by a wallet Use `getAllDomains` to list the `.sol` domains owned by a wallet. ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getAllDomains", "params": ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] } ``` Response: ```json theme={null} { "context": { "slot": 423867852, "apiVersion": "3.0.0" }, "value": { "wallet": "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "domains": ["solanatracker.sol", "othername.sol"] } } ``` If the wallet has no domains, `domains` is an empty array. ## Resolve a domain to an owner Use `resolveSolDomain` to resolve a `.sol` name to its owner wallet. ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "resolveSolDomain", "params": ["solanatracker.sol"] } ``` Response: ```json theme={null} { "context": { "slot": 423867852, "apiVersion": "3.0.0" }, "value": { "domain": "solanatracker.sol", "owner": "9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p", "nameAccount": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" } } ``` If the domain is not found, `value` is `null`. `resolveSolDomain` supports root `.sol` domains like `name.sol` and one-level subdomains like `sub.parent.sol`. ## Example: wallet identity helper This helper uses primary domains for display and keeps the wallet address available for linking, copying, or transaction actions. ```javascript theme={null} function shortWallet(wallet) { return `${wallet.slice(0, 4)}...${wallet.slice(-4)}`; } async function getWalletIdentity(wallet) { const { result } = await fetch( "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getPrimaryDomain", params: [wallet] }) } ).then(r => r.json()); return { wallet, label: result.value.domain ?? shortWallet(wallet), domain: result.value.domain }; } ``` ## Choosing the right SNS method | Situation | Recommendation | | - | - | | Single wallet profile header | `getPrimaryDomain` | | Leaderboard or holder table | `getMultiplePrimaryDomains` | | Domain portfolio page | `getAllDomains` | | Search input accepts `.sol` names | `resolveSolDomain` | | PnL V2 response already includes `identity.sns` | Use the included PnL V2 identity field | PnL V2 already includes SNS identity in supported wallet and token analytics responses. Use these RPC methods when you need SNS resolution directly from the Solana RPC surface. ## UI and product tips * Always keep the wallet address available, even when showing a domain. * Treat `domain: null` as a normal result, not an error. * Use batch resolution for tables and feeds instead of calling `getPrimaryDomain` in a loop. * Show `.sol` names as labels, but copy and link the underlying wallet address. * For user search, resolve `.sol` names first, then continue with the returned owner wallet. Batch primary `.sol` domains for up to 100 wallets. See where SNS identity appears in PnL V2 responses. # Build and send Solana swaps with Raptor Source: https://docs.solanatracker.io/guides/swap-api Swap tokens from a browser wallet with Raptor: quote, build, sign, send and track. Also covers building your own transaction from instructions and streaming ready-to-sign swaps. This guide shows a browser swap flow from start to finish, then two variations: building the transaction yourself, and streaming ready-to-sign swaps. For a server-side script, see the [Raptor quickstart](/raptor/overview#quickstart). **HTTP:** `https://raptor.solanatracker.io` · **WebSocket:** `wss://raptor.solanatracker.io`. No API key needed. ## Swap from a browser wallet The example uses `@solana/web3.js` and any wallet that exposes `signTransaction` (Phantom, Solflare, Wallet Adapter). ```javascript theme={null} import { VersionedTransaction } from "@solana/web3.js"; const RAPTOR = "https://raptor.solanatracker.io"; async function api(path, body) { const res = await fetch(`${RAPTOR}${path}`, body && { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const text = await res.text(); if (!res.ok) throw new Error(`${res.status}: ${text}`); return JSON.parse(text); } export async function swap(wallet, inputMint, outputMint, amount) { // 1. Quote const quote = await api(`/quote?${new URLSearchParams({ inputMint, outputMint, amount, slippageBps: "50", })}`); // 2. Build. Send the quote back unchanged, within a few seconds. const { swapTransaction } = await api("/swap", { userPublicKey: wallet.publicKey.toBase58(), quoteResponse: quote, priorityFee: "high", }); // 3. Sign in the wallet const tx = VersionedTransaction.deserialize( Uint8Array.from(atob(swapTransaction), (c) => c.charCodeAt(0)) ); const signed = await wallet.signTransaction(tx); // 4. Send const { signature } = await api("/send-transaction", { transaction: btoa(String.fromCharCode(...signed.serialize())), }); // 5. Wait for the result for (let i = 0; i < 30; i++) { const result = await api(`/transaction/${signature}`); if (result.status !== "pending") return result; // confirmed, failed or expired await new Promise((r) => setTimeout(r, 1000)); } throw new Error("Timed out"); } // 0.1 SOL -> USDC await swap( window.solana, "So11111111111111111111111111111111111111112", "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "100000000" ); ``` ### Show the price before signing If the user should confirm the price first, show the quote fields, then build the transaction once they accept. Fetch a new quote if they wait more than a few seconds. | Field | Show it as | | - | - | | `amountOut` | Expected amount, in the output token's smallest unit. Divide by `10^decimals`. | | `minAmountOut` | Least they'll receive after slippage and your platform fee | | `priceImpact` | Already a percent: `0.25` means 0.25% | | `routePlan[].dex` | DEXes used | ### Common options On `/quote`: | Option | Example | Effect | | - | - | - | | `slippageBps` | `100` or `dynamic` | Maximum price movement, in basis points | | `dexes` | `raydium,meteora` | Only use these DEXes | | `maxHops` | `2` | Shorter routes | | `feeAccount` + `feeBps` | `25` | Take a 0.25% platform fee | On `/swap`: | Option | Example | Effect | | - | - | - | | `priorityFee` | `high` or `"50000"` | Priority level, or a total fee in lamports | | `maxPriorityFee` | `200000` | Cap on compute unit price, in micro-lamports | | `tipAccount` + `tipLamports` | `10000` | Add a SOL tip | | `txVersion` | `LEGACY` | Transaction format (`V0` by default, upper-case) | | `wrapUnwrapSol` | `false` | Turn off automatic SOL wrapping | Raptor creates any token accounts the user is missing and wraps and unwraps SOL inside the transaction. The user pays the rent for new token accounts (about 0.002 SOL each). ## Quote and build in one call When the user doesn't need to review the price, `POST /quote-and-swap` takes the quote parameters and the wallet together and returns both: ```javascript theme={null} const { quote, swapTransaction } = await api("/quote-and-swap", { userPublicKey: wallet.publicKey.toBase58(), inputMint: "So11111111111111111111111111111111111111112", outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", amount: 100000000, slippageBps: "50", priorityFee: "high", }); ``` ## Build your own transaction Use `POST /swap-instructions` to add your own instructions, such as a memo or a transfer, around the swap. It takes the same body as `/swap`. ```javascript theme={null} import { Connection, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; const connection = new Connection("https://rpc-mainnet.solanatracker.io/?api_key=YOUR_KEY"); const ix = await api("/swap-instructions", { userPublicKey: wallet.publicKey.toBase58(), quoteResponse: quote, }); const toIx = (i) => new TransactionInstruction({ programId: new PublicKey(i.programId), keys: i.accounts.map((a) => ({ pubkey: new PublicKey(a.pubkey), isSigner: a.isSigner, isWritable: a.isWritable })), data: Buffer.from(i.data, "base64"), }); const instructions = [ ...ix.computeBudgetInstructions, ...ix.setupInstructions, ix.swapInstruction, ix.cleanupInstruction, ix.tipInstruction, ].filter(Boolean).map(toIx); // Add your own instructions here. If ix.topLevelOnly is true, move the swap to the end. const lookupTables = await Promise.all( ix.addressLookupTableAddresses.map(async (a) => (await connection.getAddressLookupTable(new PublicKey(a))).value) ); const { blockhash } = await connection.getLatestBlockhash(); const tx = new VersionedTransaction(new TransactionMessage({ payerKey: wallet.publicKey, recentBlockhash: blockhash, instructions, }).compileToV0Message(lookupTables)); ``` Sign and send it as in the browser example. Two things to know: * If the response includes `quoteResponse`, the route was rebuilt. Show the user those amounts. * `/swap-instructions` returns an ordinary swap that you can also call from your own program through CPI. If you ask for `jitRouting: true`, the response has `topLevelOnly: true`, and the swap must be the last top-level instruction. See [JIT routing](/raptor/overview#jit-routing). ## Stream ready-to-sign swaps `/stream/swap` sends a new quote and a freshly built transaction whenever the best route changes. When the user clicks Swap, sign the latest transaction and send it. There's no separate build step. ```javascript theme={null} const ws = new WebSocket("wss://raptor.solanatracker.io/stream/swap"); let latest; ws.onopen = () => ws.send(JSON.stringify({ type: "subscribe", inputMint: "So11111111111111111111111111111111111111112", outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", amount: 100000000, userPublicKey: wallet.publicKey.toBase58(), slippageBps: "50", priorityFee: "high", })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "swap") { latest = msg; console.log(`Now: ${msg.quote.amountOut}`); } if (msg.type === "error") console.error(msg.error); }; async function onSwapClick() { const tx = VersionedTransaction.deserialize( Uint8Array.from(atob(latest.swapTransaction), (c) => c.charCodeAt(0)) ); const signed = await wallet.signTransaction(tx); return api("/send-transaction", { transaction: btoa(String.fromCharCode(...signed.serialize())), }); } ``` For prices only, use `/stream` instead. It takes the same subscribe message without `userPublicKey`, and its updates have `type: "quote"` with the quote in `data`. Parameters, JIT routing, errors and supported DEXes. Status values and reading swap results. # Find new and trending Solana tokens Source: https://docs.solanatracker.io/guides/token-discovery Find new Solana tokens, trending pairs, volume leaders, and recent graduations with the Solana Tracker Data API. Use the discovery endpoints to choose a starting set of tokens, then filter by market, liquidity, volume, or launch status. Use search when you already know a name, symbol, or mint. ## Latest tokens The [latest tokens endpoint](/data-api/tokens/get-latest-tokens) returns the most recently created tokens on Solana. ```bash cURL theme={null} curl "https://data.solanatracker.io/tokens/latest" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch("https://data.solanatracker.io/tokens/latest", { headers: { "x-api-key": "YOUR_API_KEY" } }); const tokens = await res.json(); tokens.forEach(t => { console.log(`${t.token.name} (${t.token.symbol})`); console.log(` Pool: ${t.pools[0]?.address}`); console.log(` MC: $${t.pools[0]?.marketCap?.usd?.toLocaleString()}`); }); ``` ```python Python theme={null} import requests res = requests.get("https://data.solanatracker.io/tokens/latest", headers={"x-api-key": "YOUR_API_KEY"}) for t in res.json(): print(f"{t['token']['name']} ({t['token']['symbol']})") ``` ## Trending tokens The [trending tokens endpoint](/data-api/tokens/get-trending-tokens) returns tokens with the most activity right now. ```bash theme={null} curl "https://data.solanatracker.io/tokens/trending" \ -H "x-api-key: YOUR_API_KEY" ``` Filter by timeframe: ```bash theme={null} # Trending in the last hour curl "https://data.solanatracker.io/tokens/trending/1h" \ -H "x-api-key: YOUR_API_KEY" ``` ## Tokens by volume The [volume endpoint](/data-api/tokens/get-tokens-by-volume) ranks tokens by trading volume. ```bash theme={null} # All-time volume leaders curl "https://data.solanatracker.io/tokens/volume" \ -H "x-api-key: YOUR_API_KEY" # Volume in the last 24 hours curl "https://data.solanatracker.io/tokens/volume/24h" \ -H "x-api-key: YOUR_API_KEY" ``` ## Top performers The [top performers endpoint](/data-api/tokens/get-top-performing-tokens) returns the biggest price gainers across different timeframes. ```bash theme={null} # Top gainers in the last hour curl "https://data.solanatracker.io/top-performers/1h" \ -H "x-api-key: YOUR_API_KEY" # Top gainers in the last 24 hours curl "https://data.solanatracker.io/top-performers/24h" \ -H "x-api-key: YOUR_API_KEY" ``` ## Graduating tokens Bonding curve tokens trade on their launch platform before migrating to a DEX pool. Use the graduating and graduated endpoints to separate those stages. ### Currently graduating The [graduating tokens endpoint](/data-api/tokens/get-graduating-tokens) returns tokens that are close to completing their bonding curve. ```bash theme={null} curl "https://data.solanatracker.io/tokens/multi/graduating" \ -H "x-api-key: YOUR_API_KEY" ``` ### Already graduated The [graduated tokens endpoint](/data-api/tokens/get-graduated-tokens) returns tokens that have completed their bonding curve and migrated to a DEX. ```bash theme={null} curl "https://data.solanatracker.io/tokens/multi/graduated" \ -H "x-api-key: YOUR_API_KEY" ``` ## Search The [search endpoint](/data-api/search/token-search) finds tokens by name, symbol, or address. Supports filtering and sorting. ```bash cURL theme={null} # Search by name curl "https://data.solanatracker.io/search?query=bonk" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const res = await fetch( "https://data.solanatracker.io/search?query=bonk", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const results = await res.json(); results.forEach(r => { console.log(`${r.token.name}: $${r.pools[0]?.price?.usd}`); }); ``` ## Tokens by deployer The [deployer endpoint](/data-api/tokens/get-tokens-by-deployer) returns all tokens created by a specific wallet — useful for tracking serial deployers. ```bash theme={null} curl "https://data.solanatracker.io/deployer/{walletAddress}" \ -H "x-api-key: YOUR_API_KEY" ``` ### `deployer` vs `tokenDetails.creator` Each token in the response carries two related but distinct wallet fields: | Field | Meaning | | - | - | | `deployer` (top level) | The wallet that signed and submitted the mint transaction on-chain. This is what the `/deployer/{wallet}` path filters on. | | `tokenDetails.creator` | The creator address recorded in the token's on-chain metadata (set by the launchpad or minting program). | The two fields can differ. Filter by `deployer` to find the wallet that submitted the mint transaction; read `tokenDetails.creator` for the creator recorded in metadata. ## Token overview The [token overview endpoint](/data-api/tokens/get-token-overview) returns grouped token lists for a discovery page. ```bash theme={null} curl "https://data.solanatracker.io/tokens/multi/all" \ -H "x-api-key: YOUR_API_KEY" ``` ## Real-time streams For live token discovery, use the [Datastream WebSocket](/datastream/websockets/latesttokens) channels: | Room | What it streams | | - | - | | `latest` | Newly created tokens as they appear | | `graduating` | Tokens approaching graduation | | `graduated` | Tokens that just graduated | | `token:{token}` | Pool state changes (price, liquidity, mcap) | | `stats:token:{token}` | Multi-timeframe statistics | ## Example: build a token scanner ```javascript theme={null} const headers = { "x-api-key": "YOUR_API_KEY" }; // 1. Get trending tokens const trending = await fetch( "https://data.solanatracker.io/tokens/trending/1h", { headers } ).then(r => r.json()); // 2. Check top performers const gainers = await fetch( "https://data.solanatracker.io/top-performers/1h", { headers } ).then(r => r.json()); // 3. Cross-reference: trending tokens that are also top gainers const gainerAddresses = new Set(gainers.map(g => g.token.mint)); const hotTokens = trending.filter(t => gainerAddresses.has(t.token.mint)); console.log(`${hotTokens.length} tokens are both trending and top gainers:`); hotTokens.forEach(t => { console.log(` ${t.token.name} (${t.token.symbol})`); }); ``` Deep-dive into any token: stats, holders, trades, and events. Check if a new token has suspicious early buyer activity. Stream new tokens, graduating tokens, and curve events in real time. Track snipers and bundlers on newly discovered tokens. # Get Solana token holders and wallet concentration Source: https://docs.solanatracker.io/guides/token-holders Fetch top Solana token holders or paginate through the full list. Calculate wallet concentration and connect holder snapshots to live updates. Choose a holder endpoint based on the number of wallets you need: top 20, top 100, or the full paginated list. Use wallet balances and supply percentages to show how holdings are distributed. ## Top 100 holders Use [top 100 holders](/data-api/tokens/get-token-holders-top-100) for a ranked holder table without pagination. ```bash cURL theme={null} curl "https://data.solanatracker.io/tokens/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN/holders" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const res = await fetch(`https://data.solanatracker.io/tokens/${token}/holders`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const { accounts: holders, total } = await res.json(); console.log(`Total holders: ${total}`); holders.forEach((h, i) => { console.log(`#${i + 1} ${h.wallet} — ${h.percentage.toFixed(2)}% (${h.amount.toLocaleString()} tokens)`); }); ``` ```python Python theme={null} import requests token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" res = requests.get( f"https://data.solanatracker.io/tokens/{token}/holders", headers={"x-api-key": "YOUR_API_KEY"} ) data = res.json() print(f"Total holders: {data['total']}") for i, h in enumerate(data["accounts"]): print(f"#{i+1} {h['wallet']} — {h['percentage']:.2f}%") ``` ## Top 20 holders Use [top 20 holders](/data-api/tokens/get-top-20-token-holders) when only the largest positions matter. ```bash theme={null} curl "https://data.solanatracker.io/tokens/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN/holders/top" \ -H "x-api-key: YOUR_API_KEY" ``` **Quick concentration check:** ```javascript theme={null} const res = await fetch(`https://data.solanatracker.io/tokens/${token}/holders/top`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const holders = await res.json(); const top10Pct = holders.slice(0, 10).reduce((sum, h) => sum + h.percentage, 0); console.log(`Top 10 wallets hold ${top10Pct.toFixed(1)}% of supply`); if (top10Pct > 50) { console.log("Top 10 concentration exceeds the 50% alert threshold"); } else if (top10Pct > 30) { console.log("Top 10 concentration exceeds the 30% alert threshold"); } else { console.log("Top 10 concentration is at or below 30%"); } ``` ## All holders (paginated) Use [paginated holders](/data-api/tokens/get-all-token-holders-paginated) for a full export or a supply-distribution snapshot. Each page can contain up to 5,000 holders. Pass the response's `cursor` unchanged in the next request. Continue until there is no next page. ```bash cURL theme={null} # First page curl "https://data.solanatracker.io/tokens/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN/holders/paginated?limit=1000" \ -H "x-api-key: YOUR_API_KEY" # Subsequent pages — pass the cursor from the previous response curl "https://data.solanatracker.io/tokens/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN/holders/paginated?limit=1000&cursor=CURSOR_FROM_PREV_RESPONSE" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} async function getAllHolders(token) { const allHolders = []; let cursor = null; do { const url = new URL(`https://data.solanatracker.io/tokens/${token}/holders/paginated`); url.searchParams.set("limit", "1000"); if (cursor) url.searchParams.set("cursor", cursor); const res = await fetch(url.toString(), { headers: { "x-api-key": "YOUR_API_KEY" } }); const data = await res.json(); allHolders.push(...data.accounts); cursor = data.hasMore ? data.cursor : null; console.log(`Fetched ${allHolders.length} / ${data.total} holders`); } while (cursor); return allHolders; } const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const holders = await getAllHolders(token); console.log(`Total holders fetched: ${holders.length}`); ``` ```python Python theme={null} import requests def get_all_holders(token, api_key): all_holders = [] cursor = None base_url = f"https://data.solanatracker.io/tokens/{token}/holders/paginated" headers = {"x-api-key": api_key} while True: params = {"limit": 1000} if cursor: params["cursor"] = cursor res = requests.get(base_url, headers=headers, params=params) data = res.json() all_holders.extend(data["accounts"]) print(f"Fetched {len(all_holders)} / {data['total']} holders") cursor = data.get("cursor") if data.get("hasMore") else None if not cursor: break return all_holders holders = get_all_holders( "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN", "YOUR_API_KEY" ) print(f"Done — {len(holders)} total holders") ``` ## Holder concentration analysis Sum the largest holders' percentages to measure concentration. Check wallet labels before treating pool accounts or other infrastructure accounts as individual traders. Holder table showing wallet labels beside top token holders ```javascript theme={null} async function analyzeConcentration(token) { const res = await fetch( `https://data.solanatracker.io/tokens/${token}/holders/top`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const holders = await res.json(); const top5 = holders.slice(0, 5).reduce((s, h) => s + h.percentage, 0); const top10 = holders.slice(0, 10).reduce((s, h) => s + h.percentage, 0); const top20 = holders.reduce((s, h) => s + h.percentage, 0); console.log(`Top 5 wallets: ${top5.toFixed(1)}%`); console.log(`Top 10 wallets: ${top10.toFixed(1)}%`); console.log(`Top 20 wallets: ${top20.toFixed(1)}%`); console.log(`Largest single holder: ${(holders[0]?.percentage ?? 0).toFixed(2)}%`); // Example display thresholds; choose thresholds for your application if ((holders[0]?.percentage ?? 0) > 20) console.log("Largest account holds more than 20%"); if (top10 > 50) console.log("Top 10 accounts hold more than 50%"); } ``` Cross-reference holder data with the [risk score](/data-api/risk) returned by the token info endpoint — it already factors in top-10 concentration and single-wallet ownership thresholds. See the [Token Safety & Rugcheck](/guides/token-safety) guide for details. ## Use cases | What you're building | Endpoint to use | | - | - | | Quick concentration check before buying | Top 20 holders | | Holder count badge on a token page | Top 100 (check `total` field) | | Full holder export / CSV | Paginated (cursor loop) | | Whale alert — detect large positions | Top 100 or Top 20, filter by `percentage` | | Historical holder distribution | Paginated snapshots over time | ## Live holder updates For live count and concentration changes, follow the [holder updates guide](/guides/live-holder-updates). Use paginated REST snapshots when you need the full wallet list. # Query Solana token data, holders, and trades Source: https://docs.solanatracker.io/guides/token-research Get Solana token metadata, pool data, trading stats, holders, and recent swaps. Build a token page with the Solana Tracker Data API. Start with the token mint. Fetch metadata and pools, add trading stats and holders, then load recent swaps or liquidity activity. The examples below cover each part of a token page. ## Get token info Fetch [token information](/data-api/tokens/get-token-information) for the mint. Read metadata from `token` and market data from `pools`; a token can have more than one pool. ```bash cURL theme={null} curl "https://data.solanatracker.io/tokens/{tokenAddress}" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch(`https://data.solanatracker.io/tokens/${token}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const data = await res.json(); console.log(`${data.token.name} (${data.token.symbol})`); console.log(`Price: $${data.pools[0]?.price?.usd}`); console.log(`Market Cap: $${data.pools[0]?.marketCap?.usd}`); ``` ```python Python theme={null} import requests token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump" res = requests.get( f"https://data.solanatracker.io/tokens/{token}", headers={"x-api-key": "YOUR_API_KEY"} ) data = res.json() print(f"{data['token']['name']} ({data['token']['symbol']})") ``` ## Token stats The `/events` endpoints are **deprecated**. Switch to [token stats](/data-api/stats/get-token-stats) (`GET /stats/{token}`) or [token-pool stats](/data-api/stats/get-token-pool-stats) (`GET /stats/{token}/{pool}`). Both return computed statistics as JSON, without binary decoding. With the SDK, use `client.getTokenStats(token)` or `client.getPoolStats(token, pool)`. Use [token stats](/data-api/stats/get-token-stats) for volume, buy/sell counts, and unique traders over each supported window. ```bash theme={null} curl "https://data.solanatracker.io/stats/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` Returns stats broken down by `5m`, `1h`, `6h`, and `24h` windows including: * Buy and sell volume (USD) * Number of buys and sells * Unique buyers and sellers * Price change percentage ## Token holders ### Top 100 The [top 100 holders](/data-api/tokens/get-token-holders-top-100) endpoint returns the largest token holders. ```bash theme={null} curl "https://data.solanatracker.io/tokens/{token}/holders" \ -H "x-api-key: YOUR_API_KEY" ``` ### All holders (paginated) For the full holder list, use the [paginated holders](/data-api/tokens/get-all-token-holders-paginated) endpoint: ```bash theme={null} # Page 1 curl "https://data.solanatracker.io/tokens/{token}/holders/paginated?limit=100" \ -H "x-api-key: YOUR_API_KEY" ``` ## Recent trades By default, trade endpoints return swaps. Set `events=all` to include liquidity adds and removes, or `events=liquidity` for LP activity only. Use `limit` to set the page size. See the [liquidity activity guide](/guides/liquidity) for REST history and live rooms. The [token trades](/data-api/trades/get-token-trades) endpoint returns the most recent buys and sells. ```bash cURL theme={null} curl "https://data.solanatracker.io/trades/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"; const res = await fetch(`https://data.solanatracker.io/trades/${token}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const { trades } = await res.json(); trades.forEach(t => { const side = t.type === "buy" ? "BUY" : "SELL"; console.log(`${side} $${t.volume.toFixed(2)} by ${t.wallet}`); }); ``` You can also filter trades by pool or by a specific wallet: ```bash theme={null} # Trades on a specific pool curl "https://data.solanatracker.io/trades/{token}/{pool}" \ -H "x-api-key: YOUR_API_KEY" # Trades by a specific wallet curl "https://data.solanatracker.io/trades/{token}/by-wallet/{wallet}" \ -H "x-api-key: YOUR_API_KEY" ``` ## Search for tokens The [search endpoint](/data-api/search/token-search) finds tokens by name, symbol, or address. ```bash theme={null} # Search by name curl "https://data.solanatracker.io/search?query=bonk" \ -H "x-api-key: YOUR_API_KEY" # Search by exact symbol curl "https://data.solanatracker.io/search?symbol=BONK" \ -H "x-api-key: YOUR_API_KEY" ``` Filter by [Coin Communities](/guides/search-coin-communities) activity — live message counts, range filters, and sorting by `communityMessages`. ## Discover new tokens Most recently created tokens on Solana. Tokens with the most activity right now. Tokens approaching the end of their bonding curve. Tokens ranked by price change over a selected period. ## All-time high Fetch the all-time high to compare with the current price: ```bash theme={null} curl "https://data.solanatracker.io/tokens/{token}/ath" \ -H "x-api-key: YOUR_API_KEY" ``` Fetch chart candles, historical prices, and multi-token price snapshots. Find early buyers, bundled launches, and suspicious wallet activity on a token. # Read Solana token risk scores and safety signals Source: https://docs.solanatracker.io/guides/token-safety Read Solana token risk scores, mint and freeze authority, liquidity flags, and holder concentration. Build filters from the Data API risk response. The token response includes a `risk` object with a score and individual risk factors. Read the factors alongside liquidity and holder data; a score is a screening signal, not a guarantee about a token. ## Get the risk score The risk score is included in the standard [token info](/data-api/tokens/get-token-information) response under `risk`. Higher score means higher risk. The final score uses a 1–10 range, even though individual risk factors use larger internal weights. ```bash cURL theme={null} curl "https://data.solanatracker.io/tokens/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"; const res = await fetch(`https://data.solanatracker.io/tokens/${token}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const data = await res.json(); const risk = data.risk; console.log(`Risk score: ${risk.score}/10`); console.log(`Rugged: ${risk.rugged}`); console.log(`Risk factors: ${risk.risks.length}`); risk.risks.forEach(r => { console.log(` [${r.level.toUpperCase()}] ${r.name}: ${r.description}`); }); ``` ```python Python theme={null} import requests token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" data = requests.get( f"https://data.solanatracker.io/tokens/{token}", headers={"x-api-key": "YOUR_API_KEY"} ).json() risk = data["risk"] print(f"Risk score: {risk['score']}/10") for r in risk["risks"]: print(f" [{r['level'].upper()}] {r['name']}") ``` **Risk response shape:** ```json theme={null} { "score": 7.4, "rugged": false, "risks": [ { "name": "Freeze Authority Enabled", "description": "Tokens can be frozen and prevented from trading in the future", "level": "danger", "score": 7500 }, { "name": "Top 10 Holders", "description": "Top 10 holders own more than 15% of the total supply", "level": "danger", "score": 5000 } ] } ``` ## Key risk factors ### Freeze authority An active freeze authority can freeze token accounts. Check who controls that authority before presenting the token as unrestricted. ```javascript theme={null} const isFreezeEnabled = data.risk.risks.some(r => r.name === "Freeze Authority Enabled"); if (isFreezeEnabled) { console.log("🚨 Freeze authority is ON — dev can freeze your tokens"); } ``` ### Mint authority An active mint authority can issue additional supply. Show the authority status alongside supply and holder data. ```javascript theme={null} const isMintEnabled = data.risk.risks.some(r => r.name === "Mint Authority Enabled"); if (isMintEnabled) { console.log("🚨 Mint authority is ON — supply can be inflated at any time"); } ``` ### LP burned vs removable Removable liquidity can change a pool's ability to fill swaps. Read the LP status alongside current pool liquidity. ```javascript theme={null} const lpNotBurned = data.risk.risks.some(r => r.name === "LP Burned"); if (lpNotBurned) { console.log("⚠️ LP not burned — dev can remove liquidity at any time"); } ``` ### Bundler activity Bundler fields identify wallets associated with bundled launch activity. `totalBundlerPercentage` measures their share of supply; choose a display threshold based on your application. ```javascript theme={null} const bundlerRisk = data.risk.risks.find(r => r.name.toLowerCase().includes("bundl")); if (bundlerRisk) { console.log(`⚠️ Bundler activity detected — ${bundlerRisk.description}`); } ``` ### Insider concentration Insider fields describe wallets identified by the API's insider signals. Review their holdings and changes alongside developer and first-buyer data. ```javascript theme={null} const insiderRisk = data.risk.risks.find(r => r.name.toLowerCase().includes("insider")); if (insiderRisk) { console.log(`⚠️ Insider wallets detected: ${insiderRisk.description}`); } ``` ### Rugged status Read `risk.rugged` as a separate flag in the risk response. Show the flag together with the reported risk factors and current pool state. ```javascript theme={null} if (data.risk.rugged) { console.log("💀 Token is rugged — no liquidity"); } ``` ## Build a risk screener This example excludes tokens with a danger-level factor. Adjust the filter to the fields your app needs to display: ```javascript theme={null} async function isSafe(token) { const res = await fetch(`https://data.solanatracker.io/tokens/${token}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const data = await res.json(); const { risk } = data; if (risk.rugged) return { safe: false, reason: "Rugcheck: token is rugged" }; if (risk.score >= 8) return { safe: false, reason: `Risk score too high: ${risk.score}/10` }; const dangerFlags = risk.risks.filter(r => r.level === "danger"); if (dangerFlags.length > 0) { return { safe: false, reason: dangerFlags.map(r => r.name).join(", ") }; } return { safe: true, score: risk.score }; } const result = await isSafe("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN"); console.log(result); // { safe: false, reason: "Freeze Authority Enabled, Top 10 Holders" } ``` ## Risk score reference | Score range | Risk level | What it means | | - | - | - | | 1–3 | Low | Lower reported score; inspect the individual factors | | 4–6 | Medium | Some warnings, review manually | | 7–8 | High | One or more danger factors — proceed with caution | | 9–10 | Critical | Higher reported score; inspect the factors and rugged flag | For the complete list of risk factors and their weights, see the [Risk Score Reference](/data-api/risk). ## Real-time safety monitoring Risk scores reflect a point-in-time snapshot. For live alerts — sniper wallet movements, dev selling, bundler activity as it happens — use the Safety Streams via Datastream WebSocket. See the [Safety Streams](/guides/datastream-safety) guide. # Track Solana wallet holdings and trade history Source: https://docs.solanatracker.io/guides/wallet-tracking Query Solana wallet token balances, recent trades, and portfolio charts. Add PnL analysis or live wallet updates when your app needs them. Use wallet endpoints for token holdings, recent swaps, and portfolio value. Add PnL V2 when you need cost basis, realized returns, or per-token performance. PnL means profit and loss. For detailed PnL with cost basis, win rate, and realized profit, use the [PnL V2 wallet endpoints](/guides/pnl-v2/wallet-analysis) instead. ## Wallet tokens The [wallet tokens endpoint](/data-api/wallet/get-wallet-tokens) returns token holdings and their current values. ```bash cURL theme={null} curl "https://data.solanatracker.io/wallet/{walletAddress}" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const wallet = "YOUR_WALLET_ADDRESS"; const res = await fetch(`https://data.solanatracker.io/wallet/${wallet}`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const { tokens } = await res.json(); tokens.forEach(t => { console.log(`${t.token.name}: ${t.balance} ($${t.value?.toFixed(2)})`); }); ``` ```python Python theme={null} import requests wallet = "YOUR_WALLET_ADDRESS" res = requests.get(f"https://data.solanatracker.io/wallet/{wallet}", headers={"x-api-key": "YOUR_API_KEY"}) for t in res.json()["tokens"]: print(f"{t['token']['name']}: {t['balance']} (${t.get('value', 0):.2f})") ``` ### Paginated holdings For wallets with many tokens, use the [paginated endpoint](/data-api/wallet/get-wallet-tokens-with-pagination): ```bash theme={null} # Page 1 (first page) curl "https://data.solanatracker.io/wallet/{wallet}/page/1" \ -H "x-api-key: YOUR_API_KEY" ``` ## Basic wallet info Use the [basic wallet endpoint](/data-api/wallet/get-basic-wallet-information) for totals without the full token list. ```bash theme={null} curl "https://data.solanatracker.io/wallet/{wallet}/basic" \ -H "x-api-key: YOUR_API_KEY" ``` ## Wallet trades The [wallet trades endpoint](/data-api/wallet/get-wallet-trades) returns recent trades across all tokens for a wallet. ```bash cURL theme={null} curl "https://data.solanatracker.io/wallet/{wallet}/trades" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const wallet = "YOUR_WALLET_ADDRESS"; const res = await fetch(`https://data.solanatracker.io/wallet/${wallet}/trades`, { headers: { "x-api-key": "YOUR_API_KEY" } }); const { trades } = await res.json(); trades.forEach(t => { console.log(`${t.from.token.symbol} → ${t.to.token.symbol}: $${t.volume.usd.toFixed(2)} at ${new Date(t.time).toISOString()}`); }); ``` ## Portfolio chart Use the [wallet chart endpoint](/data-api/wallet/get-wallet-portfolio-chart) to plot portfolio value over time. Wallet dashboard showing net worth, identity tags, and portfolio chart ```bash theme={null} curl "https://data.solanatracker.io/wallet/{wallet}/chart" \ -H "x-api-key: YOUR_API_KEY" ``` ## Wallet PnL Use [PnL V2](/guides/pnl-v2/overview) for wallet summaries, token positions, identity tags (including [SNS primary `.sol` domains](/guides/pnl-v2/sns-identity)), PnL modes, and batch lookups. ```bash theme={null} # Wallet-level PnL summary curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}" \ -H "x-api-key: YOUR_API_KEY" # All token positions for a wallet curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions?sort=total&direction=desc" \ -H "x-api-key: YOUR_API_KEY" # Token-specific PnL curl "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/tokens/{token}" \ -H "x-api-key: YOUR_API_KEY" ``` ## Top traders Use the [Solana Traders Leaderboard](/guides/pnl-v2/leaderboards#solana-traders-leaderboard) for Solana-wide trader rankings, and [Token Intelligence](/guides/pnl-v2/token-intelligence) for token-specific trader rankings. ### Solana traders leaderboard ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/leaderboard/top?days=30&sort=realized&direction=desc&limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` ### Token-specific top traders ```bash theme={null} curl "https://data.solanatracker.io/v2/pnl/tokens/{token}/traders?sort=pnl&direction=desc&limit=50" \ -H "x-api-key: YOUR_API_KEY" ``` ## Example: wallet dashboard ```javascript theme={null} const wallet = "YOUR_WALLET_ADDRESS"; const headers = { "x-api-key": "YOUR_API_KEY" }; // 1. Basic info const basic = await fetch( `https://data.solanatracker.io/wallet/${wallet}/basic`, { headers } ).then(r => r.json()); // 2. All holdings const holdings = await fetch( `https://data.solanatracker.io/wallet/${wallet}`, { headers } ).then(r => r.json()); // 3. Recent trades const trades = await fetch( `https://data.solanatracker.io/wallet/${wallet}/trades`, { headers } ).then(r => r.json()); // 4. Portfolio chart const chart = await fetch( `https://data.solanatracker.io/wallet/${wallet}/chart`, { headers } ).then(r => r.json()); console.log(`Tokens held: ${holdings.tokens.length}`); console.log(`Recent trades: ${trades.trades.length}`); console.log(`Chart data points: ${chart.chartData.length}`); ``` Full PnL calculations with cost basis, win rate, and position tracking. Track and compare KOL wallet performance over time. Monitor wallet transactions and balance changes in real time. Stream real-time prices for tokens in a wallet's portfolio. # Track whale and KOL trades on Solana Source: https://docs.solanatracker.io/guides/whale-kol Query whale and KOL trades on Solana, filter by USD size or token, and subscribe to live Datastream feeds with wallet identity. Load recent whale or KOL trades with REST, then subscribe to Datastream for new activity. Whale filters use fixed USD thresholds; the base KOL feed also includes trades below \$1,000. The REST API returns the latest indexed trades. Datastream delivers new trades in real time over WebSocket. Both use your Solana Tracker Data API key. ## REST API ### Latest whale trades Request whale trades above a supported USD threshold: ```bash theme={null} curl "https://data.solanatracker.io/trades/whales?minVolume=10000&limit=50&hideArb=true" \ -H "x-api-key: YOUR_API_KEY" ``` `minVolume` accepts `1000`, `2500`, `5000`, or `10000`. Results are sorted newest first. ### Latest KOL trades Fetch trades from wallets on the shared KOL roster: ```bash theme={null} curl "https://data.solanatracker.io/trades/kols?minVolume=2500&limit=100" \ -H "x-api-key: YOUR_API_KEY" ``` For all eligible KOL trades, use `minVolume=0` or omit `minVolume` entirely: ```bash theme={null} curl "https://data.solanatracker.io/trades/kols?limit=100" \ -H "x-api-key: YOUR_API_KEY" ``` When identity data is available, each trade includes: ```json theme={null} { "wallet": "9jyqFiLnruggWnN4EQwBNFXwpbLM9hrA4hV59ytyAVVz", "type": "buy", "volume": 1517.82, "identity": { "name": "Example KOL", "twitter": "@example" } } ``` ### KOL trades for one token Scope KOL trades to a mint for a token page or alert: ```bash theme={null} curl "https://data.solanatracker.io/trades/kols/TOKEN_MINT?minVolume=1000&hideArb=true" \ -H "x-api-key: YOUR_API_KEY" ``` The token-scoped KOL endpoint also defaults to `minVolume=0`; pass `minVolume=0` explicitly when you want to make that behavior clear. With `hideArb=true`, the response keeps only rows where the requested mint is one side of the trade. ### Paginate through history Responses include `nextCursor` and `hasNextPage`. Pass the opaque cursor back unchanged: ```javascript theme={null} const base = "https://data.solanatracker.io/trades/whales"; const params = new URLSearchParams({ minVolume: "5000", limit: "250", showMeta: "true", }); let cursor; do { if (cursor) params.set("cursor", cursor); const response = await fetch(`${base}?${params}`, { headers: { "x-api-key": process.env.SOLANA_TRACKER_API_KEY }, }); const page = await response.json(); for (const trade of page.trades) { console.log(trade.time, trade.type, trade.volume, trade.wallet); } cursor = page.hasNextPage ? page.nextCursor : null; } while (cursor); ``` Use `showMeta=true` when your UI needs token names, symbols, images, decimals, or historical prices for the `from` and `to` sides. Treat `nextCursor` as opaque. Do not decode, modify, or construct cursors in application code. ## Real-time Datastream Connect to: ```text theme={null} wss://datastream.solanatracker.io/{YOUR_API_KEY} ``` ### Whale watch Join a tier room to receive new qualifying trades: ```javascript theme={null} const ws = new WebSocket( "wss://datastream.solanatracker.io/YOUR_API_KEY" ); ws.addEventListener("open", () => { ws.send(JSON.stringify({ type: "join", room: "transaction:whale:10000", })); }); ws.addEventListener("message", (event) => { const message = JSON.parse(event.data); if (message.type !== "message") return; for (const trade of message.data) { const label = trade.type === "buy" ? "WHALE BUY" : "WHALE SELL"; console.log( `${label} $${trade.volume.toLocaleString()} ` + `${trade.token?.to?.symbol ?? "token"} by ${trade.wallet}` ); } }); ``` Available whale rooms: ```text theme={null} transaction:whale:1000 transaction:whale:2500 transaction:whale:5000 transaction:whale:10000 ``` Rooms are cumulative. A \$12,000 trade is delivered to the `1000`, `2500`, `5000`, and `10000` rooms. Join only the tiers your application needs. ### KOL tracker `transaction:kol` receives every eligible KOL trade, including trades below the \$1,000 tier threshold: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "transaction:kol", })); ws.addEventListener("message", (event) => { const message = JSON.parse(event.data); if (message.type !== "message" || message.room !== "transaction:kol") { return; } const trade = message.data[0]; const identity = trade.identity?.twitter || trade.identity?.name || trade.wallet; console.log( `${identity}: ${trade.type} $${trade.volume.toLocaleString()} ` + `on ${trade.token?.to?.symbol ?? trade.token?.from?.symbol ?? "token"}` ); }); ``` For high-value KOL alerts, use cumulative tier rooms: ```javascript theme={null} ws.send(JSON.stringify({ type: "join", room: "transaction:kol:5000", })); ``` ### KOL signal pipeline Apply a size filter to incoming KOL trades before sending an alert: ```javascript theme={null} function handleKolTrade(message) { if (message.type !== "message") return; for (const trade of message.data) { const identity = trade.identity; const token = trade.token?.to?.symbol || trade.token?.from?.symbol; if (trade.type === "buy" && trade.volume >= 5000) { console.log({ event: "kol_buy_signal", wallet: trade.wallet, name: identity?.name, twitter: identity?.twitter, token, volumeUsd: trade.volume, signature: trade.tx, }); } } } ws.addEventListener("message", (event) => { handleKolTrade(JSON.parse(event.data)); }); ``` Keep raw trades separate from alerts derived from them. An alert is an application event; it does not submit a swap. ## Message shape Whale and KOL Datastream messages contain one enriched trade in a one-item `data` array: ```json theme={null} { "type": "message", "room": "transaction:whale:10000", "data": [ { "tx": "TRANSACTION_SIGNATURE", "amount": 125000.5, "priceUsd": 0.00012, "solVolume": 12.5, "volume": 12500, "type": "buy", "wallet": "WALLET_ADDRESS", "time": 1786470000000, "program": "raydium", "token": { "from": { "symbol": "SOL", "amount": 12.5 }, "to": { "symbol": "MEME", "amount": 125000.5 } }, "identity": { "name": "Example KOL", "twitter": "@example" } } ] } ``` `identity` is present when the trading wallet is on the shared KOL roster. `time` is a Unix timestamp in milliseconds. `volume` is absolute USD volume; use `type` to determine buy or sell direction. ## Production checklist 1. Deduplicate by transaction signature plus wallet, token, and side if your consumer reconnects. 2. Persist the last REST `nextCursor` when backfilling. 3. Reconnect WebSocket clients with exponential backoff. 4. Join only the required rooms to avoid duplicate cumulative events. 5. Store the raw trade and your derived alert separately. 6. Apply your own risk and execution checks before copy trading. Browse endpoint parameters, response schemas, and pagination. Browse rooms, join messages, and live trade payloads. Subscribe to every swap for a token. Analyze wallet performance and KOL activity. # Solana Tracker Docs Source: https://docs.solanatracker.io/index Solana Tracker docs — Data API with 70+ endpoints, Datastream WebSockets, the Raptor DEX aggregator, Yellowstone gRPC, and dedicated Solana RPC nodes.

Core Products

Token prices, holder analytics, chart data, and market intelligence across Solana pools. Swap routing across 71 Solana DEXes. Currently free, as a hosted API or a self-hosted binary. Beta Kalshi and Polymarket API — markets, full history, and live Datastream rooms. Standard and custom HTTP/WebSocket methods. Shared and dedicated node infrastructure. High-throughput account, transaction, slot, and entry streaming over gRPC.

Quick Start

Get your API key and make your first request in a few minutes. Plans, rate limits, and pricing for every Solana Tracker product. Real-time WebSocket feeds for new tokens, trades, and price changes. Plain-language definitions for trading, PnL, RPC, and streaming terms. Machine-readable docs for LLM agents and RAG pipelines.

Key Methods

Wide account scans with practical server-side filters. Dynamic fee estimation for optimal transaction landing. Broadcast transactions with confirmation tracking. Stream and filter transactions in real time over gRPC.

Resources

Latest releases and API changes. Uptime monitoring and incident history. Community support and implementation help.
# Pricing & Limits Source: https://docs.solanatracker.io/pricing Plans, rate limits, and pricing for the Solana Tracker Data API, Datastream, Solana RPC, Yellowstone gRPC, dedicated nodes, and free products. All prices are in **EUR**. Annual billing saves **30%** on Data API plans and **15%** on shared RPC plans. Dedicated nodes offer additional commit discounts. REST endpoints for tokens, wallets, trades, charts, and PnL. Shared RPC with Shredstream, V2 methods, and credit-based usage. Real-time account, transaction, slot, and block streaming over gRPC. Private bare-metal RPC with zero rate limits and optional RidgeDB. *** ## Data API & Datastream The Data API covers 70+ REST endpoints for token data, wallet analytics, trades, OHLCV charts, risk scores, and PnL V2. WebSocket **Datastream** access starts on the **Premium** plan and above. Datastream has 20+ room types, unlimited messages on Premium+, and no usage-based fees. Manage your plan and API keys in the dashboard. | Plan | Price (monthly) | Requests / month | Rate limit | Datastream | Support | | - | - | - | - | - | - | | **Free** | €0 | 10,000 | 3 req/sec | No | - | | **Advanced** | €50 | 200,000 | None | No | Discord / email | | **Pro** | €200 | 1,000,000 | None | No | Discord / email | | **Premium** | €397 | 10,000,000 | - | Yes | Discord, email, Telegram, Calendly | | **Business** | €599 | 25,000,000 | - | Yes | Discord, email, Telegram, Calendly | | **Enterprise** | €1,499 | 100,000,000 | - | Yes | Priority support | | **Enterprise+** | Custom | Custom / unlimited | - | Yes | Dedicated infra, white-label | Annual billing saves 30% on all paid Data API plans. ### Datastream availability | Feature | Free to Pro | Premium+ | | - | - | - | | REST API | Yes | Yes | | WebSocket Datastream | No | Yes | | Message limits | - | Unlimited on Premium+ | | Usage-based fees | - | None | Datastream rooms for PnL V2, live transactions, holder updates, and price feeds require **Premium, Business, or Enterprise**. See the [Datastream protocol](/guides/datastream-protocol) and [Datastream guides](/guides/datastream-prices) for room details. ### Datastream connection limits | Detail | Policy | | - | - | | URL | Always `wss://datastream.solanatracker.io/{apiKey}`. Custom Data API REST hostnames do **not** serve Datastream. | | Messages | Unlimited on Premium+ (no per-message fees). | | Concurrent connections & rooms | No limit. | | REST quota exhaustion | Does **not** close an established Datastream connection. REST over-quota returns `429`; the WebSocket session keeps streaming until disconnect/auth failure. | *** ## Solana RPC Shared Solana RPC uses a **credit-based** system. Most methods cost 1 credit; archival and DAS calls cost 10 credits. V2 optimized methods cost 1 credit and use 90% fewer credits than their standard counterparts. Get started with the free tier or upgrade from your dashboard. | Plan | Price | Monthly credits | General RPS | Included | | - | - | - | - | - | | **Free** | €1 one-time | 500,000 | 5 | 2 WebSocket connections | | **Developer** | €35/mo | 15,000,000 | 60 | Shredstream | | **Business** | €399/mo | 100,000,000 | 225 | Shredstream + Yellowstone gRPC | | **Professional** | €799/mo | 250,000,000 | 500 | Shredstream + Yellowstone gRPC | Annual billing saves 15% on all paid RPC plans. For per-method credit costs and detailed RPS limits (sendTransaction, getProgramAccounts, DAS API, WebSocket connections), see [Credits and Rate Limits](/solana-rpc/credits-and-rate-limits). *** ## Yellowstone gRPC Yellowstone gRPC streams real-time Solana data (accounts, transactions, slots, blocks, and entries) over a persistent gRPC connection. Enhanced with Jito Shredstream for 50-150 ms lower latency. | Option | Price | Connections | Regions | Overages | | - | - | - | - | - | | **Standalone** | €200/mo | 25 concurrent | EU + US | None | | **Bundled with RPC Business** | Included with €399/mo RPC | 25 concurrent | EU + US | None | | **Bundled with RPC Professional** | Included with €799/mo RPC | 25 concurrent | EU + US | None | | **Bundled with dedicated nodes** | Included | - | - | None | Standalone gRPC or bundled with an RPC plan. Standalone endpoints: * **EU:** `https://grpc.solanatracker.io` * **US:** `https://grpc-us.solanatracker.io` See the full plan comparison on this page or the [Yellowstone gRPC docs](/yellowstone-grpc/index). *** ## Dedicated Nodes Deploy private Solana RPC nodes with **zero rate limits**, IP whitelisting, and real-time monitoring. Most nodes are live within 24 hours. Choose hardware, region, and billing from the dashboard. | Configuration | Price (monthly) | Hardware | | - | - | - | | **Standard Server** | €1,297 | 24-core AMD EPYC, 512 GB RAM | | **Large Server** | €2,097 | 32-core AMD EPYC, 1 TB+ RAM, account indexes enabled | | **Solana Ridge DB add-on** | €900 | 1k-10k RPS on getProgramAccounts / V2 / getTokenAccountsByOwner | **Included with every dedicated node:** * Yellowstone gRPC * Raptor Swap API * Global load balancer (free with 2+ nodes) **Commit discounts:** | Billing period | Discount | | - | - | | 3 months | 10% off | | 6 months | 15% off | | 12 months | 20% off | Available in 11 regions: New York, Los Angeles, Utah, St. Louis, Chicago, Frankfurt, Strasbourg, Amsterdam, Šiauliai, Tokyo, and Singapore. *** ## Free products These products have no subscription fee: | Product | Pricing | Notes | | - | - | - | | **Raptor (self-hosted)** | Free | Download the binary from [GitHub](https://github.com/solanatracker/raptor-binary/releases/latest). No API keys, no rate limits, no licensing fees. See [Self-hosting](/raptor/self-hosting). | | **Raptor hosted API** | Free | `raptor.solanatracker.io`. Currently free, with no API key. See the [Raptor overview](/raptor/overview). | | **Prediction Markets API** | Public beta | `prediction-market-api.solanatracker.io`. Uses your Data API key. No separate plan pricing yet. | | **Swap UI** | 0% fees | Best-price swaps across 20+ DEXes at [solanatracker.io/swap](https://www.solanatracker.io/swap) | | **Memescope** | Free | Real-time token launch feed at [solanatracker.io/memescope](https://www.solanatracker.io/memescope) | | **Trading Terminal** | Free | Real-time charts, swaps, and portfolio tracking | *** ## Billing & upgrades * All listed prices are in **EUR**. * **Data API:** 30% off with annual billing. * **Shared RPC:** 15% off with annual billing. * **Dedicated nodes:** 10% off (3 mo), 15% off (6 mo), 20% off (12 mo). * **RPC credits** reset each billing cycle and do not roll over. * **Upgrades** take effect immediately with the new allowance and limits. This restarts your subscription billing cycle. * **Enterprise+** and custom volume: contact [contact@solanatracker.io](mailto:contact@solanatracker.io) or [book a call](https://www.solanatracker.io/data-api). *** ## FAQ Datastream starts on the **Premium** plan (€397/mo) and above. Free through Pro plans include REST API access only. Connect only to `wss://datastream.solanatracker.io/{apiKey}` — see [Datastream protocol](/guides/datastream-protocol). No. On Premium+, message volume is unlimited, and there is no limit on concurrent WebSocket connections or rooms per connection. REST request quota exhaustion does not drop an active Datastream session. No. Yellowstone gRPC is available as a standalone service (€200/mo) or bundled free with RPC Business, RPC Professional, and all dedicated nodes. Requests exceeding your plan limits return a `429 Too Many Requests` error. RPC credits are consumed per call based on method cost. See [Credits and Rate Limits](/solana-rpc/credits-and-rate-limits). No. Credits reset at the start of each billing cycle. There is no separate "add credits" purchase. To get more capacity before your cycle resets, **upgrade your plan** from your [account dashboard](https://www.solanatracker.io/account). Upgrades take effect immediately with the higher allowance and restart your subscription billing cycle. If you don't upgrade, requests over your allowance return `429 Too Many Requests` until the next cycle begins. Yes. Dedicated nodes serve only your traffic with zero rate limits. Optional RidgeDB add-on provides 1k-10k RPS on account query methods. Upgrade from your [account dashboard](https://www.solanatracker.io/account). For Enterprise+, white-label, or custom request limits, email [contact@solanatracker.io](mailto:contact@solanatracker.io). # Quick Start Source: https://docs.solanatracker.io/quickstart Get up and running with the Solana Tracker Data API in a few minutes — sign up, grab an API key, and make your first token, wallet, and price requests. This guide will help you make your first API calls to the Solana Tracker Data API. You'll learn how to authenticate, make requests, and handle responses. ## Prerequisites Before you begin, make sure you have: Sign up for free to get your API key. ## Step 1: Get Your API Key After creating your account, retrieve your API key from the dashboard. This key is used to authenticate your requests by passing it in the `x-api-key` header. Visit [your account dashboard](https://www.solanatracker.io/account). In the dashboard sidebar, click [**Data API**](https://www.solanatracker.io/account/data-api). Each product has its own sidebar entry — there is no single "API Keys" page. Use **Data API** for the Data API and Datastream, [**Solana RPC**](https://www.solanatracker.io/account/shared-rpc) for shared RPC, [**Dedicated Nodes**](https://www.solanatracker.io/account/dedicated-nodes) for dedicated nodes, and [**Yellowstone gRPC**](https://www.solanatracker.io/account/yellowstone-grpc) for the Geyser stream. Click the copy button next to your API key. Keep your API key secure and never commit it to public repositories. ## Step 2: Make Your First API Call Let's start by fetching the current price of SOL using the `/price` endpoint. ```bash cURL theme={null} curl -X GET "https://data.solanatracker.io/price?token=So11111111111111111111111111111111111111112" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const apiKey = 'YOUR_API_KEY'; const solMint = 'So11111111111111111111111111111111111111112'; fetch(`https://data.solanatracker.io/price?token=${solMint}`, { headers: { 'x-api-key': apiKey } }) .then(response => response.json()) .then(data => console.log('SOL Price:', data.price)); ``` ```python Python theme={null} import requests api_key = 'YOUR_API_KEY' sol_mint = 'So11111111111111111111111111111111111111112' response = requests.get( f'https://data.solanatracker.io/price?token={sol_mint}', headers={ 'x-api-key': api_key } ) data = response.json() print(f"SOL Price: ${data['price']}") ``` ```json Success Response theme={null} { "price": 175.42, "priceQuote": 175.42, "liquidity": 14187570.69, "marketCap": 99213713748.19, "lastUpdated": 1760274132867 } ``` ## Step 3: Connect to RPC Nodes Solana Tracker also provides RPC nodes for direct blockchain calls. RPC uses a different URL and auth style than the Data API: | Product | Use it for | Auth style | | - | - | - | | Data API | Token prices, wallets, trades, and analytics | `x-api-key` header | | RPC | Direct Solana methods like balances and account updates | `api_key` in the RPC URL | ```javascript @solana/web3.js theme={null} import { Connection, PublicKey } from '@solana/web3.js'; const connection = new Connection( 'https://rpc-mainnet.solanatracker.io?api_key=YOUR_API_KEY', { commitment: 'confirmed', wsEndpoint: 'wss://rpc-mainnet.solanatracker.io?api_key=YOUR_API_KEY' } ); // Get account balance const publicKey = new PublicKey('YOUR_WALLET_ADDRESS'); const balance = await connection.getBalance(publicKey); console.log(`Balance: ${balance / 1e9} SOL`); // Subscribe to account changes connection.onAccountChange( publicKey, (accountInfo) => { console.log('Account updated:', accountInfo); } ); ``` ```python solana.py theme={null} from solana.rpc.api import Client from solders.pubkey import Pubkey # Connect to RPC client = Client("https://rpc-mainnet.solanatracker.io?api_key=YOUR_API_KEY") # Get account balance pubkey = Pubkey.from_string("YOUR_WALLET_ADDRESS") response = client.get_balance(pubkey) balance = response.value / 1e9 print(f"Balance: {balance} SOL") # Get recent blockhash blockhash = client.get_latest_blockhash() print(f"Recent blockhash: {blockhash.value.blockhash}") ``` ## Step 4: Explore Common Use Cases Monitor real-time price changes for any SPL token using the `/price` endpoint. ```javascript theme={null} const apiKey = 'YOUR_API_KEY'; const trackPrice = async (mint) => { const response = await fetch( `https://data.solanatracker.io/price?token=${mint}`, { headers: { 'x-api-key': apiKey } } ); const data = await response.json(); console.log(`Price: $${data.price}`); }; // Track price every 5 seconds setInterval(() => trackPrice('YOUR_TOKEN_MINT'), 5000); ``` Discover newly created tokens with the `/tokens/latest` endpoint. It returns the newest tokens first. ```javascript theme={null} const apiKey = 'YOUR_API_KEY'; const findNewTokens = async () => { const response = await fetch( 'https://data.solanatracker.io/tokens/latest', { headers: { 'x-api-key': apiKey } } ); const result = await response.json(); result.data.forEach(token => { console.log(`New token: ${token.token.symbol} on ${token.pools[0].market}`); console.log(`Liquidity: $${token.pools[0].liquidity.usd}`); }); }; ``` Track token holdings and the total portfolio value for any wallet. ```javascript theme={null} const apiKey = 'YOUR_API_KEY'; const getWalletTokens = async (walletAddress) => { const response = await fetch( `https://data.solanatracker.io/wallet/${walletAddress}`, { headers: { 'x-api-key': apiKey } } ); const portfolio = await response.json(); console.log(`Total Portfolio Value: $${portfolio.total}`); portfolio.tokens.forEach(holding => { const tokenInfo = holding.token; console.log(`${tokenInfo.symbol}: ${holding.balance} ($${holding.value.toFixed(2)})`); }); }; ``` ## Error Handling Always implement proper error handling in your applications. ```javascript JavaScript theme={null} const apiKey = 'YOUR_API_KEY'; try { const response = await fetch('https://data.solanatracker.io/price?token=INVALID_TOKEN_ADDRESS', { headers: { 'x-api-key': apiKey } }); if (!response.ok) { const error = await response.json(); console.error(`API Error: ${error.message || response.statusText}`); // Handle specific error codes switch (response.status) { case 401: console.error('Invalid API key'); break; case 429: console.error('Rate limit exceeded'); break; case 500: console.error('Server error - please retry'); break; } } else { const data = await response.json(); // Process successful response } } catch (error) { console.error('Network error:', error); } ``` ```python Python theme={null} import requests from time import sleep def api_call_with_retry(url, headers, max_retries=3): for attempt in range(max_retries): try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.json() elif response.status_code == 429: # Rate limited - wait and retry print(f"Rate limit exceeded. Retrying in {2 ** attempt}s...") sleep(2 ** attempt) # Exponential backoff elif response.status_code == 401: raise Exception("Invalid API key") else: print(f"Error {response.status_code}: {response.text}") break except requests.RequestException as e: print(f"Network error: {e}") if attempt < max_retries - 1: sleep(1) else: raise return None ``` **Need help?** Join our [Discord community](https://discord.gg/JH2e9rR9fc) or email [support@solanatracker.io](mailto:support@solanatracker.io). # Get DCA order by address Source: https://docs.solanatracker.io/data-api/dca/orders/get-dca-order-by-address /data-api/dca/openapi.json get /dca/order/{address} Returns a single DCA account by its pubkey. Order status values: | Status | Meaning | |--------|---------| | `active` | Recurring in progress — has fills and waiting for the next scheduled cycle, or due now | | `pending` | Funded but first cycle not run yet | | `paused` | Schedule paused on-chain or overdue well past 2× cycle frequency | | `completed` | No remaining input to spend | USD fields are included when price data is available; otherwise `*Usd` fields may be null or omitted. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaOrder('125PQmudTAXHUUGxtSra1xTzGu3NRCMbRU7i9cikEpwd'); ``` # Get DCA orders for trading pair Source: https://docs.solanatracker.io/data-api/dca/orders/get-dca-orders-for-trading-pair /data-api/dca/openapi.json get /dca/pair/{inputMint}/{outputMint} Orders for a specific input → output mint pair. Order status values: | Status | Meaning | |--------|---------| | `active` | Recurring in progress — has fills and waiting for the next scheduled cycle, or due now | | `pending` | Funded but first cycle not run yet | | `paused` | Schedule paused on-chain or overdue well past 2× cycle frequency | | `completed` | No remaining input to spend | USD fields are included when price data is available; otherwise `*Usd` fields may be null or omitted. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaPair('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', 'So11111111111111111111111111111111111111112', { sort: 'volume', limit: 10 }); ``` # List DCA programs Source: https://docs.solanatracker.io/data-api/dca/programs/list-dca-programs /data-api/dca/openapi.json get /dca/programs Returns supported recurring (DCA) programs. Each entry includes `id`, `label`, and on-chain `programId`. Today only Jupiter is available (`id`: `jupiter`). ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaPrograms(); ``` # Get DCA buyers for token Source: https://docs.solanatracker.io/data-api/dca/token/get-dca-buyers-for-token /data-api/dca/openapi.json get /dca/token/{mint}/buyers DCA orders **buying** this token (token is the output mint). May return 408 on timeout. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaTokenBuyers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { sort: 'volume', limit: 10 }); ``` # Get DCA sellers for token Source: https://docs.solanatracker.io/data-api/dca/token/get-dca-sellers-for-token /data-api/dca/openapi.json get /dca/token/{mint}/sellers DCA orders **selling** this token (token is the input mint). May return 408 on timeout. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaTokenSellers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { sort: 'volume', limit: 10 }); ``` # Get token DCA flow overview Source: https://docs.solanatracker.io/data-api/dca/token/get-token-dca-flow-overview /data-api/dca/openapi.json get /dca/token/{mint} Buy/sell flow overview for recurring orders involving this token. Results may be cached; may return 408 on timeout. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaTokenFlow('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Get top DCA users for token Source: https://docs.solanatracker.io/data-api/dca/token/get-top-dca-users-for-token /data-api/dca/openapi.json get /dca/token/{mint}/users Top wallets by DCA activity for this token. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaTokenUsers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { limit: 10 }); ``` # Get paginated wallet DCA orders Source: https://docs.solanatracker.io/data-api/dca/wallet/get-paginated-wallet-dca-orders /data-api/dca/openapi.json get /dca/wallet/{wallet}/orders Paginated list of DCA orders for a wallet. Order status values: | Status | Meaning | |--------|---------| | `active` | Recurring in progress — has fills and waiting for the next scheduled cycle, or due now | | `pending` | Funded but first cycle not run yet | | `paused` | Schedule paused on-chain or overdue well past 2× cycle frequency | | `completed` | No remaining input to spend | USD fields are included when price data is available; otherwise `*Usd` fields may be null or omitted. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaWalletOrders('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { sort: 'recent', limit: 10 }); ``` # Get wallet DCA orders Source: https://docs.solanatracker.io/data-api/dca/wallet/get-wallet-dca-orders /data-api/dca/openapi.json get /dca/wallet/{wallet} Returns all DCA orders for a wallet with a status summary. Order status values: | Status | Meaning | |--------|---------| | `active` | Recurring in progress — has fills and waiting for the next scheduled cycle, or due now | | `pending` | Funded but first cycle not run yet | | `paused` | Schedule paused on-chain or overdue well past 2× cycle frequency | | `completed` | No remaining input to spend | USD fields are included when price data is available; otherwise `*Usd` fields may be null or omitted. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getDcaWallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { status: 'active', limit: 25 }); ``` # Get Position Batch Lookup Source: https://docs.solanatracker.io/data-api/pnl-v2/batch/get-position-batch-lookup /data-api/pnl-v2/openapi.json post /v2/pnl/positions/batch Returns positions for arbitrary wallet and token pairs in a single request. Submit `{ wallet, token }` objects; unmatched pairs come back in `notFound`. Max 200 pairs. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.batchPnlV2PositionPairs([{ wallet: 'FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', token: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN' }]); ``` # Get Wallet Summaries Batch Source: https://docs.solanatracker.io/data-api/pnl-v2/batch/get-wallet-summaries-batch /data-api/pnl-v2/openapi.json post /v2/pnl/wallets/batch Returns wallet-level PnL summaries, resolved identity, and wallet tags for up to 100 unique wallets. Missing/non-indexed wallets are returned in `notFound`; invalid addresses are returned in `invalid`; requests above the limit are truncated and include a `truncated` object. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.batchPnlV2WalletSummaries(['FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF']); ``` # Get KOL Calendar Source: https://docs.solanatracker.io/data-api/pnl-v2/leaderboard/get-kol-calendar /data-api/pnl-v2/openapi.json get /v2/pnl/leaderboard/kols/calendar Returns one row per day for a given month with aggregate KOL realized PnL, volume, trade counts, and active wallet count. Useful for calendar and heatmap views. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2KOLCalendar({ year: 2025, month: 1 }); ``` # Get KOL Daily Breakdown Source: https://docs.solanatracker.io/data-api/pnl-v2/leaderboard/get-kol-daily-breakdown /data-api/pnl-v2/openapi.json get /v2/pnl/leaderboard/kols/date Returns per-KOL performance for a single trading day, including realized PnL, volume, trade counts, and cumulative totals as of that date. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2KOLByDate({ date: '2025-01-15' }); ``` # Get KOL Leaderboard for a Period Source: https://docs.solanatracker.io/data-api/pnl-v2/leaderboard/get-kol-leaderboard-for-a-period /data-api/pnl-v2/openapi.json get /v2/pnl/leaderboard/kols/period Ranks tracked KOL wallets inside a defined window. Use `period` for rolling windows like `7d` or `30d`, or `start` and `end` for explicit dates. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2KOLPeriodLeaderboard({ period: '7d', limit: 50 }); ``` # Solana Traders Leaderboard Source: https://docs.solanatracker.io/data-api/pnl-v2/leaderboard/solana-traders-leaderboard /data-api/pnl-v2/openapi.json get /v2/pnl/leaderboard/top Ranks Solana trading wallets by recent PnL performance over supported windows (`1`, `7`, `30`, or `90` days). Use filters to remove low-signal wallets, arbitrage wallets, and one-off winners. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2TopTraders({ limit: 50, pnlMode: 'strict' }); ``` # Get Token Batch Positions Source: https://docs.solanatracker.io/data-api/pnl-v2/token/get-token-batch-positions /data-api/pnl-v2/openapi.json post /v2/pnl/tokens/{token}/positions/batch Returns positions for multiple wallets on one token mint in a single request. Wallets with no matching position are returned in `notFound`. Max 200 wallets. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.batchPnlV2TokenWalletPositions('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', ['FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF']); ``` # Get Token First Buyers Source: https://docs.solanatracker.io/data-api/pnl-v2/token/get-token-first-buyers /data-api/pnl-v2/openapi.json get /v2/pnl/tokens/{token}/first-buyers Returns the same trader dataset as `/traders`, but only in chronological earliest-first order. Omit `sort` or use `sort=first_trade`, and use `direction=asc`. For ROI, PnL, position size, latest trade, or descending order, use `/v2/pnl/tokens/{token}/traders`. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2TokenFirstBuyers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { limit: 50 }); ``` # Get Token Traders Source: https://docs.solanatracker.io/data-api/pnl-v2/token/get-token-traders /data-api/pnl-v2/openapi.json get /v2/pnl/tokens/{token}/traders Returns wallets that traded the token, along with full position state: realized and unrealized PnL, remaining size, trade counts, and timing. Legacy fields (`wallet`, `pnl`, `position`, `buyUsd`, `sellUsd`, `counts`, `roi`, `timing.firstTrade`, `timing.lastTrade`) are unchanged. Additive fields (`invested`, `proceeds`, `volume`, `averages`, `current`, extended `timing`) align with `/v2/pnl/wallets/:wallet/positions` and `/tokens/:token/holders?enrich=walletPnl` for the same wallet-token pair. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2TokenTraders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { limit: 50 }); ``` # Get Wallet Batch Positions Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-batch-positions /data-api/pnl-v2/openapi.json post /v2/pnl/wallets/{wallet}/positions/batch Returns positions for one wallet across multiple token mints in a single request. Tokens with no matching position are returned in `notFound`. Max 100 tokens. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.batchPnlV2WalletTokenPositions('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', ['6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN']); ``` # Get Wallet Chart Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-chart /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/chart Returns daily time-series points for charting wallet PnL, volume, and activity. Supports backward pagination with `time_from` and `time_to` and includes a computed performance summary. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletChart('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { time_from: 1700000000, time_to: 1700086400 }); ``` # Get Wallet Highlights Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-highlights /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/highlights Returns the wallet's standout positions, such as biggest winner, biggest loser, largest current bag, fastest flip, longest hold, and most traded token. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletHighlights('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Performance Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-performance /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/performance Returns rolling performance stats for a wallet, including realized PnL, volume, streaks, drawdown, best day, worst day, and the underlying daily breakdown. Trade counts (`totals.trades` and per-day `trades`) reflect daily activity within the window (`day_buys + day_sells`), not cumulative lifetime totals. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletPerformance('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { period: '30d' }); ``` # Get Wallet PnL Calendar Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-pnl-calendar /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/history Returns daily wallet snapshots with cumulative PnL plus per-day realized PnL, volume, buy and sell counts, and averages. Use `period` for quick windows or `start` and `end` for exact ranges. Pass `?currency=sol` or `?currency=eur` to convert monetary fields at read time using historical daily reference rates. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletHistory('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { period: '30d' }); ``` # Get Wallet Positions Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-positions /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/positions Returns paginated token positions for a wallet. Each list item exposes the same trade-activity fields as `/v2/pnl/wallets/:wallet/tokens/:token` (`volume`, `counts`, `timing`, and related PnL fields). Supports sorting plus filters for holding state, PnL, ROI, invested capital, market, liquidity, market cap, and token list. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletPositions('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { limit: 50 }); ``` # Get Wallet Risk Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-risk /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/risk Returns risk metrics for current holdings, including portfolio concentration, realized versus unrealized mix, open exposure, and the largest live positions. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletRisk('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Summary Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-summary /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet} Returns the top-level trading summary for a wallet: total PnL, win rate, averages, counts, ROI buckets, platform tags, and `summary.timing.avgHoldTimeSecs`. Use `/positions` when you need per-token detail. Pass `?currency=sol` or `?currency=eur` to convert monetary fields at read time using current spot reference prices. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletOverview('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF'); ``` # Get Wallet Token Position Source: https://docs.solanatracker.io/data-api/pnl-v2/wallet/get-wallet-token-position /data-api/pnl-v2/openapi.json get /v2/pnl/wallets/{wallet}/tokens/{token} Returns the full position for one wallet-token pair, wrapped with the wallet address, resolved identity, and the applied `pnlMode`. ## SDK Example ```typescript import { Client } from '@solana-tracker/data-api'; const client = new Client({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlV2WalletTokenPosition('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN'); ``` # Risk Score Source: https://docs.solanatracker.io/data-api/risk How the Solana Tracker token risk score works — rug pull signals, freeze and mint authority checks, top holder concentration, and bundler detection. The Risk Score API evaluates token investment risk across multiple factors, generating a normalized score from 1-10 to help users make informed trading decisions on Solana. ## Risk Categories Risk factors are organized into four severity-based categories: Potential issues requiring attention but may have legitimate explanations Significant red flags indicating high risk or potential malicious activity Token liquidity and holder concentration issues Early buyer and insider wallet concentration risks ## Scoring Methodology Final risk scores are normalized to 1-10 based on the sum of individual risk factor weights. Higher scores indicate higher risk. The tables below show internal weights for each signal. The API combines those weights, then converts the total into the final 1-10 score. Treat the table scores as relative strength, not as the final user-facing score. ## Warning Risk Factors | Risk Factor | Description | Score | | - | - | - | | No social media | Token has no associated social media links | 2000 | | No file metadata | Token has no file metadata | 100 | | Pump.fun contract risks | Pump.fun contracts can be changed by Pump.fun at any time | 10 | | Incomplete bonding curve | No Raydium liquidity pool, bonding curve not complete | 4000 | | Transitioning to Raydium | Token is currently transitioning to Raydium | 100 | | Price decrease | Price decreased by more than 50% in the last 24 hours | 1000 | | Suspicious Volume | High percentage of buy transactions indicating possible manipulation. Score scales with severity. | 1000-10000 | ## Danger Risk Factors | Risk Factor | Description | Score | | - | - | - | | Freeze Authority Enabled | Tokens can be frozen and prevented from trading in the future | 7500 | | Mint Authority Enabled | More tokens can be minted by the owner at any time | 2500 | | Rugged | No liquidity remains, so Rugcheck considers the token unsafe to buy | 20000 | | LP not burned or not locked | Liquidity can still be removed by the owner or deployer | 4000 | ### Dynamic Fee Risk (Meteora Curve) | Fee Range | Level | Score | | - | - | - | | >5% | Danger | 1000 | | >10% | Danger | 1500 | | >20% | Danger | 3000 | | >40% | Danger | 4000 | | >50% | Danger | 5000 | | >75% | Danger | 7500 | ## Liquidity Risk Factors ### Liquidity Levels | Risk Factor | Description | Level | Score | | - | - | - | - | | Very Low Liquidity | The total liquidity for this token is very low | Danger | 7500 | | Low Liquidity | The total liquidity for this token is low | Warning | 5000 | ### Holders | Threshold | Level | Score | | - | - | - | | >90% | Danger | 7000 | | >80% | Danger | 6000 | | >70% | Danger | 4600 | | >60% | Danger | 4400 | | >50% | Danger | 4300 | | >40% | Danger | 4100 | | >30% | Danger | 3500 | | >20% | Danger | 2500 | | >10% | Danger | 2000 | | Risk Factor | Description | Level | Score | | - | - | - | - | | Top 10 Holders | Top 10 holders own more than 15% of the total supply | Danger | 5000 | ## Snipers and Insiders ### Snipers Risk Levels Wallets that bought tokens within the first few transactions or blocks: | Ownership Percentage | Level | Score | | - | - | - | | >50% | Danger | 10000 | | >30% | Danger | 6000 | | >20% | Danger | 4000 | | >10% | Warning | 3000 | ### Insiders Risk Levels Wallets potentially connected to token creators or team: | Ownership Percentage | Level | Score | | - | - | - | | >50% | Danger | 10000 | | >30% | Danger | 7000 | | >20% | Danger | 5000 | | >10% | Warning | 3000 | ### Bundlers Risk Levels Wallets that bundled tokens, meaning they bought in coordinated groups: | Count/Percentage | Level | Score | | - | - | - | | ≥1000 wallets | Danger | 15000 | | ≥500 wallets | Danger | 10000 | | ≥100 wallets | Warning | 5000 | | ≥1 wallet | Warning | 2000 | | Ownership Percentage | Level | Score | | - | - | - | | >50% | Danger | 15000 | | >30% | Danger | 10000 | | >15% | Danger | 7000 | | >5% | Warning | 3000 | ### Developer Holdings Risk Levels Wallets identified as belonging to the token developer or creator: | Ownership Percentage | Level | Score | | - | - | - | | >50% | Danger | 10000 | | >30% | Danger | 8000 | | >20% | Danger | 6000 | | >10% | Danger | 4000 | | >5% | Warning | 2500 | | >1% | Warning | 1000 | ## API Response Risk scores are returned on all `token` objects with enhanced snipers, insiders, bundlers, and developer data. ```json theme={null} { "risk": { "snipers": { "count": 5, "totalBalance": 50000000, "totalPercentage": 12.5, "wallets": [ { "address": "WalletAddress1...", "balance": 20000000, "percentage": 5.0 } ] }, "insiders": { "count": 3, "totalBalance": 30000000, "totalPercentage": 7.5, "wallets": [ { "address": "WalletAddress2...", "balance": 15000000, "percentage": 3.75 } ] }, "bundlers": { "count": 25, "totalBalance": 10000000, "totalPercentage": 2.5, "wallets": [ { "address": "BundleWallet1...", "balance": 500000, "percentage": 0.125 } ] }, "top10": 25.5, "dev": { "percentage": 15.0, "amount": 15000000 }, "rugged": false, "risks": [ { "name": "Snipers", "description": "Snipers own 12.50% of the total supply.", "value": "12.50%", "level": "warning", "score": 3000 }, { "name": "Bundler Holdings", "description": "Bundlers own 2.50% of the total supply.", "value": "2.50%", "level": "warning", "score": 3000 }, { "name": "Dev Holdings", "description": "Developer holds 15.00% of the total supply.", "value": "15.00%", "level": "danger", "score": 4000 }, { "name": "Bonding curve not complete", "description": "No raydium liquidity pool, bonding curve not complete", "level": "warning", "score": 4000 } ], "score": 5, "jupiterVerified": false } } ``` # Recent changes Source: https://docs.solanatracker.io/datastream/recent-changes New endpoints, added features, and fixes for Datastream. [View the full changelog](/changelog)
September 18, 2026
New Data API Datastream
## Swaps, LP moves, and wallet labels in one feed Track buys and sells alongside LP adds and removes. See which wallets are adding liquidity, which are pulling it, and where it all lands in your trade feed.
Updated trade feed with All, Swaps, and Liquidity tabs, green LP adds, red LP removes, and wallet labels.

After: swaps and LP activity in one feed, with wallet labels and All / Swaps / Liquidity filters.

Previous trade feed showing buys and sells with shortened wallet addresses.

Before: a swaps-only feed with wallet addresses.

* **Stream LP moves.** Five new liquidity room scopes: token, token + pool, token + pool + wallet, pool, or wallet. * **Build All / Swaps / Liquidity tabs.** Query `events=all`, `events=trades`, or `events=liquidity` on all four token trade endpoints. Set `limit` to load up to 500 rows per page. * **Put a name to the wallet.** Use `enrich=identity` on REST or `:enriched` on live rooms for available KOL profiles, dev labels, SNS names, and trading platforms. * **Keep LP amounts exact.** Adds and removes include the pool and each token's amount as a decimal string. Liquidity stays in token units, separate from swap volume. ```http theme={null} GET /trades/{token}?events=all&enrich=identity&limit=100 ``` ```json theme={null} { "type": "join", "room": "liquidity:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN:enriched" } ``` Load the history with REST, then keep the feed moving with Datastream. Existing trade requests and rooms remain swaps-only by default. Live LP events are provisional; use REST to reconcile confirmed activity. ### Changed endpoints and rooms
September 7–16, 2026
Data API Datastream Solana RPC PnL V2 General

Platform speed, Search API, RidgeDB, and dashboard updates

### Faster data, from indexing to delivery * **Search and holders:** faster Search API responses and improved holder data performance. * **Token coverage:** support for all quote tokens on Meteora Curve, Raydium LaunchLab, and Pump.fun, plus Pump.fun `isHolderReward` and Transaction V1 support. * **Indexing and streaming:** rebuilt metadata indexing, RidgeDB, and Ridge streaming for improved speed, accuracy, and efficiency across Data API and RPC services. * **PnL V2:** improved redundancy and accuracy. ### More ways to manage your subscription * **Teams:** invite teammates and manage their access on Premium, Business, and dedicated node plans. * **On-chain USDC subscriptions:** automatic renewals and top-ups using native USDC on Solana.
August 2026
Data API Datastream

See what whales and KOLs are trading as it happens

Know when high-value wallets move. New REST endpoints and Datastream rooms make it easy to follow whale activity, track KOL trades, power token pages, and trigger alerts from a single trade feed. * **REST endpoints:** Fetch the latest whale trades, all KOL trades, or KOL activity for a specific token. * **Live Datastream rooms:** Subscribe to whale and KOL trades as they happen. * **Flexible volume filters:** Watch trades from `$1k` to `$10k`, or request all eligible KOL trades with `minVolume=0`. * **KOL identity:** Show names, Twitter handles, and other identity metadata when available. * **More context when you need it:** Paginate with opaque cursors, add token metadata, and filter arbitrage activity when needed.
August 2026
Prediction Markets Datastream

Beta Prediction Markets API for Kalshi and Polymarket

Unified read-only API for **Kalshi** and **Polymarket** with full historical market data. * **REST:** `https://prediction-market-api.solanatracker.io` * **Datastream:** `pm:*` rooms on `wss://datastream.solanatracker.io/{apiKey}` (same hub and key as other Datastream products) * Markets, events, trades, candlesticks, orderbooks, crypto up/down windows, and Polymarket wallet analytics * Auth with your existing Data API key (`x-api-key`)
July 2026
Datastream

Meteora DLMM and Raydium CLMM pool monitors improved for new pool creations

Meteora DLMM and Raydium CLMM pool monitors have been improved for new pool creations.
June 2026
Data API Datastream

Jupiter DCA V2 — full support and indexing for recurring orders

Jupiter DCA V2 orders (`openDcaV2`) are now fully supported and indexed across the DCA API and Datastream feeds. Previously hidden DCA V2 positions are now visible in REST responses and live WebSocket events. Existing `/dca/*` endpoints and `dca:jupiter` rooms automatically include V2 orders — no query changes required. Order objects include `openInstruction: "openDcaV2"` to distinguish V2 accounts.
# All events Source: https://docs.solanatracker.io/datastream/websockets/allevents Every non-market-state realtime event (trades, crypto_price, lifecycle/resolution). Does not include high-frequency prices/quotes/orderbook/volume. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # All trades Source: https://docs.solanatracker.io/datastream/websockets/alltrades Full trade tape across Kalshi and Polymarket. Recommended hub feed. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.trades().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Bundlers Source: https://docs.solanatracker.io/datastream/websockets/bundlers Stream bundler wallet activity for a Solana token over Datastream WebSocket to detect coordinated trading and bundle buys in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.bundlers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Curve percentage Source: https://docs.solanatracker.io/datastream/websockets/curvepercentage Subscribe to Solana bonding curve percentage alerts on Datastream WebSocket and trigger actions when tokens hit specific curve thresholds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.curvePercentage('pumpfun', 50).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # All Events Source: https://docs.solanatracker.io/datastream/websockets/dcajupiter Subscribe to every Jupiter DCA event on one Datastream WebSocket channel: opens, fills, deposits, withdrawals, closes, and position snapshots. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # By Account Source: https://docs.solanatracker.io/datastream/websockets/dcajupiteraccount Subscribe to every Jupiter DCA event for a specific DCA account address over Datastream WebSocket: opens, fills, deposits, withdraws, and closes. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.order('125PQmudTAXHUUGxtSra1xTzGu3NRCMbRU7i9cikEpwd').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Order Closed Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterclosed Stream Jupiter DCA position close events live over Datastream WebSocket to track when recurring orders end across all DCA accounts on Solana. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.closed().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Fee Collected Source: https://docs.solanatracker.io/datastream/websockets/dcajupitercollectedfee Subscribe to Jupiter DCA fee collection events on Datastream WebSocket to monitor protocol fees paid by recurring buy orders across Solana. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.collectedFee().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Deposit Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterdeposit Stream Jupiter DCA deposit events over Datastream WebSocket to track funds added to existing recurring orders across all DCA accounts on Solana. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.deposit().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Order Filled Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterfilled Stream Jupiter DCA cycle fill events over Datastream WebSocket to track each scheduled buy executed by recurring orders across Solana in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.filled().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Buyers by Token Source: https://docs.solanatracker.io/datastream/websockets/dcajupitermintbuyers Stream Jupiter DCAs buying a specific Solana token (output mint) over Datastream WebSocket to power token terminal buyer feeds and analytics. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').buyers().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Sellers by Token Source: https://docs.solanatracker.io/datastream/websockets/dcajupitermintsellers Stream Jupiter DCAs selling a specific Solana token (input mint) over Datastream WebSocket to power token terminal seller feeds and analytics. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').sellers().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Order Opened Source: https://docs.solanatracker.io/datastream/websockets/dcajupiteropened Stream newly created Jupiter DCA recurring orders (openDca and openDcaV2) over Datastream WebSocket to detect fresh DCAs as they launch on Solana. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.opened().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Position Updates Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterposition Stream Jupiter DCA position account snapshots over Datastream WebSocket — throttled live updates with order state but no signature or eventName. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.position().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # By Wallet Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterwallet Subscribe to every Jupiter DCA event for a specific wallet owner over Datastream WebSocket: opens, deposits, fills, withdraws, and closes in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Withdraw Source: https://docs.solanatracker.io/datastream/websockets/dcajupiterwithdraw Stream Jupiter DCA withdrawal events over Datastream WebSocket to track funds removed from recurring orders across all DCA accounts on Solana. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.dca.withdraw().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Developer holdings Source: https://docs.solanatracker.io/datastream/websockets/developerholdings Subscribe to Solana token developer wallet holdings changes over Datastream WebSocket to detect dev sells, transfers, and balance shifts in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').dev.holding().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Event trades Source: https://docs.solanatracker.io/datastream/websockets/eventtrades Trades for all markets under one event (requires eventId/eventTicker on the trade payload). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.event('kalshi', 'EVENT_TICKER').trades().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Event volume Source: https://docs.solanatracker.io/datastream/websockets/eventvolume Live cumulative USD volume for an event (crypto 5m windows use the event slug). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.event('kalshi', 'EVENT_TICKER').volume().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Exchange lifecycle Source: https://docs.solanatracker.io/datastream/websockets/exchangelifecycle Lifecycle channel scoped to one exchange (typically kalshi). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.exchange('kalshi').marketLifecycle().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Exchange resolution Source: https://docs.solanatracker.io/datastream/websockets/exchangeresolution Resolution channel scoped to one exchange (typically kalshi). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.exchange('kalshi').resolution().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Exchange trades Source: https://docs.solanatracker.io/datastream/websockets/exchangetrades Trade tape for one exchange (pm:kalshi:trades or pm:polymarket:trades). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.exchange('kalshi').trades().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Fee tracking Source: https://docs.solanatracker.io/datastream/websockets/feetracking Stream global Solana token fee tracking over Datastream WebSocket to monitor trading fee accruals and revenue events live across pools. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').fees().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Graduated Source: https://docs.solanatracker.io/datastream/websockets/graduated Stream tokens that just graduated from bonding curves over Datastream WebSocket to detect Pump.fun and other launchpad graduations as they happen. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.graduated().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Graduating Source: https://docs.solanatracker.io/datastream/websockets/graduating Stream tokens approaching bonding curve completion over Datastream WebSocket to catch graduating tokens before they migrate to a Solana DEX. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.graduating(500).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Holders Source: https://docs.solanatracker.io/datastream/websockets/holders Subscribe to Solana token holder count changes over Datastream WebSocket to track holder growth, churn, and distribution shifts in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.holders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Insider tracking Source: https://docs.solanatracker.io/datastream/websockets/insidertracking Stream Solana insider wallet balance and percentage changes for a token over Datastream WebSocket to detect dev and team holding shifts live. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.insiders('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Kol trades Source: https://docs.solanatracker.io/datastream/websockets/koltrades All spot trades from wallets on the shared KOL roster, regardless of USD volume. One trade object per swap. Includes `identity` when available. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.kol(undefined, { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Kol trades by volume Source: https://docs.solanatracker.io/datastream/websockets/koltradesbyvolume Cumulative high-volume KOL trade rooms. Same thresholds and fan-out as `transaction:whale:{volume}`. Volumes below $1,000 are excluded from these volume rooms (they still appear on `transaction:kol`). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.kol(1000, { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Latest tokens Source: https://docs.solanatracker.io/datastream/websockets/latesttokens Subscribe to brand-new tokens and pools created on Solana over Datastream WebSocket to catch fresh launches from Pump.fun, Raydium, and more. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.latest().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Liquidity pool Source: https://docs.solanatracker.io/datastream/websockets/liquiditypool Liquidity actions in one pool, across its tokens. Room: `liquidity:pool:{pool}`. Append `:enriched` for current wallet identity. Events are provisional at processed commitment; overlapping rooms can deliver the same action more than once. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.liquidity.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Liquidity token Source: https://docs.solanatracker.io/datastream/websockets/liquiditytoken All liquidity actions involving this token. Room: `liquidity:{mint}`. Append `:enriched` for current wallet identity. Events are provisional at processed commitment; overlapping rooms can deliver the same action more than once. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.liquidity.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Liquidity token pool Source: https://docs.solanatracker.io/datastream/websockets/liquiditytokenpool Liquidity actions for a token in one pool. Room: `liquidity:{mint}:{pool}`. Append `:enriched` for current wallet identity. Events are provisional at processed commitment; overlapping rooms can deliver the same action more than once. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.liquidity.tokenPool('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Liquidity token pool wallet Source: https://docs.solanatracker.io/datastream/websockets/liquiditytokenpoolwallet Liquidity actions by one wallet for a token in one pool. Room: `liquidity:{mint}:{pool}:{wallet}`. Append `:enriched` for current wallet identity. Events are provisional at processed commitment; overlapping rooms can deliver the same action more than once. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.liquidity.tokenPoolWallet('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', 'FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Liquidity wallet Source: https://docs.solanatracker.io/datastream/websockets/liquiditywallet Liquidity actions by one wallet, across pools and tokens. Room: `liquidity:wallet:{wallet}`. Append `:enriched` for current wallet identity. Events are provisional at processed commitment; overlapping rooms can deliver the same action more than once. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.liquidity.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market lifecycle Source: https://docs.solanatracker.io/datastream/websockets/marketlifecycle Broad Kalshi lifecycle channel (opened/closed/suspended). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.marketLifecycle().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market orderbook Source: https://docs.solanatracker.io/datastream/websockets/marketorderbook Full orderbook snapshots for one market/token. Market-scoped only. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').orderbook().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market prices Source: https://docs.solanatracker.io/datastream/websockets/marketprices Live top-of-book mid (+ displayPrice). Market-scoped only — there is no pm:prices firehose. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').prices().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market quotes Source: https://docs.solanatracker.io/datastream/websockets/marketquotes Streaming size-aware VWAP quote ladder (Polymarket). REST: GET /v1/markets/{id}/quote. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').quotes().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market trades Source: https://docs.solanatracker.io/datastream/websockets/markettrades Single-market trade tape. Polymarket marketId must be the CLOB token id. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').trades().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market volume Source: https://docs.solanatracker.io/datastream/websockets/marketvolume Live cumulative USD volume for one outcome token/market. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').volume().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Metadata Source: https://docs.solanatracker.io/datastream/websockets/metadata Stream Solana token metadata updates (name, symbol, image, socials) over Datastream WebSocket to keep token info current as projects update. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.metadata('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool statistics Source: https://docs.solanatracker.io/datastream/websockets/poolstatistics Subscribe to multi-timeframe pool statistics (price, volume, txns, buyers) over Datastream WebSocket for live Solana DEX pool analytics. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.stats.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool statistics total Source: https://docs.solanatracker.io/datastream/websockets/poolstatisticstotal Subscribe to total all-time pool statistics over Datastream WebSocket to track cumulative volume, txn counts, and traders for any Solana pool. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.stats.total.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool transactions Source: https://docs.solanatracker.io/datastream/websockets/pooltransactions Stream live swap transactions for a specific Solana token in a specific pool over Datastream WebSocket — ideal for per-pool trade feeds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.pool('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool updates Source: https://docs.solanatracker.io/datastream/websockets/poolupdates Subscribe to Solana DEX pool updates (price, liquidity, reserves) over Datastream WebSocket for live state changes on a specific pool address. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool volume Source: https://docs.solanatracker.io/datastream/websockets/poolvolume Subscribe to live pool volume updates for any Solana DEX pool over Datastream WebSocket to power real-time volume charts and trading dashboards. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.volume.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Pool wallet transactions Source: https://docs.solanatracker.io/datastream/websockets/poolwallettransactions Stream live swap transactions for a specific wallet in a specific Solana pool over Datastream WebSocket to track wallet-level pool activity. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.poolWallet('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', '9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2', 'FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Price aggregated Source: https://docs.solanatracker.io/datastream/websockets/priceaggregated Stream aggregated price updates across all pools for a Solana token over Datastream WebSocket for unified, volume-weighted price feeds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.price.aggregated('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Price all pools Source: https://docs.solanatracker.io/datastream/websockets/priceallpools Stream price updates for a Solana token across every pool it trades in over Datastream WebSocket for full multi-pool live price coverage. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.price.allPoolsForToken('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Price by pool Source: https://docs.solanatracker.io/datastream/websockets/pricebypool Stream live price updates for a specific Solana DEX pool over Datastream WebSocket to power per-pool charts and pool-level trading alerts. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.price.pool('9d9mb8kooFfaD3SctgZtkxQypkshx6ezhbKio89ixyy2').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Price by token Source: https://docs.solanatracker.io/datastream/websockets/pricebytoken Stream live price updates for a Solana token from its primary (highest-liquidity) pool over Datastream WebSocket for fast single-token price feeds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.price.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Resolution Source: https://docs.solanatracker.io/datastream/websockets/resolution Broad Kalshi resolution channel. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.resolution().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Significant trades Source: https://docs.solanatracker.io/datastream/websockets/significanttrades Executed trades with notionalUsd (price × quantity) ≥ 25. Hub sidebars / large-print feeds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.significantTrades().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Single market lifecycle Source: https://docs.solanatracker.io/datastream/websockets/singlemarketlifecycle Kalshi market lifecycle updates (opened/closed/suspended) for one ticker. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').marketLifecycle().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Single market resolution Source: https://docs.solanatracker.io/datastream/websockets/singlemarketresolution Kalshi resolution updates for one ticker. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').resolution().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Sniper tracking Source: https://docs.solanatracker.io/datastream/websockets/snipertracking Stream sniper wallet balance and percentage changes for a Solana token over Datastream WebSocket to monitor early buyers and snipe activity live. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.snipers('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token changes Source: https://docs.solanatracker.io/datastream/websockets/tokenchanges Subscribe to every pool change for a Solana token over Datastream WebSocket to capture price, liquidity, and stats updates across all its pools. `tokenSupply` on each pool object is the **total on-chain supply** of the token mint (i.e. `mint.supply` adjusted for `decimals`), not a circulating supply estimate. It is what's used together with `price.usd` to derive `marketCap.usd`, so `marketCap.usd` here is fully diluted market cap. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token position Source: https://docs.solanatracker.io/datastream/websockets/tokenposition Stream real-time PnL updates for a single token position in a Solana wallet over Datastream WebSocket via tradeUpdate and balanceUpdate events. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pnl.position('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token primary Source: https://docs.solanatracker.io/datastream/websockets/tokenprimary Stream updates from a Solana token's primary (highest-liquidity) pool over Datastream WebSocket for the canonical price and volume feed. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').primary().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token statistics Source: https://docs.solanatracker.io/datastream/websockets/tokenstatistics Subscribe to multi-timeframe token statistics (price, volume, txns, holders) over Datastream WebSocket for live Solana token analytics dashboards. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.stats.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token statistics total Source: https://docs.solanatracker.io/datastream/websockets/tokenstatisticstotal Subscribe to total all-time token statistics over Datastream WebSocket to track cumulative volume, txns, holders, and traders for any Solana token. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.stats.total.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token transactions Source: https://docs.solanatracker.io/datastream/websockets/tokentransactions Stream live swap transactions for any Solana token across every pool over Datastream WebSocket for real-time trade feeds and trading bot triggers. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Token volume Source: https://docs.solanatracker.io/datastream/websockets/tokenvolume Subscribe to live Solana token volume updates over Datastream WebSocket to power real-time volume charts, trending boards, and momentum signals. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.volume.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Top10 holders Source: https://docs.solanatracker.io/datastream/websockets/top10holders Stream top-10 holder percentage changes for a Solana token over Datastream WebSocket to monitor concentration risk and whale activity in real time. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').top10().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Wallet balance Source: https://docs.solanatracker.io/datastream/websockets/walletbalance Subscribe to Solana wallet SOL balance changes over Datastream WebSocket for live wallet tracking, alerting, and portfolio monitoring dashboards. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF').balance().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Wallet positions Source: https://docs.solanatracker.io/datastream/websockets/walletpositions Stream real-time PnL updates for every token a Solana wallet holds over Datastream WebSocket via tradeUpdate and balanceUpdate events per token. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pnl.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Wallet summary Source: https://docs.solanatracker.io/datastream/websockets/walletsummary Stream aggregated wallet-level PnL totals — counts, averages, open positions, ROI, and timing — for a Solana wallet over Datastream WebSocket live. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pnl.summary('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Wallet token balance Source: https://docs.solanatracker.io/datastream/websockets/wallettokenbalance Subscribe to a specific token balance change for a Solana wallet over Datastream WebSocket for granular per-token holding alerts and updates. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF').tokenBalance('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Wallet transactions Source: https://docs.solanatracker.io/datastream/websockets/wallettransactions Stream live swap transactions for a Solana wallet over Datastream WebSocket to power copy trading, wallet tracking, and on-chain trade feeds. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.wallet('FbMxP3GVq8TQ36nbYgx4NP9iygMpwAwFWJwW81ioCiSF', { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Whale trades Source: https://docs.solanatracker.io/datastream/websockets/whaletrades Cumulative high-volume spot trade rooms. A trade is published to every room whose tier it meets. Example: a $12,000 trade is sent to `transaction:whale:1000`, `:2500`, `:5000`, and `:10000`. Volumes below $1,000 are excluded. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.tx.whale(5000, { enriched: true }).on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Category feed Source: https://docs.solanatracker.io/datastream/websockets/categoryfeed Trades (and other non-state events) when the payload includes category/categorySlug (enriched feeds). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.category('crypto').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Crypto underlying Source: https://docs.solanatracker.io/datastream/websockets/cryptounderlying Live Chainlink underlying USD ticks for crypto up/down charts (btc, eth, …). Isolated from probability price rooms. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.crypto('btc').all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Crypto underlying prices Source: https://docs.solanatracker.io/datastream/websockets/cryptounderlyingprices Same Chainlink ticks as pm:crypto:{asset}, explicitly scoped to the prices channel. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.crypto('btc').prices().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Event feed Source: https://docs.solanatracker.io/datastream/websockets/eventfeed Non-state updates for an event (typically trades). Volume uses the :volume suffix room only. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.event('kalshi', 'EVENT_TICKER').all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Event type feed Source: https://docs.solanatracker.io/datastream/websockets/eventtypefeed Events of one type across exchanges (trade, crypto_price, market_opened, resolved, …). Does not receive market-state prices/quotes/orderbook/volume. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.type('trade').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Exchange event type feed Source: https://docs.solanatracker.io/datastream/websockets/exchangeeventtypefeed One event type scoped to one exchange. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.exchange('kalshi').type('trade').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Exchange feed Source: https://docs.solanatracker.io/datastream/websockets/exchangefeed Non-market-state events for one exchange (trades, crypto_price, lifecycle). Not a prices firehose. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.exchange('kalshi').all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Market feed Source: https://docs.solanatracker.io/datastream/websockets/marketfeed Non-state updates for one market (trades/lifecycle). Does not receive prices/quotes/orderbook/volume — join the :{channel} rooms for those. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.market('kalshi', 'MARKET_TICKER').all().on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Series feed Source: https://docs.solanatracker.io/datastream/websockets/seriesfeed Published only when the payload includes seriesId/seriesTicker (common on Kalshi trades). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.series('kalshi', 'SERIES_TICKER').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Sport feed Source: https://docs.solanatracker.io/datastream/websockets/sportfeed Published only when the payload includes sport/sportSlug. Not used for prices/orderbook/volume. ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.sport('basketball').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Status feed Source: https://docs.solanatracker.io/datastream/websockets/statusfeed Lifecycle feed when payload includes status (active, closed, settled, suspended, resolved). ## SDK Example ```typescript theme={null} import { Datastream } from '@solana-tracker/data-api'; const dataStream = new Datastream({ wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY', }); dataStream.on('error', console.error); await dataStream.connect(); const sub = dataStream.subscribe.pm.status('active').on((data) => { console.log(data); }); // sub.unsubscribe(); ``` # Canonical wallet overview (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/canonical-wallet-overview-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/overview Returns lifecycle-aware positions and counts, authoritative marks and settlement values, FIFO PnL, portfolio value, and recent trades enriched with the same canonical market metadata as /v1/markets/batch. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountOverview('0xYOUR_POLYMARKET_WALLET'); ``` # Closed or resolved positions (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/closed-or-resolved-positions-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/closed-positions ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountClosedPositions('0xYOUR_POLYMARKET_WALLET'); ``` # Fast authoritative wallet PnL chart Source: https://docs.solanatracker.io/prediction-markets/accounts/fast-authoritative-wallet-pnl-chart /prediction-markets/openapi.json get /v1/accounts/{address}/pnl/chart Reads precomputed hourly authoritative PnL snapshots. Daily, weekly, and monthly points are last-value rollups and never scan raw fills. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountPnlChart('0xYOUR_POLYMARKET_WALLET'); ``` # Open positions (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/open-positions-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/positions ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountPositions('0xYOUR_POLYMARKET_WALLET'); ``` # Portfolio value (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/portfolio-value-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/value ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountValue('0xYOUR_POLYMARKET_WALLET'); ``` # Search Polymarket traders Source: https://docs.solanatracker.io/prediction-markets/accounts/search-polymarket-traders /prediction-markets/openapi.json get /v1/traders/search Search Polymarket traders by wallet address, address prefix, @username, display name, or X handle. Joins leaderboard stats when available. Kalshi has no public wallet identities. Cursor is an opaque keyset token. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.searchTraders({ q: 'trader', limit: 10 }); ``` # Wallet activity feed (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/wallet-activity-feed-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/activity ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountActivity('0xYOUR_POLYMARKET_WALLET'); ``` # Wallet PnL by event (Polymarket, FIFO) Source: https://docs.solanatracker.io/prediction-markets/accounts/wallet-pnl-by-event-polymarket-fifo /prediction-markets/openapi.json get /v1/accounts/{address}/pnl/events ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountPnlEvents('0xYOUR_POLYMARKET_WALLET'); ``` # Wallet PnL summary (Polymarket, FIFO) Source: https://docs.solanatracker.io/prediction-markets/accounts/wallet-pnl-summary-polymarket-fifo /prediction-markets/openapi.json get /v1/accounts/{address}/pnl ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountPnl('0xYOUR_POLYMARKET_WALLET'); ``` # Wallet trade history (Polymarket) Source: https://docs.solanatracker.io/prediction-markets/accounts/wallet-trade-history-polymarket /prediction-markets/openapi.json get /v1/accounts/{address}/trades ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getAccountTrades('0xYOUR_POLYMARKET_WALLET'); ``` # Crypto up/down page bundle Source: https://docs.solanatracker.io/prediction-markets/crypto/crypto-updown-page-bundle /prediction-markets/openapi.json get /v1/events/{event_id}/crypto For Polymarket Chainlink up/down events (e.g. btc-updown-5m-*), returns Price to Beat, final/live price, underlying chart history, phase, and sibling series windows for the interval strip. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventCrypto('EVENT_TICKER'); ``` # Crypto window open/close oracle price Source: https://docs.solanatracker.io/prediction-markets/crypto/crypto-window-openclose-oracle-price /prediction-markets/openapi.json get /v1/crypto/price Proxies Polymarket Chainlink openPrice/closePrice for a crypto up/down window (Price to Beat + Final Price). ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCryptoPrice({ symbol: 'BTC', eventStartTime: '2026-09-18T12:00:00Z', endDate: '2026-09-18T12:05:00Z' }); ``` # List crypto up/down series events Source: https://docs.solanatracker.io/prediction-markets/crypto/list-crypto-updown-series-events /prediction-markets/openapi.json get /v1/crypto/events Lists recurring Polymarket Chainlink up/down windows for an asset/interval series (e.g. BTC 5m). Each event includes `cryptoUpDown` metadata. Proxies Gamma `series_slug` ordering by window start. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCryptoEvents(); ``` # Top traders across crypto events Source: https://docs.solanatracker.io/prediction-markets/crypto/top-traders-across-crypto-events /prediction-markets/openapi.json get /v1/crypto/traders Ranks Polymarket wallets by estimated mark-to-market P&L across all indexed BTC, ETH, SOL, XRP, DOGE, BNB, and HYPE Up/Down events. Intended for wallet discovery and copy-trading research. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCryptoTraders(); ``` # Underlying crypto price chart series Source: https://docs.solanatracker.io/prediction-markets/crypto/underlying-crypto-price-chart-series /prediction-markets/openapi.json get /v1/crypto/price-history Returns Chainlink-derived price points for the window chart (timestamp ms + value). ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCryptoPriceHistory({ symbol: 'BTC', eventStartTime: '2026-09-18T12:00:00Z', endDate: '2026-09-18T12:05:00Z' }); ``` # Batch fetch events by id Source: https://docs.solanatracker.io/prediction-markets/events/batch-fetch-events-by-id /prediction-markets/openapi.json get /v1/events/batch ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventsBatch({ ids: 'EVENT_TICKER', exchange: 'kalshi' }); ``` # Get grouped event with nested markets Source: https://docs.solanatracker.io/prediction-markets/events/get-grouped-event-with-nested-markets /prediction-markets/openapi.json get /v1/events/{event_id} Returns a single event with nested markets. Polymarket combo-enabled sports events include comboEnabled=true and typed comboGroups containing the exact market lines and selectable outcomes needed by a combo-builder UI. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEvent('EVENT_TICKER'); ``` # List grouped events Source: https://docs.solanatracker.io/prediction-markets/events/list-grouped-events /prediction-markets/openapi.json get /v1/events Returns Kalshi events and Polymarket Gamma events. Use marketKind=combo to discover combo-builder events. Event detail exposes typed comboGroups with sections, periods, lines, selectable outcomes, prices, and CLOB token IDs. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEvents(); ``` # Multi-series OHLCV for grouped Polymarket event Source: https://docs.solanatracker.io/prediction-markets/events/multi-series-ohlcv-for-grouped-polymarket-event /prediction-markets/openapi.json get /v1/events/{event_id}/candlesticks Returns one candle series per market in a grouped Polymarket event (e.g. each World Cup country option). Each series includes groupItemTitle, market title, and OHLCV bars normalized to Yes-token prices. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventCandlesticks('EVENT_TICKER'); ``` # Top holders for an event Source: https://docs.solanatracker.io/prediction-markets/events/top-holders-for-an-event /prediction-markets/openapi.json get /v1/events/{event_id}/holders Largest open positions across every outcome token in the event (including crypto up/down windows). Aggregates net tokens from the Polymarket asset trader rollup. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventHolders('EVENT_TICKER'); ``` # Top traders for an event Source: https://docs.solanatracker.io/prediction-markets/events/top-traders-for-an-event /prediction-markets/openapi.json get /v1/events/{event_id}/traders Ranks Polymarket wallets by mark-to-market total P&L across every outcome token in the event. Works for regular events and crypto up/down windows. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventTraders('EVENT_TICKER'); ``` # Exchange connectivity status Source: https://docs.solanatracker.io/prediction-markets/exchange/exchange-connectivity-status /prediction-markets/openapi.json get /v1/exchange/status ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getExchangeStatus(); ``` # Exchange trading schedule Source: https://docs.solanatracker.io/prediction-markets/exchange/exchange-trading-schedule /prediction-markets/openapi.json get /v1/exchange/schedule ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getExchangeSchedule(); ``` # Top Polymarket traders by cumulative volume Source: https://docs.solanatracker.io/prediction-markets/leaderboard/top-polymarket-traders-by-cumulative-volume /prediction-markets/openapi.json get /v1/leaderboard/traders Global wallet ranking backed by a refreshable serving snapshot. Includes public Polymarket username, cumulative volume, and FIFO PnL fields. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTraderLeaderboard(); ``` # Top wallets by FIFO PnL Source: https://docs.solanatracker.io/prediction-markets/leaderboard/top-wallets-by-fifo-pnl /prediction-markets/openapi.json get /v1/leaderboard/pnl ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getPnlLeaderboard(); ``` # Top wallets by FIFO PnL on an event Source: https://docs.solanatracker.io/prediction-markets/leaderboard/top-wallets-by-fifo-pnl-on-an-event /prediction-markets/openapi.json get /v1/events/{event_id}/leaderboard/pnl ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getEventPnlLeaderboard('EVENT_TICKER'); ``` # Batch fetch candlesticks Source: https://docs.solanatracker.io/prediction-markets/markets/batch-fetch-candlesticks /prediction-markets/openapi.json get /v1/markets/candlesticks/batch ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCandlesticksBatch({ tickers: 'MARKET_TICKER', exchange: 'kalshi', period_interval: '1h' }); ``` # Batch fetch markets by id Source: https://docs.solanatracker.io/prediction-markets/markets/batch-fetch-markets-by-id /prediction-markets/openapi.json get /v1/markets/batch ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketsBatch({ ids: 'MARKET_TICKER', exchange: 'kalshi' }); ``` # Batch fetch markets by id (POST body) Source: https://docs.solanatracker.io/prediction-markets/markets/batch-fetch-markets-by-id-post-body /prediction-markets/openapi.json post /v1/markets/batch Same behavior as GET /v1/markets/batch, with ids in the JSON body (preferred for long id lists). Always returns { results, notFound }. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.postMarketsBatch({ ids: ['MARKET_TICKER'], exchange: 'kalshi' }); ``` # Batch fetch orderbooks Source: https://docs.solanatracker.io/prediction-markets/markets/batch-fetch-orderbooks /prediction-markets/openapi.json get /v1/markets/books ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketBooks({ tickers: 'MARKET_TICKER', exchange: 'kalshi' }); ``` # Bid-ask spread Source: https://docs.solanatracker.io/prediction-markets/markets/bid-ask-spread /prediction-markets/openapi.json get /v1/markets/{ticker}/spread ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketSpread('MARKET_TICKER'); ``` # Bundled market snapshot Source: https://docs.solanatracker.io/prediction-markets/markets/bundled-market-snapshot /prediction-markets/openapi.json get /v1/markets/{ticker}/snapshot Returns market plus optional sections. Default include is lean: price,midpoint. Pass include=all or an explicit list for the full bundle. Sets X-Cache header. Path {ticker} accepts Kalshi ticker or Polymarket condition_id (CLOB token ids for some book endpoints). ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketSnapshot('MARKET_TICKER'); ``` # Bundled market snapshot by slug Source: https://docs.solanatracker.io/prediction-markets/markets/bundled-market-snapshot-by-slug /prediction-markets/openapi.json get /v1/markets/slug/{slug}/snapshot Returns market plus optional sections. Default include is lean: price,midpoint. Pass include=all or an explicit list for the full bundle. Sets X-Cache header. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketSnapshotBySlug('MARKET_SLUG'); ``` # Current price snapshot Source: https://docs.solanatracker.io/prediction-markets/markets/current-price-snapshot /prediction-markets/openapi.json get /v1/markets/{ticker}/price ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketPrice('MARKET_TICKER'); ``` # Get market by slug Source: https://docs.solanatracker.io/prediction-markets/markets/get-market-by-slug /prediction-markets/openapi.json get /v1/markets/slug/{slug} ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketBySlug('MARKET_SLUG'); ``` # Get market by ticker or condition id Source: https://docs.solanatracker.io/prediction-markets/markets/get-market-by-ticker-or-condition-id /prediction-markets/openapi.json get /v1/markets/{ticker} ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarket('MARKET_TICKER'); ``` # List markets Source: https://docs.solanatracker.io/prediction-markets/markets/list-markets /prediction-markets/openapi.json get /v1/markets ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarkets(); ``` # Market trade history Source: https://docs.solanatracker.io/prediction-markets/markets/market-trade-history /prediction-markets/openapi.json get /v1/markets/{ticker}/trades ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketTrades('MARKET_TICKER'); ``` # Midpoint price Source: https://docs.solanatracker.io/prediction-markets/markets/midpoint-price /prediction-markets/openapi.json get /v1/markets/{ticker}/midpoint ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketMidpoint('MARKET_TICKER'); ``` # Newest markets Source: https://docs.solanatracker.io/prediction-markets/markets/newest-markets /prediction-markets/openapi.json get /v1/markets/new ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getNewMarkets(); ``` # OHLCV candlesticks Source: https://docs.solanatracker.io/prediction-markets/markets/ohlcv-candlesticks /prediction-markets/openapi.json get /v1/markets/{ticker}/candlesticks ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketCandlesticks('MARKET_TICKER'); ``` # Open interest and holder stats Source: https://docs.solanatracker.io/prediction-markets/markets/open-interest-and-holder-stats /prediction-markets/openapi.json get /v1/markets/{ticker}/oi ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketOpenInterest('MARKET_TICKER'); ``` # Orderbook snapshot Source: https://docs.solanatracker.io/prediction-markets/markets/orderbook-snapshot /prediction-markets/openapi.json get /v1/markets/{ticker}/orderbook ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketOrderbook('MARKET_TICKER'); ``` # Related markets on other exchange Source: https://docs.solanatracker.io/prediction-markets/markets/related-markets-on-other-exchange /prediction-markets/openapi.json get /v1/markets/{ticker}/related ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getRelatedMarkets('MARKET_TICKER'); ``` # Search markets Source: https://docs.solanatracker.io/prediction-markets/markets/search-markets /prediction-markets/openapi.json get /v1/markets/search Indexed relevance-ranked search across both exchanges. Default sort is relevance (exact id/ticker/slug, prefix, all-token substring, fuzzy n-gram, then 24h volume). Cursor is an opaque keyset token (breaking change vs numeric offsets). ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.searchMarkets({ q: 'Bitcoin', limit: 10 }); ``` # Size-aware VWAP quote (walk the book) Source: https://docs.solanatracker.io/prediction-markets/markets/size-aware-vwap-quote-walk-the-book /prediction-markets/openapi.json get /v1/markets/{ticker}/quote Walks the live orderbook for a stake size. Buy walks asks; sell walks bids. Use for TradePanel fill estimates. Top-of-book chance remains on `/price` and WS `…:prices`. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketQuote('MARKET_TICKER'); ``` # Top holders (Polymarket only) Source: https://docs.solanatracker.io/prediction-markets/markets/top-holders-polymarket-only /prediction-markets/openapi.json get /v1/markets/{ticker}/holders ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketHolders('MARKET_TICKER'); ``` # Top traders on a market by total P&L Source: https://docs.solanatracker.io/prediction-markets/markets/top-traders-on-a-market-by-total-p&l /prediction-markets/openapi.json get /v1/markets/{ticker}/traders Polymarket returns a fast paginated trader leaderboard (`PaginatedMarketTraders`) sorted by market-specific `totalPnlUsd` descending, with persisted public usernames when available. Kalshi returns aggregate `MarketTradeSummary` instead. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMarketTradersByExchange('MARKET_TICKER', { exchange: 'kalshi' }); ``` # Trending markets by 24h volume and trade count Source: https://docs.solanatracker.io/prediction-markets/markets/trending-markets-by-24h-volume-and-trade-count /prediction-markets/openapi.json get /v1/markets/trending ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getTrendingMarkets(); ``` # Unified typeahead search (markets + events) Source: https://docs.solanatracker.io/prediction-markets/markets/unified-typeahead-search-markets-+-events /prediction-markets/openapi.json get /v1/search Indexed relevance-ranked search across Kalshi and Polymarket markets and events, plus Polymarket traders. Prefer this for search UIs. Cursor pagination is not used here (typeahead). Trader identity is Polymarket-only. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.search({ q: 'Bitcoin' }); ``` # Browse hub bootstrap Source: https://docs.solanatracker.io/prediction-markets/meta/browse-hub-bootstrap /prediction-markets/openapi.json get /v1/browse Single call for above-the-fold browse data: platform stats, exchange status, categories, trending markets, and recent trades. ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getBrowseHub(); ``` # Event/sports milestones Source: https://docs.solanatracker.io/prediction-markets/meta/eventsports-milestones /prediction-markets/openapi.json get /v1/milestones ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getMilestones(); ``` # List market categories Source: https://docs.solanatracker.io/prediction-markets/meta/list-market-categories /prediction-markets/openapi.json get /v1/categories ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCategories(); ``` # List market series (Kalshi) Source: https://docs.solanatracker.io/prediction-markets/meta/list-market-series-kalshi /prediction-markets/openapi.json get /v1/series ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getSeries(); ``` # List Polymarket sports categories Source: https://docs.solanatracker.io/prediction-markets/meta/list-polymarket-sports-categories /prediction-markets/openapi.json get /v1/sports ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getSports(); ``` # Live market snapshots Source: https://docs.solanatracker.io/prediction-markets/meta/live-market-snapshots /prediction-markets/openapi.json get /v1/live_data ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getLiveData({ tickers: 'MARKET_TICKER', exchange: 'kalshi' }); ``` # Prediction Markets Overview Source: https://docs.solanatracker.io/prediction-markets/overview Beta unified API for Kalshi and Polymarket — markets, events, full historical trades and candlesticks, orderbooks, crypto windows, wallet analytics, and live Datastream rooms. **Public Beta** — Kalshi and Polymarket coverage with full historical market data. APIs may change. Join [Discord](https://discord.gg/JH2e9rR9fc) for feedback and support. Unified, read-only prediction market data for **Kalshi** and **Polymarket** — browse events and markets, pull historical trades and candlesticks, stream live tape and books, and (on Polymarket) analyze wallet PnL and positions. **Hosted API** * **REST:** `https://prediction-market-api.solanatracker.io` * **Realtime:** `wss://datastream.solanatracker.io/{apiKey}` — join `pm:*` rooms * **Auth:** Data API key in the `x-api-key` header (same key as the Solana Data API) Auth, exchanges, IDs, historical data, and copy-paste REST examples. Join `pm:*` rooms on `wss://datastream.solanatracker.io/{apiKey}`. Open **Prediction Markets** for the REST OpenAPI, and **Datastream → Prediction Markets** for the live room reference. *** ## What you get | Area | Coverage | | - | - | | Exchanges | Kalshi and Polymarket (`exchange=kalshi\|polymarket\|poly`) | | Discovery | Search, browse, trending, new markets, categories, series, sports | | Market data | Prices, midpoint, spread, quote ladder, open interest, related markets | | History | Full historical trades and candlesticks (per market and per event) | | Books | Live orderbooks and batch book lookups | | Crypto | Polymarket crypto up/down windows, Chainlink price-to-beat, price history | | Wallets | Polymarket positions, activity, FIFO PnL, charts, closed positions | | Leaderboards | Top traders / PnL (Polymarket; Kalshi has no public wallets) | | Realtime | Trades, significant trades (≥ \$25 notional), prices, quotes, books, volume, lifecycle, resolution | *** ## Quick example ```bash theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/trending?limit=5" \ -H "x-api-key: YOUR_API_KEY" ``` ```bash theme={null} curl "https://prediction-market-api.solanatracker.io/v1/markets/{ticker}/candlesticks?interval=1h" \ -H "x-api-key: YOUR_API_KEY" ``` *** ## Conventions * Response bodies use **camelCase**. * Query params are **snake\_case** (camelCase aliases accepted where noted). * SWR endpoints may return `X-Cache: HIT | HIT-STALE | MISS`. * Busy backends may return **503** with `SERVICE_BUSY` (not a rate-limit 429). * This API is **read / market-data only** — no order placement. *** ## IDs that matter | Exchange | Use in REST | Use in realtime rooms | | - | - | - | | Polymarket | Slug, condition id, or CLOB **token id** depending on endpoint | Decimal **CLOB token id** in `pm:market:polymarket:{tokenId}:*` | | Kalshi | Market / event tickers (often uppercase in REST) | **Lowercase** tickers in room names | Room segments are always lowercase. Event-scoped rooms accept slug **or** gamma / event ticker identities when present on the payload. # Recent changes Source: https://docs.solanatracker.io/prediction-markets/recent-changes New endpoints, added features, and fixes for Prediction Markets. [View the full changelog](/changelog)
August 2026
Prediction Markets Datastream

Beta Prediction Markets API for Kalshi and Polymarket

Unified read-only API for **Kalshi** and **Polymarket** with full historical market data. * **REST:** `https://prediction-market-api.solanatracker.io` * **Datastream:** `pm:*` rooms on `wss://datastream.solanatracker.io/{apiKey}` (same hub and key as other Datastream products) * Markets, events, trades, candlesticks, orderbooks, crypto up/down windows, and Polymarket wallet analytics * Auth with your existing Data API key (`x-api-key`)
# Combined platform statistics Source: https://docs.solanatracker.io/prediction-markets/stats/combined-platform-statistics /prediction-markets/openapi.json get /v1/stats ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getCombinedStats(); ``` # Per-exchange statistics Source: https://docs.solanatracker.io/prediction-markets/stats/per-exchange-statistics /prediction-markets/openapi.json get /v1/stats/{exchange} ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getExchangeStats('kalshi'); ``` # Global trade feed Source: https://docs.solanatracker.io/prediction-markets/trades/global-trade-feed /prediction-markets/openapi.json get /v1/markets/trades ## SDK Example ```typescript import { PredictionMarketsClient } from '@solana-tracker/data-api'; const client = new PredictionMarketsClient({ apiKey: 'YOUR_API_KEY' }); const data = await client.getGlobalTrades(); ``` # Build swap instructions Source: https://docs.solanatracker.io/raptor/http/build-swap-instructions /raptor/http/openapi.json post /swap-instructions Same input as `/swap`, but returns the individual instructions so you can add your own and build the transaction yourself. The swap is built as an ordinary swap unless you send `jitRouting: true`, so it can be called from your own program. If the response includes `quoteResponse`, use its amounts. When `topLevelOnly` is `true`, put `swapInstruction` last in the transaction and do not call it through CPI. # Build swap transaction Source: https://docs.solanatracker.io/raptor/http/build-swap-transaction /raptor/http/openapi.json post /swap Turn a quote into a base64 transaction for the user to sign. Send the quote exactly as `/quote` returned it, within a few seconds. If the quote has expired, the call fails; get a new quote and try again. Routing options (`dexes`, `maxHops` and so on) belong on `/quote` and are ignored here. # Get swap quote Source: https://docs.solanatracker.io/raptor/http/get-swap-quote /raptor/http/openapi.json get /quote Find the best route for a swap and return the expected output. No wallet is needed. Pass the whole response to `POST /swap` unchanged, and do it within a few seconds: quotes that carry a `quoteId` point to a short-lived execution plan. # Get transaction status Source: https://docs.solanatracker.io/raptor/http/get-transaction-status /raptor/http/openapi.json get /transaction/{signature} Status of a transaction sent through `POST /send-transaction`. Poll about once a second until `status` is no longer `pending`. Transactions sent elsewhere return 404. # Health check Source: https://docs.solanatracker.io/raptor/http/health-check /raptor/http/openapi.json get /health Returns `OK` when the service is up. # Quote and swap in one request Source: https://docs.solanatracker.io/raptor/http/quote-and-swap-in-one-request /raptor/http/openapi.json post /quote-and-swap Get a quote and the transaction in one call. Use it when the user does not need to review the price before signing. # Send a signed transaction Source: https://docs.solanatracker.io/raptor/http/send-a-signed-transaction /raptor/http/openapi.json post /send-transaction Submit a signed transaction. The call returns as soon as the transaction is accepted; Raptor keeps resending it for up to 30 seconds or until it confirms. Track it with `GET /transaction/{signature}`. # Raptor Swap API Source: https://docs.solanatracker.io/raptor/overview Swap any Solana token through a free hosted API or a free self-hosted binary. Get a quote, build the transaction, sign it and send it, routed across 71 DEXes. No API key needed. Raptor finds the best route for a swap across 71 Solana DEXes and gives you a transaction that the user's wallet signs. There are two ways to use it, and **both are currently free**, with no API key or sign-up: **Free.** Call `raptor.solanatracker.io` with nothing to install or run. Start with the quickstart below. **Free.** Download Raptor from GitHub and run the same API on your own servers, with no limits. Questions go to [Discord](https://discord.gg/JH2e9rR9fc). | | Address | | - | - | | HTTP | `https://raptor.solanatracker.io` | | WebSocket | `wss://raptor.solanatracker.io` | | Program ID | `RaptorD5ojtsqDDtJeRsunPLg6GvLYNnwKJWxYE4m87` | ## JIT routing A normal route picks its pools when you quote. With just-in-time (JIT) routing, the transaction carries several candidate pools and picks the best ones when it executes, using live prices. This helps most on larger orders and fast-moving pools. | `jitRouting` | Behavior | | - | - | | `auto` (default) | Raptor uses JIT when it improves the result. Orders of about \$10,000 or more get a full search. | | `true` | Always build a JIT route | | `false` | Never use JIT | Quotes that use JIT include `"jitRouting": true`. Things to know: * **`minAmountOut` is still enforced.** If live prices can't meet it, the transaction fails instead of filling worse. * **JIT works with `V0` and `V1` transactions.** `LEGACY` transactions have no lookup tables and a 1,232-byte limit, so JIT routes rarely fit; quote with `jitRouting=false` when you need `LEGACY`. * **JIT swaps can't be called from another program.** `/swap-instructions` returns an ordinary swap unless you send `jitRouting: true`. When it returns `topLevelOnly: true`, put `swapInstruction` last in the transaction and call it directly, not through CPI. Otherwise it fails with `InvalidJitPlan` (6026). * JIT is available on every supported DEX except Heaven, SolFi V1, BisonFi and Quantum. ## Quickstart Every swap takes the same five steps. Raptor does the routing; the user's wallet only signs. Ask for the price of selling 0.1 SOL (`100000000` lamports) for USDC. No wallet is needed. ```bash theme={null} curl "https://raptor.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50" ``` `amountOut` is the expected USDC (6 decimals). `minAmountOut` is the least the swap will accept. Send the quote back **unchanged** with the user's wallet address. Do this right away, because quotes expire after a few seconds. ```bash theme={null} curl -s "https://raptor.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000" \ | jq '{userPublicKey: "YOUR_WALLET_ADDRESS", quoteResponse: .}' \ | curl -s -X POST "https://raptor.solanatracker.io/swap" -H "Content-Type: application/json" -d @- ``` The response holds `swapTransaction`, an unsigned base64 transaction. Sign `swapTransaction` with the wallet, then submit the signed transaction as base64. Raptor keeps resending it until it lands or expires. ```bash theme={null} curl -X POST "https://raptor.solanatracker.io/send-transaction" \ -H "Content-Type: application/json" \ -d '{"transaction": "SIGNED_TRANSACTION_BASE64"}' ``` Poll until `status` is `confirmed`, `failed` or `expired`. ```bash theme={null} curl "https://raptor.solanatracker.io/transaction/SIGNATURE" ``` ### Complete example This script swaps 0.1 SOL for USDC from a local keypair. In a browser app, replace the signing step with your wallet adapter's `signTransaction`. ```javascript Node.js theme={null} // npm install @solana/web3.js bs58 import { Keypair, VersionedTransaction } from "@solana/web3.js"; import bs58 from "bs58"; const RAPTOR = "https://raptor.solanatracker.io"; const SOL = "So11111111111111111111111111111111111111112"; const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY)); async function api(path, body) { const res = await fetch(`${RAPTOR}${path}`, body && { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const text = await res.text(); if (!res.ok) throw new Error(`${path} ${res.status}: ${text}`); return JSON.parse(text); } // 1. Quote 0.1 SOL -> USDC const quote = await api(`/quote?inputMint=${SOL}&outputMint=${USDC}&amount=100000000&slippageBps=50`); console.log(`Expected: ${quote.amountOut} (min ${quote.minAmountOut})`); // 2. Build the transaction (right away: quotes expire after a few seconds) const { swapTransaction } = await api("/swap", { userPublicKey: wallet.publicKey.toBase58(), quoteResponse: quote, priorityFee: "high", }); // 3. Sign const tx = VersionedTransaction.deserialize(Buffer.from(swapTransaction, "base64")); tx.sign([wallet]); // 4. Send const { signature } = await api("/send-transaction", { transaction: Buffer.from(tx.serialize()).toString("base64"), }); console.log(`Sent: ${signature}`); // 5. Wait for the result for (let i = 0; i < 30; i++) { const { status, error } = await api(`/transaction/${signature}`); if (status !== "pending") { console.log(status, error ?? ""); break; } await new Promise((r) => setTimeout(r, 1000)); } ``` ```python Python theme={null} # pip install requests solders import base64, os, time import requests from solders.keypair import Keypair from solders.transaction import VersionedTransaction RAPTOR = "https://raptor.solanatracker.io" SOL = "So11111111111111111111111111111111111111112" USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" wallet = Keypair.from_base58_string(os.environ["PRIVATE_KEY"]) def api(path, body=None): if body is None: res = requests.get(RAPTOR + path) else: res = requests.post(RAPTOR + path, json=body) if not res.ok: raise RuntimeError(f"{path} {res.status_code}: {res.text}") return res.json() # 1. Quote 0.1 SOL -> USDC quote = api(f"/quote?inputMint={SOL}&outputMint={USDC}&amount=100000000&slippageBps=50") print("Expected:", quote["amountOut"], "min", quote["minAmountOut"]) # 2. Build the transaction (right away: quotes expire after a few seconds) swap = api("/swap", { "userPublicKey": str(wallet.pubkey()), "quoteResponse": quote, "priorityFee": "high", }) # 3. Sign unsigned = VersionedTransaction.from_bytes(base64.b64decode(swap["swapTransaction"])) signed = VersionedTransaction(unsigned.message, [wallet]) # 4. Send sent = api("/send-transaction", {"transaction": base64.b64encode(bytes(signed)).decode()}) signature = sent["signature"] print("Sent:", signature) # 5. Wait for the result for _ in range(30): status = api(f"/transaction/{signature}") if status["status"] != "pending": print(status["status"], status.get("error", "")) break time.sleep(1) ``` ## Endpoints | Endpoint | Use it to | | - | - | | [`GET /quote`](/raptor/http/get-swap-quote) | Price a swap | | [`POST /swap`](/raptor/http/build-swap-transaction) | Turn a quote into a transaction to sign | | [`POST /swap-instructions`](/raptor/http/build-swap-instructions) | Get the instructions to build your own transaction | | [`POST /quote-and-swap`](/raptor/http/quote-and-swap-in-one-request) | Quote and build in one call | | [`POST /send-transaction`](/raptor/http/send-a-signed-transaction) | Send a signed transaction | | [`GET /transaction/{signature}`](/raptor/http/get-transaction-status) | Check whether it landed | | [`GET /health`](/raptor/http/health-check) | Check the service is up | | `wss://…/stream` | Stream live quotes ([WebSocket](#websocket)) | | `wss://…/stream/swap` | Stream live quotes with ready-to-sign transactions | On a [self-hosted](/raptor/self-hosting) instance, streaming, `/send-transaction`, `/transaction/{signature}` and `/quote-and-swap` are off until you [turn them on](/raptor/self-hosting#optional-features). ## Parameters you'll use most ### Amounts Amounts are integers in the token's smallest unit: `amount = tokens × 10^decimals`. SOL has 9 decimals, so `1000000000` is 1 SOL. USDC has 6, so `1000000` is 1 USDC. Use mint `So11111111111111111111111111111111111111112` for SOL; Raptor wraps and unwraps it for you. ### Slippage `slippageBps` sets the most the price may move against you, in basis points: `50` is 0.5%. Pass `dynamic` to let Raptor pick a value for the token and route. If the price moves further, the transaction fails instead of filling at a worse price. Only the network fee is spent. ### Priority fee Set `priorityFee` on `/swap` to a level (`min`, `low`, `medium`, `auto`, `high`, `veryHigh`, `turbo`, `unsafeMax`) or to a total fee in lamports as a string, such as `"50000"`. The default is `auto`. `maxPriorityFee` caps the compute unit price in micro-lamports. The response field `prioritizationFeeLamports` shows what was included. ### Platform fees Charge your own fee on swaps by adding `feeAccount` (a normal wallet address) and `feeBps` (up to `1000`, or 10%) to `/quote`. The fee carries through to `/swap`. It's taken from the output token unless you set `feeFromInput=true`. `minAmountOut` already accounts for your fee. `chargeBps` takes an extra cut only when the user gets more than quoted. ### Tips Add a SOL tip to the transaction, for example to a Jito tip account, with `tipAccount` and `tipLamports` on `/swap`. ### Limit the route On `/quote`, `dexes` limits routing to the DEXes you list (comma-separated, case-insensitive). `raydium` matches every Raydium pool type, and `raydium-clmm` matches just one. `pools` limits routing to specific pool addresses, `maxHops` caps the route length (1 to 4), and `onlyDirectRoutes=true` allows single-hop routes only. ```bash theme={null} curl "https://raptor.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&dexes=raydium,meteora,whirlpool&maxHops=2" ``` Routing options go on `/quote` only. `/swap` builds whatever route the quote holds. ### Search depth `searchMode=deep` on `/quote` searches more pools and routes before it answers. It takes longer, and it never returns less than the default `fast` search. Use it when the best price matters more than speed, for example on large orders. ### Transaction options These go on `/swap`, `/swap-instructions` and `/quote-and-swap`. | Field | What it does | | - | - | | `txVersion` | `V0` (default), `LEGACY` or `V1`. Case-sensitive. JIT works with `V0` and `V1`; for `LEGACY`, quote with `jitRouting=false`. | | `wrapUnwrapSol` | `true` (default) wraps and unwraps SOL for you. Set `false` to trade from and to the wallet's wrapped SOL account. Use the same value on `/quote`. | | `destinationTokenAccount` | Deliver the output to this token account instead of the wallet's associated token account. `/quote-and-swap` only. | | `computeUnitLimit` | Set the compute unit limit instead of Raptor's estimate | | `computeUnitPriceMicroLamports` | Set an exact compute unit price instead of a `priorityFee` level | `/quote` doesn't need a wallet and doesn't check balances. You can pass `userPublicKey` to quote for the wallet that will swap, but `/swap` still needs it. ## Arbitrage Quote with the same mint as input and output, for example SOL to SOL, and Raptor looks for a cycle through several pools that returns more than you put in. ```bash theme={null} curl "https://raptor.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=So11111111111111111111111111111111111111112&amount=1000000000" ``` * If `routePlan` isn't empty, Raptor found a cycle. `amountOut` minus `amount` is the expected profit, before network and priority fees. Build and send it like any other swap. * If no cycle is profitable, the response has an empty `routePlan` and `amountOut` equal to `amount`. There's nothing to build. On a self-hosted instance, start the binary with [`--enable-arbitrage`](/raptor/self-hosting#arbitrage). ## Token-2022 transfer fees If the input or output token charges a Token-2022 transfer fee, the quote includes `tokenTransfers`. `netOutput` is what actually reaches the wallet after platform and transfer fees. ```json theme={null} { "tokenTransfers": { "depositFee": "37", "deliveryFee": "31", "netOutput": "9969" } } ``` ## WebSocket Stream live quotes instead of polling. Each update arrives when the best route changes. * **`/stream`** sends quotes. Use it to show prices. * **`/stream/swap`** sends quotes plus a fresh, ready-to-sign transaction for `userPublicKey`. Sign the latest one and send it with `POST /send-transaction`. ```javascript theme={null} const ws = new WebSocket("wss://raptor.solanatracker.io/stream"); ws.onopen = () => ws.send(JSON.stringify({ type: "subscribe", inputMint: "So11111111111111111111111111111111111111112", outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", amount: 100000000, slippageBps: "50", })); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "quote") console.log(msg.data.amountOut); if (msg.type === "error") console.error(msg.error); }; ``` Stop with `{ "type": "unsubscribe", "id": "" }`. One connection holds up to 50 subscriptions. All messages and fields are listed in the WebSocket reference in the sidebar. ## Errors | Status | Meaning | What to do | | - | - | - | | `400` | A parameter is missing or invalid, such as `amount=0` | Fix the request. The `error` field says which parameter. | | `404` | `/transaction/{signature}`: not sent through Raptor, or no longer tracked | Check the signature on an RPC node instead. | | `422` | No route for this pair and amount, or the JSON body is invalid, or the quote expired or was edited | No route: try another amount or fewer filters. Otherwise get a new quote and pass it to `/swap` unchanged, and check that `txVersion` is upper-case. | | `500` | The transaction couldn't be built | For `Execution plan expired`, get a new quote and retry. | Most errors are JSON, `{ "error": "...", "code": 400 }`. Errors from parsing the request (some `400`s and `422`s) are plain text, so read the body as text before parsing it. ## Supported DEXs Raptor routes across 71 DEXes. | Group | DEXes | | - | - | | Raydium | AMM, CLMM, CPMM, LaunchLab | | Meteora | DLMM, Dynamic AMM, DAMM V2, Curve, Dynamic Bonding Curve | | Orca | Whirlpool, Whirlpool V2 | | Launchpads | Pump.fun, Pumpswap, Heaven, MoonIt, Boopfun | | PropAMMs | HumidiFi, Tessera, SolFi V1, SolFi V2, AlphaQ, ZeroFi, BisonFi, GoonFi V2 | | Other | FluxBeam, PancakeSwap V3 | | Added in V1 | Aquifer, Archer, BinaryFi, BisonFi Predict, BonkSwap, Crema, Cropper, Denali, Deriverse, Flint, Fusion, GatorSwap, Hadron, Helium, Huma, Hylo Earn, Hylo Exchange, Invariant, JupLend, JupLend Earn, Kipseli, Kipseli V3, M Swap, Mercurial, MetaDAO, Omnipair, OneDex, Perena, Perena Star, Quantum, Quay, Riptide, Sanctum Infinity, Sanctum PAMM, Sanctum SOLs, Sanctum Stake, Scale AMM, Scorch, Solayer, Stabble CLMM, Stableswap, TaurusFi, Trends, VaultLiquid, Voltr, WhaleStreet V2, xORCA | ## Hosted or self-hosted | | Hosted API | Self-hosted binary | | - | - | - | | Price | Currently free | Currently free | | Setup | None | Download from [GitHub](https://github.com/solanatracker/raptor-binary/releases/latest), add your RPC and Yellowstone gRPC endpoints | | API key | None | None | | Limits | Shared service | None. Run as many instances as you want. | | Endpoints | All | All. Streaming, sending and `/quote-and-swap` are opt-in flags. | | Instance-wide DEX, mint and pool allowlists | No | Yes | Both run the same routing engine and build transactions for the same program. See [Self-hosting](/raptor/self-hosting) to install the binary. ## Next steps Browser wallets, instructions-only builds and streaming swaps. Submit signed transactions and read swap results. Download the binary from GitHub and run Raptor on your own servers. # Recent changes Source: https://docs.solanatracker.io/raptor/recent-changes New endpoints, added features, and fixes for Raptor Swap API. [View the full changelog](/changelog)
October 8, 2026
New Raptor Swap API
## Raptor V1: 71 DEXes, JIT routing, and out of beta Raptor V1 is live on mainnet. It adds 47 DEXes and JIT routing, and the hosted API has a new address. * **47 new DEXes.** Raptor now routes across 71, including MetaDAO, Hylo, Sanctum, JupLend, Solayer and Invariant. See the [full list](/raptor/overview#supported-dexs). * **JIT routing, on by default.** A JIT swap carries several candidate pools and chooses between them on-chain when it executes, using live prices. `minAmountOut` is still enforced. Set `jitRouting` to `true` or `false` to force it on or off. * **Token-2022 transfer fees in the quote.** If a token charges a transfer fee, the quote includes `tokenTransfers` with `depositFee`, `deliveryFee` and `netOutput`. * **Error codes.** No route now returns `422` instead of `500`, and an invalid amount returns `400`. Both are JSON. ### Update your base URL The hosted API moved from `raptor-beta.solanatracker.io` to `raptor.solanatracker.io`. Change the base URL in your code. The program ID is still `RaptorD5ojtsqDDtJeRsunPLg6GvLYNnwKJWxYE4m87`. ```diff theme={null} - https://raptor-beta.solanatracker.io + https://raptor.solanatracker.io ```
# Self-host Raptor Source: https://docs.solanatracker.io/raptor/self-hosting Download the free Raptor binary from GitHub and run the same swap API on your own servers. No API key, no request limits and as many instances as you like. Raptor is also a single binary that you run on your own servers. It's the same routing engine and the same [HTTP](/raptor/http/get-swap-quote) and [WebSocket](#websocket-streaming) API as the hosted service at `raptor.solanatracker.io`. * **Currently free.** There's no charge for the binary, and no API key or license key. Download it and run it. * **No limits.** Run as many instances as you want and serve as many requests as your hardware handles. * **You can resell it.** Put your own API in front of it, charge for access or add your own [platform fee](/raptor/overview#platform-fees). The latest release for Linux and macOS, with checksums and release notes. Bugs and feature requests go to the GitHub repository. Questions go to Discord. You don't need to self-host to use Raptor. The [hosted API](/raptor/overview), which is also currently free, needs no setup. Self-host when you want your own capacity, your own infrastructure or no dependency on a shared service. ## What the binary does Out of the box, the binary serves quotes and builds swap transactions. Four more features are off until you turn them on. | Feature | Endpoints | Default | Turn it on with | | - | - | - | - | | Quotes across every [supported DEX](/raptor/overview#supported-dexs), with multi-hop, split and [JIT](/raptor/overview#jit-routing) routing | `GET /quote` | On | | | Build swap transactions, with priority fees, tips and platform fees | `POST /swap`, `POST /swap-instructions` | On | | | Health and readiness checks | `GET /health`, `GET /ready` | On | | | [Live quote streaming](#websocket-streaming) | `/stream`, `/stream/swap` | Off | `--enable-websocket` | | [Send and track transactions](#send-and-track-transactions) | `POST /send-transaction`, `GET /transaction/{signature}` | Off | `--enable-yellowstone-jet` | | [Quote and build in one call](#quote-and-swap-in-one-call) | `POST /quote-and-swap` | Off | `--enable-quote-and-swap` | | [Arbitrage quotes](/raptor/overview#arbitrage), where the input and output mint are the same | `GET /quote` | Off | `--enable-arbitrage` | A request to an endpoint that's turned off returns `404`. Raptor keeps pool state current by streaming account updates from Yellowstone gRPC, so it uses very little RPC after startup. ## Requirements * **A Linux or macOS server.** * Linux: x86-64 with glibc 2.30 or newer, such as Ubuntu 20.04+, Debian 11+ or RHEL 9+. * macOS: Apple Silicon or Intel. * **A Solana RPC endpoint**, set as `RPC_URL`. * **A Yellowstone gRPC endpoint**, set as `YELLOWSTONE_ENDPOINT`, plus `YELLOWSTONE_TOKEN` if your provider needs one. Raptor won't start without it. * **A writable directory for the pool cache.** By default it's `.r_cache` next to the binary. Set `RAPTOR_POOL_DATA_DIR` to use another directory. * **Outbound HTTPS.** On startup, Raptor downloads the current pool index from Solana Tracker, then keeps it current from Yellowstone. ## Install Each [release](https://github.com/solanatracker/raptor-binary/releases/latest) has one zip per platform, named `raptor--.zip`. | Server | Platform in the file name | | - | - | | Linux, x86-64 | `x86_64-unknown-linux-gnu` | | macOS, Apple Silicon | `aarch64-apple-darwin` | | macOS, Intel | `x86_64-apple-darwin` | These commands download the latest release and check it against the published `checksums.txt`. ```bash Linux theme={null} VERSION=$(curl -s https://api.github.com/repos/solanatracker/raptor-binary/releases/latest \ | grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4) PLATFORM=x86_64-unknown-linux-gnu BASE=https://github.com/solanatracker/raptor-binary/releases/download/$VERSION curl -LO "$BASE/raptor-$VERSION-$PLATFORM.zip" curl -LO "$BASE/checksums.txt" sha256sum --check --ignore-missing checksums.txt unzip "raptor-$VERSION-$PLATFORM.zip" ``` ```bash macOS theme={null} VERSION=$(curl -s https://api.github.com/repos/solanatracker/raptor-binary/releases/latest \ | grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4) PLATFORM=aarch64-apple-darwin # x86_64-apple-darwin on Intel Macs BASE=https://github.com/solanatracker/raptor-binary/releases/download/$VERSION curl -LO "$BASE/raptor-$VERSION-$PLATFORM.zip" curl -LO "$BASE/checksums.txt" shasum -a 256 --check --ignore-missing checksums.txt unzip "raptor-$VERSION-$PLATFORM.zip" ``` The check prints `raptor--.zip: OK`. If it prints anything else, delete the zip and download it again. Keep `raptor.sig` in the same directory as `raptor`. The binary uses it to check that it hasn't been modified. ```bash theme={null} ./raptor --version ``` If macOS blocks a binary you downloaded in a browser, clear the quarantine flag with `xattr -d com.apple.quarantine raptor`. ## Run Set your endpoints and start the server. ```bash theme={null} export RPC_URL="https://your-rpc.example.com" export YELLOWSTONE_ENDPOINT="https://your-grpc.example.com" export YELLOWSTONE_TOKEN="your-token" ./raptor ``` Raptor listens on `0.0.0.0:8080`. Set `BIND_ADDR` to change it, for example `BIND_ADDR=127.0.0.1:9000`. To turn on every optional feature except arbitrage: ```bash theme={null} ./raptor --enable-websocket --enable-yellowstone-jet --enable-quote-and-swap ``` ### Wait until it's ready Raptor indexes pools before it can route. Until it finishes, `/quote` returns `503` with `Server warming up`. `/ready` returns `200` once Raptor can serve quotes, and `503` before that: ```bash theme={null} curl http://localhost:8080/ready ``` ```json theme={null} { "ready": true, "pool_count": 812345, "indexed_count": 812345, "indexing_in_progress": false } ``` `/health` returns `OK` as soon as the server is up, even while it's still indexing. Point load-balancer health checks at `/ready` so an instance gets traffic only once it can quote. ### Make your first quote ```bash theme={null} curl "http://localhost:8080/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50" ``` Every example in the [overview](/raptor/overview) works against your instance once you replace `https://raptor.solanatracker.io` with your server's address. ## Optional features Every flag also has an environment variable. For on/off variables, `1`, `true`, `yes` and `on` all turn the feature on. ### WebSocket streaming ```bash theme={null} ./raptor --enable-websocket # or ENABLE_WEBSOCKET=true ``` Clients connect to `ws://your-server:8080/stream` for live quotes, or to `/stream/swap` for quotes with a ready-to-sign transaction. Raptor pushes an update whenever the best route changes, so clients don't need to poll. See [WebSocket](/raptor/overview#websocket) for the message format. ### Send and track transactions ```bash theme={null} ./raptor --enable-yellowstone-jet # or ENABLE_YELLOWSTONE_JET=true ``` This turns on `POST /send-transaction` and `GET /transaction/{signature}`. Raptor sends signed transactions straight to the upcoming block leaders over QUIC using [Yellowstone Jet](https://github.com/rpcpool/yellowstone-jet), and resends them until they land or expire. See [Send and track transactions](/raptor/transactions) for the request and response formats. | Flag | Variable | Default | What it does | | - | - | - | - | | `--jet-identity ` | `JET_IDENTITY` | none | Keypair file to send from. A staked validator identity gets stake-weighted priority with leaders. | | `--jet-identities ` | `JET_NUM_IDENTITIES` | `4` | Without `--jet-identity`, Raptor sends from this many random identities. | | `--tx-cache-ttl ` | `TX_CACHE_TTL_SECS` | `30` | How long a finished transaction's status stays queryable | | `--tx-pending-expiry ` | `TX_PENDING_EXPIRY_SECS` | `120` | When a transaction that hasn't landed is marked `expired` | The server needs outbound UDP access to Solana validators for QUIC. ### Quote and swap in one call ```bash theme={null} ./raptor --enable-quote-and-swap # or -s, or ENABLE_QUOTE_AND_SWAP=true ``` This turns on `POST /quote-and-swap`, which quotes and builds the transaction in one request. It saves a round trip for bots and backends that don't need to show the quote first. See [Quote and swap in one request](/raptor/http/quote-and-swap-in-one-request). ### Arbitrage ```bash theme={null} ./raptor --enable-arbitrage # or ENABLE_ARBITRAGE=true ``` This lets `/quote` accept the same mint as input and output, for example SOL to SOL. Raptor then looks for a cycle through several pools that returns more than you put in, as described in [Arbitrage](/raptor/overview#arbitrage). Without this flag, same-mint quotes return `400` with `Circular arbitrage is disabled`. ## Limit what Raptor routes By default, Raptor routes through every supported DEX and pool. These filters narrow that for the whole instance. DEX filters also reduce what Raptor streams from Yellowstone, which saves memory and bandwidth. Callers can narrow routing further on each request with [`dexes` and `pools`](/raptor/overview#limit-the-route). | Flag | Variable | What it does | | - | - | - | | `--include-dexes ` | `INCLUDE_DEXES` | Use only these DEXes, comma-separated | | `--exclude-dexes ` | `EXCLUDE_DEXES` | Use every DEX except these, comma-separated | | `--include-mints-file ` | `INCLUDE_MINTS_FILE` | Use only pools that hold at least one mint from this file | | `--include-pools-file ` | `INCLUDE_POOLS_FILE` | Use only the pools listed in this file | DEX names are case-insensitive and accept several spellings, so `raydium-clmm`, `raydium_clmm` and `"Raydium CLMM"` all mean the same DEX. `raydium` and `meteora` match every pool type from that DEX, and `orca` matches Whirlpool. Set an include list or an exclude list, not both. If both are set, the include list wins. ```bash theme={null} ./raptor --include-dexes raydium,meteora,whirlpool,pumpswap ``` Allowlist files have one address per line. Raptor ignores empty lines, and `#` starts a comment. When you combine filters, a pool must pass all of them. ```text theme={null} # mints.txt So11111111111111111111111111111111111111112 EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v ``` ```bash theme={null} ./raptor --include-mints-file mints.txt ``` ## Run several instances Each instance runs independently with its own Yellowstone stream, so you can put as many as you need behind a load balancer. Every quote carries a signed `quoteId`. By default, `/swap` accepts only quotes made by the same instance. If your load balancer can send a client's `/quote` and `/swap` to different instances, give every instance the same secret: ```bash theme={null} export RAPTOR_QUOTE_SECRET="a-random-string-of-at-least-32-characters" ``` Instances that share the secret accept each other's quotes. Generate one with `openssl rand -hex 32` and keep it private. ## Memory and performance | Flag | Variable | Default | What it does | | - | - | - | - | | `--workers ` | `WORKER_THREADS` | CPU cores | Worker threads | | `--low-memory` | `LOW_MEMORY_MODE` | off | Use bounded caches and keep bonding-curve pools on disk instead of in memory | | `--memory-limit ` | `MEMORY_LIMIT_MB` | 80% of system RAM | Memory budget for low-memory mode | | `--rpc-rate-limit ` | `RPC_RATE_LIMIT` | unlimited | Most RPC requests per second, to stay under your provider's limit | | | `RAPTOR_POOL_DATA_DIR` | `.r_cache` beside the binary | Directory for the on-disk pool cache | Use `--low-memory` on small servers. Launchpads such as Pump.fun have millions of bonding-curve pools, and low-memory mode keeps them on disk. ### Startup options | Flag | Variable | What it does | | - | - | - | | `--skip-pool-indexer-wait` | `SKIP_POOL_INDEXER_WAIT` | Start serving before the pool index has synced. Early quotes may miss pools. | | `--no-pool-indexer` | `NO_POOL_INDEXER` | Don't download the pool index from Solana Tracker. Raptor finds pools from Yellowstone alone, which takes much longer to cover every pool. | ## Run it as a service Put `raptor` and `raptor.sig` in `/opt/raptor`, then create `/etc/systemd/system/raptor.service`: ```ini theme={null} [Unit] Description=Raptor swap API After=network-online.target Wants=network-online.target [Service] WorkingDirectory=/opt/raptor ExecStart=/opt/raptor/raptor --enable-websocket --enable-yellowstone-jet EnvironmentFile=/opt/raptor/raptor.env Restart=always RestartSec=5 LimitNOFILE=1048576 [Install] WantedBy=multi-user.target ``` Put your settings in `/opt/raptor/raptor.env`, one `NAME=value` per line: ```bash theme={null} RPC_URL=https://your-rpc.example.com YELLOWSTONE_ENDPOINT=https://your-grpc.example.com YELLOWSTONE_TOKEN=your-token RAPTOR_QUOTE_SECRET=your-shared-secret ``` Start it and follow the logs: ```bash theme={null} sudo systemctl daemon-reload sudo systemctl enable --now raptor journalctl -u raptor -f ``` Unzip the Linux release next to this `Dockerfile`: ```dockerfile theme={null} FROM debian:bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* WORKDIR /opt/raptor COPY raptor raptor.sig ./ ENV RAPTOR_POOL_DATA_DIR=/data VOLUME /data EXPOSE 8080 ENTRYPOINT ["/opt/raptor/raptor"] ``` ```bash theme={null} docker build -t raptor . docker run -d --name raptor -p 8080:8080 -v raptor-data:/data \ -e RPC_URL=https://your-rpc.example.com \ -e YELLOWSTONE_ENDPOINT=https://your-grpc.example.com \ -e YELLOWSTONE_TOKEN=your-token \ raptor --enable-websocket --enable-yellowstone-jet ``` The volume keeps the pool cache when the container is replaced. If your Docker network blocks outbound UDP, run with `--network host` so `--enable-yellowstone-jet` can reach validators. ## Update Download the new release the same way, replace `raptor` and `raptor.sig`, and restart. Keep the pool cache directory between versions. Release notes are on [GitHub](https://github.com/solanatracker/raptor-binary/releases) and in [Recent changes](/raptor/recent-changes). To update several instances without downtime, give them all the same `RAPTOR_QUOTE_SECRET` and restart them one at a time. Each instance rejoins the load balancer once `/ready` returns `200`. ## Configuration reference Flags take their value either way: `--workers 8` or `--workers=8`. | Flag | Variable | Default | Description | | - | - | - | - | | | `RPC_URL` | required | Solana RPC endpoint | | | `YELLOWSTONE_ENDPOINT` | required | Yellowstone gRPC endpoint | | | `YELLOWSTONE_TOKEN` | none | Yellowstone auth token | | | `BIND_ADDR` | `0.0.0.0:8080` | Address and port to listen on | | | `RAPTOR_QUOTE_SECRET` | none | Shared secret of at least 32 characters, so instances accept each other's quotes | | | `RAPTOR_POOL_DATA_DIR` | `.r_cache` beside the binary | Pool cache directory | | `--enable-websocket` | `ENABLE_WEBSOCKET` | off | Serve `/stream` and `/stream/swap` | | `--enable-yellowstone-jet` | `ENABLE_YELLOWSTONE_JET` | off | Serve `/send-transaction` and `/transaction/{signature}` | | `-s`, `--enable-quote-and-swap` | `ENABLE_QUOTE_AND_SWAP` | off | Serve `/quote-and-swap` | | `--enable-arbitrage` | `ENABLE_ARBITRAGE` | off | Allow same-mint arbitrage quotes | | `--include-dexes ` | `INCLUDE_DEXES` | all | Use only these DEXes | | `--exclude-dexes ` | `EXCLUDE_DEXES` | none | Never use these DEXes | | `--include-mints-file ` | `INCLUDE_MINTS_FILE` | none | Use only pools holding a listed mint | | `--include-pools-file ` | `INCLUDE_POOLS_FILE` | none | Use only the listed pools | | `--jet-identity ` | `JET_IDENTITY` | none | Keypair to send transactions from | | `--jet-identities ` | `JET_NUM_IDENTITIES` | `4` | Random sending identities when no keypair is set | | `--tx-cache-ttl ` | `TX_CACHE_TTL_SECS` | `30` | How long sent transactions stay queryable | | `--tx-pending-expiry ` | `TX_PENDING_EXPIRY_SECS` | `120` | When a pending transaction is marked `expired` | | `--workers ` | `WORKER_THREADS` | CPU cores | Worker threads | | `--low-memory` | `LOW_MEMORY_MODE` | off | Bounded caches and on-disk bonding-curve pools | | `--memory-limit ` | `MEMORY_LIMIT_MB` | 80% of RAM | Memory budget for low-memory mode | | `--rpc-rate-limit ` | `RPC_RATE_LIMIT` | unlimited | Most RPC requests per second | | `--skip-pool-indexer-wait` | `SKIP_POOL_INDEXER_WAIT` | off | Serve before the pool index has synced | | `--no-pool-indexer` | `NO_POOL_INDEXER` | off | Find pools from Yellowstone only | | `-h`, `--help` | | | Show help | | `-v`, `--version` | | | Show the version | ## Troubleshooting Set `RPC_URL` and `YELLOWSTONE_ENDPOINT` in the environment that runs Raptor. Under systemd, put them in the `EnvironmentFile`, because variables exported in your shell don't reach the service. Raptor is still indexing pools. Wait until `/ready` returns `200`. If it never does, check the logs for Yellowstone connection errors, and check that the server can make outbound HTTPS requests. The feature is turned off. Start Raptor with `--enable-websocket`, `--enable-yellowstone-jet` or `--enable-quote-and-swap`. Set the same `RAPTOR_QUOTE_SECRET` on every instance, or send each client's `/quote` and `/swap` to the same instance. The binary needs glibc 2.30 or newer. Use Ubuntu 20.04+, Debian 11+ or a newer distribution, or run the Docker image above. Set `--rpc-rate-limit` below your plan's requests per second. Raptor makes most of its RPC calls at startup, then reads mainly from Yellowstone. ## FAQ No. The binary is currently free: download it and run it. There's no key and no request limit. Yes. You can run it behind your own API, charge for access and add your own platform fee with `feeAccount` and `feeBps`. Yes. Raptor fills the same role: a self-hosted aggregator that quotes and builds swaps. It needs no binary key, and you can run unlimited instances. No. Raptor is closed source, and the [GitHub repository](https://github.com/solanatracker/raptor-binary) hosts the releases. Open an issue there for bugs and feature requests. Yes. Every instance builds transactions for the Raptor program, `RaptorD5ojtsqDDtJeRsunPLg6GvLYNnwKJWxYE4m87`. # Send and track transactions Source: https://docs.solanatracker.io/raptor/transactions Send signed Solana transactions through Raptor, poll their status, and read the amounts a swap actually traded. After the user signs a swap, send it with `POST /send-transaction`. Raptor submits it straight to block leaders and keeps resending it for up to 30 seconds or until it lands. Then poll `GET /transaction/{signature}` for the result. You can send any signed transaction this way, not only Raptor swaps. ## Send ```javascript theme={null} const RAPTOR = "https://raptor.solanatracker.io"; const res = await fetch(`${RAPTOR}/send-transaction`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ transaction: signedTxBase64 }), }); const { signature } = await res.json(); ``` ```json Response theme={null} { "signature": "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "signature_base64": "2E7bSk9JY3Yb1aN0…", "success": true } ``` `success: true` means Raptor accepted the transaction. It doesn't mean it landed. Check the status for that. ## Track ```javascript theme={null} async function waitForResult(signature) { for (let i = 0; i < 30; i++) { const tx = await fetch(`${RAPTOR}/transaction/${signature}`).then((r) => r.json()); if (tx.status !== "pending") return tx; await new Promise((r) => setTimeout(r, 1000)); } throw new Error("Timed out waiting for transaction"); } const tx = await waitForResult(signature); console.log(tx.status, tx.latency_ms, "ms"); ``` | `status` | Meaning | | - | - | | `pending` | Sent, not landed yet | | `confirmed` | Landed at `confirmed` commitment | | `failed` | Landed, but the transaction returned an error (see `error`) | | `expired` | Did not land in time. Get a new quote and try again. | The signature can be base58 or base64. Raptor only tracks transactions sent through `/send-transaction`, and only for a short time. Other signatures return `404`. ## Read the swap result For Raptor swaps, `events` lists the program's events. `SwapEvent` holds the amounts that were actually traded: ```javascript theme={null} for (const event of tx.events ?? []) { if (event.name === "SwapEvent") { console.log(`${event.parsed.amountIn} in → ${event.parsed.amountOut} out`); } } ``` ```json Example theme={null} { "signature": "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "status": "confirmed", "slot": 454215402, "sent_at": 1791374181491, "confirmed_at": 1791374182103, "latency_ms": 612, "events": [ { "name": "SwapEvent", "data": "…", "parsed": { "amountIn": 100000000, "amountOut": 11703794 } } ] } ``` Event names: `SwapEvent`, `SwapCompleteEvent`, `PlaceOrderEvent`, `FillOrderEvent`, `CancelOrderEvent`, `UpdateOrderEvent`. ## Errors | Status | Meaning | | - | - | | `400` | The transaction couldn't be decoded, for example it isn't base64 or isn't signed | | `404` | The signature isn't tracked | ```json theme={null} { "error": "Transaction not found.", "code": 404 } ``` Full field lists: [Send a signed transaction](/raptor/http/send-a-signed-transaction) and [Get transaction status](/raptor/http/get-transaction-status). # Quote stream Source: https://docs.solanatracker.io/raptor/websocket/websockets/quote-stream `wss://raptor.solanatracker.io/stream` Live quotes for one or more token pairs. Use it to show prices. To get a transaction, pass a quote to `POST /swap`, or use the swap stream. # Swap stream Source: https://docs.solanatracker.io/raptor/websocket/websockets/swap-stream `wss://raptor.solanatracker.io/stream/swap` Live quotes plus a ready-to-sign transaction for `userPublicKey`. Sign the latest `swapTransaction` and send it with `POST /send-transaction`. If nothing changes for 10 slots, the server re-sends a fresh transaction so the latest one does not expire. # Solana RPC credits and rate limits Source: https://docs.solanatracker.io/solana-rpc/credits-and-rate-limits Check RPC credit costs, request limits, and WebSocket connection limits for each Solana Tracker plan. RPC usage has two separate limits: credits measure consumption over a billing cycle, while rate limits control how quickly you can send requests. Check both when sizing a workload. ## Credits per call | Method or category | Credits per call | | - | - | | `getTransaction`, `getBlock`, `getBlocks`, `getBlockTime`, `getInflationReward`, `getSignaturesForAddress` | 10 | | `getProgramAccounts`, `getTokenAccountsByOwner` | 10 | | DAS API | 10 | | `getProgramAccountsV2`, `getTokenAccountsByOwnerV2`, `getTokenAccountsByOwners` | 1 | | `getLookupTablesByAuthority`, `getLookupTablesByAccount`, `getLookupTablesByMint`, `getLookupTablesByAccounts` | 1 | | `getPrimaryDomain`, `getMultiplePrimaryDomains`, `getAllDomains`, `resolveSolDomain` | 1 | | Other standard RPC methods, including `sendTransaction` and priority fee queries | 1 | Older archive aliases (`getConfirmedBlock`, `getConfirmedBlocks`, `getConfirmedTransaction`, `getConfirmedSignaturesForAddress`, and `getConfirmedSignaturesForAddress2`) also cost 10 credits. Use the current method pages for supported request shapes. DAS pricing covers asset, proof, owner, authority, creator, group, search, signature, token account, and NFT edition queries. The V2 account queries cost 1 credit rather than 10. Check their pagination and response structure before replacing a standard method; they are not identical request and response formats. ## Limits by plan The Free plan has a €1 one-time charge and includes 500,000 credits. RPS means requests per second; the WebSocket column is the connection limit. | Plan | Credits | General RPS | Send RPS | getProgramAccounts RPS | DAS RPS | WebSocket connections | | - | - | - | - | - | - | - | | Free | 500,000 | 5 | 1 | 1 | 2 | 2 | | Developer | 15,000,000 | 60 | 5 | 15 | 10 | 25 | | Business | 100,000,000 | 225 | 50 | 25 | 50 | 100 | | Professional | 250,000,000 | 500 | 100 | 50 | 100 | 250 | Requests above your rate limit return HTTP `429 Too Many Requests`. Slow the request queue and retry reads with bounded exponential backoff and jitter. Increasing concurrency does not increase the plan limit. ## Keep usage predictable * Use [V2 program queries](/solana-rpc/http/getprogramaccountsv2) and [V2 owner queries](/solana-rpc/http/gettokenaccountsbyownerv2) when their response format fits your app. * Reuse results when freshness permits. Choose a cache lifetime based on the data and commitment level. * Fetch several accounts with [getMultipleAccounts](/solana-rpc/http/getmultipleaccounts) when appropriate. Do not assume a JSON-RPC batch is charged as one method call. * Use [WebSocket subscriptions](/solana-rpc/subscriptions) for live changes and HTTP to load or recover state. * Track consumption in the [RPC dashboard](https://www.solanatracker.io/solana-rpc). ## Billing cycle and upgrades Credits reset at the start of each billing cycle; unused credits do not roll over. Upgrades apply the new allowance and limits immediately and restart the subscription. Review the dashboard before changing your plan. For account-specific billing or custom capacity, contact [support](mailto:contact@solanatracker.io). # getLookupTablesByAccount Source: https://docs.solanatracker.io/solana-rpc/http/getlookuptablesbyaccount getlookuptablesbyaccount post / Find address lookup tables containing a given account address. Find address lookup tables that contain a specific account. Useful when building transactions that reference accounts already stored in LUTs — the response includes the address index and estimated bytes saved for transaction compression. Optionally filter by LUT authority with the `owner` parameter. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLookupTablesByAccounts Source: https://docs.solanatracker.io/solana-rpc/http/getlookuptablesbyaccounts getlookuptablesbyaccounts post / Find tables containing all requested addresses or select a covering set with bestSet. `bestSet` uses a greedy selection strategy. Inspect `coveredAccounts` and `uncoveredAccounts`; the result is not a guarantee of the mathematically smallest set. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLookupTablesByAuthority Source: https://docs.solanatracker.io/solana-rpc/http/getlookuptablesbyauthority getlookuptablesbyauthority post / Find address lookup tables controlled by a wallet authority. Returns address lookup tables (LUTs) owned by a wallet authority. Use this to discover which LUTs a wallet controls, inspect their stored addresses, and check whether they are still active. Supports pagination via `cursor`, optional filtering to mint addresses only (`mintsOnly`), and inclusion of deactivated tables (`includeDeactivated`). This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLookupTablesByMint Source: https://docs.solanatracker.io/solana-rpc/http/getlookuptablesbymint getlookuptablesbymint post / Find address lookup tables containing a token mint. Find address lookup tables that contain a specific token mint. This is an alias of **getLookupTablesByAccount** — pass the mint address via the `mint` parameter instead of `account`. Response shape is identical. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getMultiplePrimaryDomains Source: https://docs.solanatracker.io/solana-rpc/http/getmultipleprimarydomains getmultipleprimarydomains post / Resolve primary .sol names for up to 100 wallets in input order. Batch primary `.sol` domain resolution for up to **100 wallets** in one request. Results are returned in the same order as the input wallet list. Ideal for dashboards, leaderboards, and any UI that displays wallet identity at scale without making individual SNS resolution calls. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getPrimaryDomain Source: https://docs.solanatracker.io/solana-rpc/http/getprimarydomain getprimarydomain post / Resolve a wallet’s primary SNS .sol name, when one is set. Resolve a wallet's primary `.sol` domain (Solscan-style favourite domain) in a single RPC call. Returns the display name with `.sol` suffix, or `null` if no primary domain is set or the favourite is no longer owned. Replaces the need to chain `getAccountInfo` and `getMultipleAccounts` for SNS resolution. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getPriorityFeeEstimate Source: https://docs.solanatracker.io/solana-rpc/http/getpriorityfeeestimate getpriorityfeeestimate post / Get priority-fee estimates for a transaction or a set of writable accounts. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getProgramAccountsV2 Source: https://docs.solanatracker.io/solana-rpc/http/getprogramaccountsv2 getprogramaccountsv2 post / Page through program-owned accounts with cursors and changedSince slot filtering. Pass the returned cursor with the same filters for the next page. `changedSince` filters accounts modified after a slot; it is not a stream of every intermediate write. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenAccountsByOwners Source: https://docs.solanatracker.io/solana-rpc/http/gettokenaccountsbyowners gettokenaccountsbyowners post / Query balances for one mint across up to 250 wallets in a single request. Get token balances for multiple wallets in a single request with **getTokenAccountsByOwners**. Powered by **Ridge DB**, our custom-built client designed for high-performance token account queries. Instead of making hundreds of individual requests, query up to 250 wallets at once for any token mint. Query up to 250 wallet addresses in one request to reduce API calls and latency. * If a wallet has multiple accounts for the same mint, the response returns all of them. * If a wallet has no token account, the response returns a clean zero balance instead of an error. * Each account includes the slot when the balance was last updated, which helps with caching and change tracking. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenAccountsByOwnerV2 Source: https://docs.solanatracker.io/solana-rpc/http/gettokenaccountsbyownerv2 gettokenaccountsbyownerv2 post / Page through a wallet’s token accounts with cursor, changedSince, and excludeZero filters. Use `excludeZero` to hide empty token accounts. Keep the same mint or program filter while paging through results. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # Solana RPC API reference and guides Source: https://docs.solanatracker.io/solana-rpc/index Read Solana accounts, send transactions, and subscribe to on-chain updates with Solana Tracker HTTP and WebSocket RPC. Use Solana RPC to query on-chain state, simulate and submit signed transactions, or subscribe to account and network updates. Solana Tracker exposes standard JSON-RPC methods alongside custom queries for token accounts, lookup tables, domains, and priority fees. ## Start with a request Send HTTP requests to `https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY`. For subscriptions, use `wss://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY`. Get an RPC API key from the [dashboard](https://www.solanatracker.io/solana-rpc). Read an account balance with curl or Node.js. Subscribe, read notifications, and unsubscribe. Check method costs and plan limits. See updates to the RPC API. ## Find the method you need * **Accounts and SOL balances:** start with [getAccountInfo](/solana-rpc/http/getaccountinfo), [getBalance](/solana-rpc/http/getbalance), or [getMultipleAccounts](/solana-rpc/http/getmultipleaccounts). * **Token holdings:** find a wallet's token accounts with [getTokenAccountsByOwnerV2](/solana-rpc/http/gettokenaccountsbyownerv2). Read supply with [getTokenSupply](/solana-rpc/http/gettokensupply). * **Transaction history:** list signatures with [getSignaturesForAddress](/solana-rpc/http/getsignaturesforaddress), then fetch details with [getTransaction](/solana-rpc/http/gettransaction). * **Transaction submission:** [simulate](/solana-rpc/http/simulatetransaction), [send](/solana-rpc/http/sendtransaction), and [check status](/solana-rpc/http/getsignaturestatuses). A returned signature does not mean the transaction is confirmed. * **Program accounts:** use [getProgramAccountsV2](/solana-rpc/http/getprogramaccountsv2) for cursor-based queries. Its response differs from the standard method. * **Lookup tables and domains:** follow the [lookup table guide](/guides/solana-rpc-lookup-tables) or [SNS guide](/guides/solana-rpc-sns-domains). ## Choose the right data interface RPC returns chain data and execution results. For indexed token prices, market data, and wallet analytics, use the [Data API guides](/guides/index). For filtered account and transaction streams over gRPC, use [Yellowstone gRPC](/yellowstone-grpc/index). Method names and parameters follow the [Solana JSON-RPC reference](https://solana.com/docs/rpc/http), except where a page describes a Solana Tracker custom method. # Solana RPC quickstart: make your first request Source: https://docs.solanatracker.io/solana-rpc/quickstart Call Solana Tracker RPC with curl and Node.js, authenticate with an API key, and handle HTTP and JSON-RPC errors. This guide reads an account's SOL balance over HTTP. Use a server-side script and an RPC API key from the [dashboard](https://www.solanatracker.io/solana-rpc). ## Call getBalance Set your API key, then run: ```bash theme={null} export SOLANA_RPC_API_KEY="YOUR_API_KEY" curl "https://rpc-mainnet.solanatracker.io/?api_key=${SOLANA_RPC_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["So11111111111111111111111111111111111111112",{"commitment":"confirmed"}]}' ``` Replace the example address with a wallet or account public key. The response contains `result.context.slot` and `result.value`. The value is in **lamports**, where 1 SOL equals 1,000,000,000 lamports; this method does not return SPL token holdings. ## Use Node.js Use Node.js 20 or later. Save this as `balance.mjs` and run it with the same environment variable. The helper checks both HTTP errors and JSON-RPC errors, which can be returned with HTTP 200. ```javascript balance.mjs theme={null} const apiKey = process.env.SOLANA_RPC_API_KEY; if (!apiKey) throw new Error("Set SOLANA_RPC_API_KEY before starting"); const endpoint = new URL("https://rpc-mainnet.solanatracker.io/"); endpoint.searchParams.set("api_key", apiKey); async function rpc(method, params = []) { const response = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }), signal: AbortSignal.timeout(15_000), }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const body = await response.json(); if (body.error) { throw new Error(`RPC ${body.error.code}: ${body.error.message}`); } return body.result; } const balance = await rpc("getBalance", [ "So11111111111111111111111111111111111111112", { commitment: "confirmed" }, ]); console.log({ slot: balance.context.slot, lamports: balance.value }); ``` ```bash theme={null} node balance.mjs ``` Keep API keys in server-side environment variables. Avoid putting the endpoint URL, including its key, into client bundles or logs. ## Choose commitment * `processed`: the node's most recent processed state; it can be rolled back. * `confirmed`: state voted on by a supermajority of stake. This example uses it for current reads. * `finalized`: state at the strongest commitment level, further behind the chain tip. Choose the same commitment when comparing related reads. Calls made separately can still return different context slots. Use [getMultipleAccounts](/solana-rpc/http/getmultipleaccounts) when you need several account values in one response. ## Handle failures For HTTP 429, reduce concurrency and retry reads with bounded backoff and jitter. Invalid parameters and authentication errors need a request or configuration fix. If a transaction submission times out, check its signature status before deciding how to retry; rebuilding and signing creates a different transaction. ## Next steps * [Read token accounts](/solana-rpc/http/gettokenaccountsbyownerv2). * [Subscribe to changes](/solana-rpc/subscriptions). * [Check request costs and rate limits](/solana-rpc/credits-and-rate-limits). # Recent changes Source: https://docs.solanatracker.io/solana-rpc/recent-changes New endpoints, added features, and fixes for Solana RPC. [View the full changelog](/changelog)
September 7–16, 2026
Data API Datastream Solana RPC PnL V2 General

Platform speed, Search API, RidgeDB, and dashboard updates

### Faster data, from indexing to delivery * **Search and holders:** faster Search API responses and improved holder data performance. * **Token coverage:** support for all quote tokens on Meteora Curve, Raydium LaunchLab, and Pump.fun, plus Pump.fun `isHolderReward` and Transaction V1 support. * **Indexing and streaming:** rebuilt metadata indexing, RidgeDB, and Ridge streaming for improved speed, accuracy, and efficiency across Data API and RPC services. * **PnL V2:** improved redundancy and accuracy. ### More ways to manage your subscription * **Teams:** invite teammates and manage their access on Premium, Business, and dedicated node plans. * **On-chain USDC subscriptions:** automatic renewals and top-ups using native USDC on Solana.
June 2026
Solana RPC

Ridge custom RPC — Address Lookup Tables & SNS Domains

Eight new Ridge DB-powered RPC methods for address lookup table queries and Solana Name Service (`.sol`) resolution. Each method costs **1 credit** per call. ### Address Lookup Tables * **`getLookupTablesByAuthority`** — LUTs owned by a wallet authority * **`getLookupTablesByAccount`** — LUTs containing a specific account * **`getLookupTablesByMint`** — LUTs containing a token mint * **`getLookupTablesByAccounts`** — LUTs containing all listed accounts, or a minimal LUT set with `bestSet: true` ### SNS Domains * **`getPrimaryDomain`** — Primary `.sol` domain for a wallet * **`getMultiplePrimaryDomains`** — Batch primary domains (up to 100 wallets) * **`getAllDomains`** — All `.sol` names owned by a wallet * **`resolveSolDomain`** — Forward resolution: `name.sol` → owner ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getPrimaryDomain", "params": ["9aoUCn5J4sxhvYERCVwVnakPQxyXTHQVXe86CUJYxY8p"] } ``` Resolve SNS identity and find LUTs for transaction compression in a single RPC call — no need to chain `getAccountInfo` / `getMultipleAccounts`.
April 2026
Data API Datastream Solana RPC General

Performance improvements, new load balancers, and reduced latency

### Infrastructure * **Improved shred delivery** — Faster shred delivery for improved block propagation. * **New global load balancer for Data API** — Added a global load balancer for the Data API. * **New US-based Data API load balancer** — Dedicated US load balancer for lower-latency access. * **Colocated US servers** — Some endpoints dropped from 600ms response times to under 100ms. * **Migrated and upgraded ClickHouse cluster** — Better latency and faster queries across the API. ### Data API * **Improved trades endpoint speeds** — All trades endpoints are now faster. * **Improved `/chart` response speed** — Faster chart data retrieval. * **Improved `/tokens/:token` response time** — Faster token detail lookups. * **Improved metadata retrieval speed** — Faster metadata fetching across endpoints. * **Improved `/wallet/:wallet/chart` endpoint** — Now returns a chart even with only 1 data point. * **Fixed pagination bug on ascending trades** — Fixed a pagination issue when fetching trades in ascending order. * **Fixed Meteora DAMM liquidity** — Resolved a liquidity calculation issue on some older Meteora DAMM pools. * **Fixed PumpFun token creation edge cases** — Resolved edge cases on token creation events. * **Imported all missing PumpFun curve data** — Backfilled 15M+ tokens of PumpFun curve data. * **Fixed curve pools on `/tokens/:token`** — Curve pools (5+) now always appear after migration. * **Fixed Axiom transaction fee parser** — Moved from transfer to internal CPI call for accurate fee parsing. * **`uniqueTokens` query param on deployers API** — Returns latest graduated pool and first non-graduated pool in the regular list. * **Raydium LaunchLab tweaks** — Adjustments for Raydium LaunchLab support. * **Raydium CPMM improvements** — Improved Raydium CPMM handling. * **Search API bug fixes** — Various fixes to the search endpoint. ### Ridge DB * **Improved performance** — Improved indexes and response times across several queries. * **Globally load balanced** — US RPC users can now call methods like `getProgramAccounts`, `getProgramAccountsV2`, etc. around 200–400ms faster. * **Fixed frozen token account decoding** — Frozen token accounts now always show and decode properly. ### Datastream * **Improved Datastream performance** — Improved price, pool, and transaction update latency.
November 2025
Solana RPC

Batch Token Balance Queries

We've added a new Ridge DB-powered RPC method that lets you query token balances for multiple wallets in a single request. ### What's New **`getTokenAccountsByOwners`** * **Batch up to 250 wallets** — Query hundreds of addresses in one call instead of making individual requests * **Multiple accounts support** — Automatically returns all token accounts if a wallet has multiple for the same mint * **Zero balance handling** — Wallets without a token account return a clean zero balance response * **Slot tracking** — Each account includes the slot when the balance was last updated ### Use Cases Perfect for: * Portfolio tracking across multiple wallets * Airdrop eligibility verification * Multi-wallet dashboards * Token distribution snapshots ```json theme={null} { "jsonrpc": "2.0", "id": 1, "method": "getTokenAccountsByOwners", "params": [ ["wallet1...", "wallet2...", "wallet3..."], "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ] } ``` This method drastically reduces API calls and latency when you need to check token holdings across many addresses at once.
October 21 2025
Solana RPC

RPC Enhancements

## Ridge DB Performance & Features Update We've shipped several improvements to our Ridge DB-powered RPC methods to give you even more control and speed. ### What's New * **Total count support** — `getProgramAccountsV2` and `getTokenAccountsByOwnerV2` now return `totalCount` in responses, making pagination and UI updates easier * **Faster queries** — New indexes dramatically improve response times for certain account lookups * **Stability improvements** — Bug fixes and optimizations These updates build on our Ridge DB launch, delivering better performance and more developer-friendly responses.
October 16 2025
Solana RPC

Ridge DB Launch

We've rolled out **two new RPC methods** powered by **Ridge DB** — our high-performance engine designed for lightning-fast account lookups on Solana. ### 🧭 New Methods #### `getProgramAccountsV2` Supercharged program account queries with: * **`changedSince`** — Fetch only accounts updated after a given slot (great for incremental syncs) * **`excludeZero`** — Automatically skip empty token accounts * **Cursor pagination** — Retrieve up to 10,000 accounts per request #### `getTokenAccountsByOwnerV2` Optimized token account retrieval, featuring the same Ridge DB speed and: * **`changedSince`** — Get only new or updated token accounts * **`excludeZero`** — Filter out dust or empty balances * **Cursor pagination** — Smoothly handle large token sets ### 💡 Why Ridge DB? Ridge DB isn't your standard RPC backend. It's a purpose-built system for account-heavy workloads that delivers: * Faster response times * Slot-based incremental updates * Cursor pagination for big datasets In short — faster queries, cleaner data, and a smoother developer experience.
# Solana RPC WebSocket subscriptions Source: https://docs.solanatracker.io/solana-rpc/subscriptions Subscribe to Solana account changes, handle subscription IDs, unsubscribe cleanly, and recover after a WebSocket disconnect. Use WebSocket subscriptions for changes after a connection is established. Fetch an HTTP snapshot when you also need the current state; a subscription is not a history query. ## Connect and subscribe Use Node.js 20 or later. Install `ws`, set an RPC API key, and choose an account that changes regularly: ```bash theme={null} npm install ws export SOLANA_RPC_API_KEY="YOUR_API_KEY" export ACCOUNT_ADDRESS="ACCOUNT_PUBLIC_KEY" ``` Save this as `accounts.mjs`, run `node accounts.mjs`, and stop with Ctrl+C. The example unsubscribes before closing when a subscription ID is available. ```javascript accounts.mjs theme={null} import WebSocket from "ws"; const apiKey = process.env.SOLANA_RPC_API_KEY; const account = process.env.ACCOUNT_ADDRESS; if (!apiKey || !account) { throw new Error("Set SOLANA_RPC_API_KEY and ACCOUNT_ADDRESS"); } const endpoint = new URL("wss://rpc-mainnet.solanatracker.io/"); endpoint.searchParams.set("api_key", apiKey); const socket = new WebSocket(endpoint); let subscriptionId; let stopping = false; let closeTimer; function unsubscribe() { socket.send(JSON.stringify({ jsonrpc: "2.0", id: 2, method: "accountUnsubscribe", params: [subscriptionId], })); } socket.on("open", () => { socket.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "accountSubscribe", params: [account, { encoding: "base64", commitment: "confirmed" }], })); }); socket.on("message", raw => { let message; try { message = JSON.parse(raw.toString()); } catch { console.error("Invalid JSON received"); return; } if (message.error) { console.error("RPC error", message.error); socket.close(); return; } if (message.id === 1) { subscriptionId = message.result; console.log("Subscribed", subscriptionId); if (stopping) unsubscribe(); } else if (message.id === 2) { console.log("Unsubscribed", message.result); socket.close(); } else if (message.method === "accountNotification" && message.params.subscription === subscriptionId) { const { context, value } = message.params.result; console.log({ slot: context.slot, lamports: value.lamports }); } }); socket.on("error", error => console.error("WebSocket error", error.message)); socket.on("close", () => { clearTimeout(closeTimer); console.log("Connection closed"); }); process.once("SIGINT", () => { stopping = true; closeTimer = setTimeout(() => socket.terminate(), 3_000); if (socket.readyState === WebSocket.OPEN && subscriptionId !== undefined) { unsubscribe(); } else if (socket.readyState !== WebSocket.OPEN) { socket.terminate(); } }); ``` A successful subscribe response confirms the subscription, not an account change. No notifications arrive until the account changes at the requested commitment. ## Request IDs and subscription IDs The `id` you send identifies a request and its response. The server returns a separate subscription ID in `result`. Notifications carry that ID in `params.subscription`; pass it to the matching unsubscribe method on the same connection. ## Choose a subscription * [accountSubscribe](/solana-rpc/websockets/accountsubscribe): changes to one account's lamports or data. * [programSubscribe](/solana-rpc/websockets/programsubscribe): writes to accounts owned by a program. * [logsSubscribe](/solana-rpc/websockets/logssubscribe): transaction logs matching the filter. * [signatureSubscribe](/solana-rpc/websockets/signaturesubscribe): a signature reaching the requested commitment; this subscription ends after the terminal notification. * [slotSubscribe](/solana-rpc/websockets/slotsubscribe): processed slot updates. See the [Solana WebSocket reference](https://solana.com/docs/rpc/websocket) for standard notification semantics. Shredstream delivers transactions before execution metadata is available. Treat them as provisional and confirm their outcome through RPC. ## Recover after a disconnect Reconnect with bounded backoff and jitter, then send the subscription requests again. IDs from the old connection cannot be reused. Refetch current account state over HTTP and reconcile it with buffered notifications using context slots. Recover transaction history separately when every event matters; reconnecting does not replay missed updates. Keep a bounded processing queue and monitor its size. If the consumer falls behind, reduce the subscription scope or move expensive decoding out of the message callback. Check your plan's [connection limits](/solana-rpc/credits-and-rate-limits). # getAccountInfo Source: https://docs.solanatracker.io/solana-rpc/http/getaccountinfo getaccountinfo post / Read an account’s lamports, program owner, executable flag, and encoded data. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getAllDomains Source: https://docs.solanatracker.io/solana-rpc/http/getalldomains getalldomains post / List the .sol domains owned by a wallet, including tokenized domains. Returns all `.sol` domain names owned by a wallet, including direct ownership and tokenized NFT domains. Use this when you need the full domain portfolio for a wallet, not just the primary favourite. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBalance Source: https://docs.solanatracker.io/solana-rpc/http/getbalance getbalance post / Read an account’s native SOL balance in lamports. One SOL is 1,000,000,000 lamports. For SPL tokens, query a token account with `getTokenAccountBalance`. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlock Source: https://docs.solanatracker.io/solana-rpc/http/getblock getblock post / Fetch a confirmed block by slot, with transaction details in the requested encoding. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlockCommitment Source: https://docs.solanatracker.io/solana-rpc/http/getblockcommitment getblockcommitment post / Inspect the stake commitment reported for a slot. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlockHeight Source: https://docs.solanatracker.io/solana-rpc/http/getblockheight getblockheight post / Read the current block height at your chosen commitment level. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlockProduction Source: https://docs.solanatracker.io/solana-rpc/http/getblockproduction getblockproduction post / Compare blocks produced and leader slots across validators in a slot range. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlocks Source: https://docs.solanatracker.io/solana-rpc/http/getblocks getblocks post / List confirmed block slots between a start slot and an optional end slot. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlocksWithLimit Source: https://docs.solanatracker.io/solana-rpc/http/getblockswithlimit getblockswithlimit post / List up to a specified number of confirmed blocks from a starting slot. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getBlockTime Source: https://docs.solanatracker.io/solana-rpc/http/getblocktime getblocktime post / Get a block’s estimated production time as a Unix timestamp. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getClusterNodes Source: https://docs.solanatracker.io/solana-rpc/http/getclusternodes getclusternodes post / Inspect RPC, gossip, and TPU addresses advertised by cluster nodes. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getEpochInfo Source: https://docs.solanatracker.io/solana-rpc/http/getepochinfo getepochinfo post / Read the current epoch, slot position, and block height. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getEpochSchedule Source: https://docs.solanatracker.io/solana-rpc/http/getepochschedule getepochschedule post / Read the cluster’s epoch length, warmup configuration, and leader schedule offset. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getFeeForMessage Source: https://docs.solanatracker.io/solana-rpc/http/getfeeformessage getfeeformessage post / Estimate the network fee in lamports for a serialized transaction message. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getFirstAvailableBlock Source: https://docs.solanatracker.io/solana-rpc/http/getfirstavailableblock getfirstavailableblock post / Find the earliest confirmed block available from the RPC node. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getGenesisHash Source: https://docs.solanatracker.io/solana-rpc/http/getgenesishash getgenesishash post / Read the genesis hash to identify the cluster you are connected to. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getHealth Source: https://docs.solanatracker.io/solana-rpc/http/gethealth gethealth post / Check whether the RPC node considers itself healthy relative to the cluster. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getHighestSnapshotSlot Source: https://docs.solanatracker.io/solana-rpc/http/gethighestsnapshotslot gethighestsnapshotslot post / Read the highest full and incremental snapshot slots available on the node. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getIdentity Source: https://docs.solanatracker.io/solana-rpc/http/getidentity getidentity post / Read the RPC node’s identity public key. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getInflationGovernor Source: https://docs.solanatracker.io/solana-rpc/http/getinflationgovernor getinflationgovernor post / Inspect the inflation parameters configured for the cluster. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getInflationRate Source: https://docs.solanatracker.io/solana-rpc/http/getinflationrate getinflationrate post / Read total, validator, and foundation inflation rates for the current epoch. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getInflationReward Source: https://docs.solanatracker.io/solana-rpc/http/getinflationreward getinflationreward post / Look up inflation rewards for a list of addresses and an epoch. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLargestAccounts Source: https://docs.solanatracker.io/solana-rpc/http/getlargestaccounts getlargestaccounts post / List the 20 largest accounts by native SOL balance. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLatestBlockhash Source: https://docs.solanatracker.io/solana-rpc/http/getlatestblockhash getlatestblockhash post / Get a recent blockhash and its last valid block height for a new transaction. Store `lastValidBlockHeight` with the blockhash. Compare it with block height, not slot number, when checking expiry. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getLeaderSchedule Source: https://docs.solanatracker.io/solana-rpc/http/getleaderschedule getleaderschedule post / Look up the validator assigned to each leader slot in an epoch. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getMaxRetransmitSlot Source: https://docs.solanatracker.io/solana-rpc/http/getmaxretransmitslot getmaxretransmitslot post / Read the highest slot observed by the node’s retransmit stage. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getMaxShredInsertSlot Source: https://docs.solanatracker.io/solana-rpc/http/getmaxshredinsertslot getmaxshredinsertslot post / Read the highest slot for which the node has inserted shreds into its blockstore. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getMinimumBalanceForRentExemption Source: https://docs.solanatracker.io/solana-rpc/http/getminimumbalanceforrentexemption getminimumbalanceforrentexemption post / Calculate the lamport balance needed for a rent-exempt account of a given size. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getMultipleAccounts Source: https://docs.solanatracker.io/solana-rpc/http/getmultipleaccounts getmultipleaccounts post / Read several accounts in one request, preserving the input address order. Match each result to the same input index. A missing account returns `null`; do not remove it before matching addresses. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getProgramAccounts Source: https://docs.solanatracker.io/solana-rpc/http/getprogramaccounts getprogramaccounts post / Find accounts owned by a program, filtered by data size or byte content. Need to track only new accounts? Use `changedSince` to fetch accounts modified after a specific slot, so you do not have to reload everything. Use cursor pagination to retrieve all matching accounts efficiently, up to 10k per request. **High Load Considerations** This endpoint streams all accounts directly to your client. While this works great for most queries, it can return errors during high load or when querying programs with millions of accounts (like liquidity pools or protocol-owned accounts). **Need better reliability?** Use **[getProgramAccountsV2](/solana-rpc/http/getprogramaccountsv2)** instead. The V2 method includes pagination support, making it more efficient and reliable for large programs and high-traffic scenarios. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getRecentPerformanceSamples Source: https://docs.solanatracker.io/solana-rpc/http/getrecentperformancesamples getrecentperformancesamples post / Read recent samples of slots, transactions, and sample duration. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getRecentPrioritizationFees Source: https://docs.solanatracker.io/solana-rpc/http/getrecentprioritizationfees getrecentprioritizationfees post / Inspect recent prioritization-fee samples, optionally scoped to writable accounts. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSignaturesForAddress Source: https://docs.solanatracker.io/solana-rpc/http/getsignaturesforaddress getsignaturesforaddress post / Page through transaction signatures that reference a wallet, account, or program. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSignatureStatuses Source: https://docs.solanatracker.io/solana-rpc/http/getsignaturestatuses getsignaturestatuses post / Check the execution and confirmation status of transaction signatures. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSlot Source: https://docs.solanatracker.io/solana-rpc/http/getslot getslot post / Read the highest slot reached at the requested commitment level. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSlotLeader Source: https://docs.solanatracker.io/solana-rpc/http/getslotleader getslotleader post / Get the validator scheduled to lead the current slot. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSlotLeaders Source: https://docs.solanatracker.io/solana-rpc/http/getslotleaders getslotleaders post / List the scheduled leaders for a sequence of slots. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getStakeMinimumDelegation Source: https://docs.solanatracker.io/solana-rpc/http/getstakeminimumdelegation getstakeminimumdelegation post / Read the minimum stake delegation amount in lamports. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getSupply Source: https://docs.solanatracker.io/solana-rpc/http/getsupply getsupply post / Read total, circulating, and non-circulating SOL supply. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenAccountBalance Source: https://docs.solanatracker.io/solana-rpc/http/gettokenaccountbalance gettokenaccountbalance post / Read the balance and decimals of one SPL token account. Pass a token account address, not the wallet address or mint. Use `amount` and `decimals` for exact calculations. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenAccountsByDelegate Source: https://docs.solanatracker.io/solana-rpc/http/gettokenaccountsbydelegate gettokenaccountsbydelegate post / Find token accounts that authorize an address as their delegate. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenAccountsByOwner Source: https://docs.solanatracker.io/solana-rpc/http/gettokenaccountsbyowner gettokenaccountsbyowner post / Find token accounts owned by a wallet, filtered by mint or Token Program. Need to track only new tokens? Use `changedSince` to fetch accounts modified after a specific slot, perfect for incremental portfolio updates. Want to filter out dust? The `excludeZero` parameter automatically hides empty token accounts, keeping your results clean and reducing bandwidth. **High Load Considerations** This endpoint streams all token accounts directly to your client. While this works great for most wallets, it can return errors during high load or when querying owners with millions of token accounts, such as protocol-owned accounts. **Need better reliability?** Use **[getTokenAccountsByOwnerV2](/solana-rpc/http/gettokenaccountsbyownerv2)** instead. The V2 method includes pagination support, making it more efficient and reliable for large wallets and high-traffic scenarios. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenLargestAccounts Source: https://docs.solanatracker.io/solana-rpc/http/gettokenlargestaccounts gettokenlargestaccounts post / List the 20 largest token accounts for an SPL token mint. Results are token accounts, not unique wallets. One wallet can own more than one token account. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTokenSupply Source: https://docs.solanatracker.io/solana-rpc/http/gettokensupply gettokensupply post / Read an SPL token mint’s supply, decimals, and display amount. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTransaction Source: https://docs.solanatracker.io/solana-rpc/http/gettransaction gettransaction post / Fetch a confirmed transaction by signature, including execution metadata. Use `maxSupportedTransactionVersion: 0` when accepting legacy and v0 transactions. A `null` result can mean the transaction is not available at the requested commitment. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getTransactionCount Source: https://docs.solanatracker.io/solana-rpc/http/gettransactioncount gettransactioncount post / Read the number of transactions processed at the requested commitment. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getVersion Source: https://docs.solanatracker.io/solana-rpc/http/getversion getversion post / Read the node’s Solana software version and feature-set identifier. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # getVoteAccounts Source: https://docs.solanatracker.io/solana-rpc/http/getvoteaccounts getvoteaccounts post / Inspect current and delinquent validator vote accounts and their stake. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # isBlockhashValid Source: https://docs.solanatracker.io/solana-rpc/http/isblockhashvalid isblockhashvalid post / Check whether a blockhash is still valid at the requested commitment. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # minimumLedgerSlot Source: https://docs.solanatracker.io/solana-rpc/http/minimumledgerslot minimumledgerslot post / Find the lowest slot still present in the node’s local ledger. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # requestAirdrop Source: https://docs.solanatracker.io/solana-rpc/http/requestairdrop requestairdrop post / Request SOL from a faucet on a cluster that supports airdrops. The documented Solana Tracker endpoint is mainnet. Airdrops are for supported test clusters; this method does not provide free mainnet SOL. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # resolveSolDomain Source: https://docs.solanatracker.io/solana-rpc/http/resolvesoldomain resolvesoldomain post / Resolve a .sol domain or supported subdomain to its owner wallet. Forward resolution: `.sol` domain name → owner wallet and name registry account. Supports root domains (`name.sol`) and one-level subdomains (`sub.parent.sol`). Returns `null` when the domain is not found. Twitter/X handles (`.twitter` TLD) are not supported. This method costs **1 credit** per call. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # sendTransaction Source: https://docs.solanatracker.io/solana-rpc/http/sendtransaction sendtransaction post / Submit a signed transaction to the cluster and receive its signature. A returned signature means the RPC accepted the submission. Check `getSignatureStatuses` or `signatureSubscribe` for execution and confirmation. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # simulateTransaction Source: https://docs.solanatracker.io/solana-rpc/http/simulatetransaction simulatetransaction post / Inspect transaction logs, errors, and compute usage without submitting the transaction. Simulation does not reserve liquidity or guarantee later execution. Inspect `err` and `logs`, then obtain a valid blockhash before sending. Request setup and error handling: [RPC quickstart](/solana-rpc/quickstart). Billing: [credits and limits](/solana-rpc/credits-and-rate-limits). # Account subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/accountsubscribe Subscribe to changes to one account’s lamports or data. Save the subscription ID returned in result and match it against params.subscription in notifications. Use accountUnsubscribe on the same connection to stop the stream. # Account unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/accountunsubscribe Cancel a account subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Block subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/blocksubscribe Subscribe to blocks matching the account filter at the requested commitment. Save the subscription ID returned in result and match it against params.subscription in notifications. Use blockUnsubscribe on the same connection to stop the stream. # Block unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/blockunsubscribe Cancel a block subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Logs subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/logssubscribe Subscribe to transaction logs matching the selected filter. Save the subscription ID returned in result and match it against params.subscription in notifications. Use logsUnsubscribe on the same connection to stop the stream. # Logs unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/logsunsubscribe Cancel a logs subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Program subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/programsubscribe Subscribe to writes to accounts owned by the specified program. Save the subscription ID returned in result and match it against params.subscription in notifications. Use programUnsubscribe on the same connection to stop the stream. # Program unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/programunsubscribe Cancel a program subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Root subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/rootsubscribe Subscribe to changes to the validator’s root slot. Save the subscription ID returned in result and match it against params.subscription in notifications. Use rootUnsubscribe on the same connection to stop the stream. # Root unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/rootunsubscribe Cancel a root subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Shred subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/shredsubscribe Subscribe to transactions reconstructed from shreds before execution metadata is available. Save the subscription ID returned in result and match it against params.subscription in notifications. Use shredUnsubscribe on the same connection to stop the stream. Events are provisional and do not include execution metadata. Confirm the signature through RPC before treating it as settled activity. # Shred unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/shredunsubscribe Cancel a shred subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Signature subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/signaturesubscribe Subscribe to a transaction signature reaching the requested commitment. Save the subscription ID returned in result and match it against params.subscription in notifications. Use signatureUnsubscribe on the same connection to stop the stream. The subscription closes automatically after the terminal signature notification; a receivedSignature notification is not confirmation. # Signature unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/signatureunsubscribe Cancel a signature subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Slot subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/slotsubscribe Subscribe to processed slots, including their parent and root. Save the subscription ID returned in result and match it against params.subscription in notifications. Use slotUnsubscribe on the same connection to stop the stream. # Slots updates subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/slotsupdatessubscribe Subscribe to slot lifecycle updates with their update type and timestamp. Save the subscription ID returned in result and match it against params.subscription in notifications. Use slotsUpdatesUnsubscribe on the same connection to stop the stream. # Slots updates unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/slotsupdatesunsubscribe Cancel a slotsUpdates subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Slot unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/slotunsubscribe Cancel a slot subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Vote subscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/votesubscribe Subscribe to vote transactions observed by the validator. Save the subscription ID returned in result and match it against params.subscription in notifications. Use voteUnsubscribe on the same connection to stop the stream. # Vote unsubscribe Source: https://docs.solanatracker.io/solana-rpc/websockets/voteunsubscribe Cancel a vote subscription on the connection that created it. Pass the server-returned subscription ID, not the JSON-RPC request ID. The response is a boolean. # Stream Solana account updates with gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/account-monitoring Subscribe to Solana account changes with Yellowstone gRPC. Filter by address, program owner, data size, or memcmp and request byte slices. Subscribe to account writes when you need updated balances or program state. An `owner` filter means the program that owns an account, not the wallet that owns tokens inside it. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Watch one account ```typescript accounts.mts theme={null} import bs58 from "bs58"; import { subscribe } from "./stream.mts"; const address = process.env.ACCOUNT_ADDRESS; if (!address) throw new Error("Set ACCOUNT_ADDRESS"); for await (const update of subscribe({ accounts: { selected: { account: [address], owner: [], filters: [] } }, })) { const account = update.account?.account; if (!account) continue; console.log({ address: bs58.encode(account.pubkey), owner: bs58.encode(account.owner), lamports: account.lamports, slot: update.account!.slot, writeVersion: account.writeVersion, dataBytes: account.data.length, }); } ``` ```bash theme={null} export ACCOUNT_ADDRESS="YOUR_ACCOUNT_ADDRESS" npx tsx accounts.mts ``` ## Filter program accounts This request selects legacy SPL Token accounts for one mint and downloads only their amount field. Pass `request` to `subscribe(request)` in place of the previous account filter. ```typescript theme={null} import { makeRequest } from "./stream.mts"; const tokenProgram = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"; const mint = process.env.TOKEN_MINT; if (!mint) throw new Error("Set TOKEN_MINT"); const request = makeRequest({ accounts: { tokenAccounts: { account: [], owner: [tokenProgram], filters: [ { datasize: "165" }, { memcmp: { offset: "0", base58: mint } }, ], }, }, accountsDataSlice: [{ offset: "64", length: "8" }], }); ``` The spelling is `datasize`, and offsets are strings in this client. Filters within one named account filter are combined; named filters can be used for separate selections. ## Decode sliced token amounts Inside the account handler, decode the eight-byte slice as an unsigned little-endian integer: ```typescript theme={null} // A slice of bytes 64–71 from a legacy SPL token account contains its amount. const amount = Buffer.from(account.data).readBigUInt64LE(0); console.log(amount.toString()); ``` The 165-byte size and offsets above describe legacy SPL Token accounts. Token-2022 extensions can change account size. Do not apply this filter to every token program without checking its layout. ## Keep state after a disconnect Store the account address, slot, and write version with each update. Refresh a REST/RPC snapshot after a gap before treating the local cache as current. A wallet-address subscription alone does not cover its separate token accounts. ## Related guides # Authenticate a Yellowstone gRPC client Source: https://docs.solanatracker.io/yellowstone-grpc/authentication Configure Yellowstone gRPC x-token authentication, select an EU or US endpoint, and troubleshoot connection errors. Use the gRPC token from your RPC dashboard. gRPC authenticates with `x-token`; the Data API’s `x-api-key` header is a different interface. ## Check your credentials Install the dependencies and set the environment variables from the [quickstart](/yellowstone-grpc/quickstart). Then save the following connection check as `check-connection.mts`. ```typescript check-connection.mts theme={null} import Yellowstone from "@triton-one/yellowstone-grpc"; const Client = typeof Yellowstone === "function" ? Yellowstone : Yellowstone.default; const token = process.env.GRPC_API_TOKEN; if (!token) throw new Error("Set GRPC_API_TOKEN"); const client = new Client( process.env.GRPC_ENDPOINT ?? "https://grpc.solanatracker.io", token, undefined, ); console.log(await client.getVersion()); ``` ```bash theme={null} npx tsx check-connection.mts ``` A version response verifies the endpoint and token. Next, run the quickstart subscription to verify streaming access. ## Choose a region * **EU:** `https://grpc.solanatracker.io` * **US:** `https://grpc-us.solanatracker.io` Measure from your deployment host. Network distance, routing, processing time, and subscription load all affect delivery latency. ## Troubleshoot connection errors * **Unauthenticated:** check that `GRPC_API_TOKEN` is set, contains no extra whitespace, and belongs to an active subscription. * **Timeout or unavailable:** verify the URL and outbound TLS/HTTP2 access; then try the other region. * **Resource exhausted:** inspect the error detail. Check connection allowances and message-size limits separately; increasing the receive limit does not fix a quota error. * **Connected but no updates:** start with `blocksMeta: { blocks: {} }`. Then reapply your filters one at a time. ## Store the token Read tokens from environment variables or your secret store. Keep them out of logs, client-side bundles, and committed examples. Restart or reconnect clients after rotating a token. ## Related guides # Handle Yellowstone gRPC reconnects and stream load Source: https://docs.solanatracker.io/yellowstone-grpc/best-practices Plan Yellowstone gRPC reconnects, gap recovery, bounded queues, message limits, and monitoring for a long-running consumer. A long-running consumer needs a recovery plan as well as a fast connection. Measure incoming rate, processing rate, and lag before changing concurrency or server settings. ## Keep the working set small Filter by address or program before decoding. Prefer block metadata when you only need hashes and counts. Slice account data only when the decoder expects that slice. Group quiet subscriptions on one connection; split high-volume programs after measurements show contention. ## Bound work and memory Awaiting an async handler controls concurrency, but it does not make CPU-heavy work parallel. Use a bounded queue and workers for expensive parsing. Define what happens when the queue fills: pause, sample disposable metrics, or stop and recover durable data. Track queue depth and the oldest pending slot. ## Reconnect with a retry budget Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. This example retries the metadata stream with backoff and jitter, then exits after eight interruptions. Authentication failures should be corrected before restarting. ```typescript reconnect.mts theme={null} import { setTimeout as delay } from "node:timers/promises"; import { subscribe } from "./stream.mts"; let retry = 0; while (retry < 8) { try { for await (const update of subscribe({ blocksMeta: { blocks: {} } })) { if (update.blockMeta) console.log(update.blockMeta.slot); } console.error("Stream ended"); } catch (error) { console.error("Stream failed", error); } retry += 1; const waitMs = Math.min(30_000, 500 * 2 ** retry) + Math.random() * 500; await delay(waitMs); } throw new Error("Reconnect budget exhausted"); ``` ## Recover gaps explicitly Persist progress only after the downstream write succeeds. Reconnect with the full subscription and reconcile the missing range using available RPC history or a fresh account snapshot. Use replay only when your endpoint confirms support and retention; do not assume every stream can replay arbitrary slots. Deduplicate replayed updates. ## Tune from measurements * Compare EU and US delivery from the deployment host. ICMP ping alone does not measure stream latency. * If a message exceeds the client limit, first reduce the payload. Configure a larger receive limit using the options supported by your client version and budget for its memory cost. * Respond to server pings. Transport keepalive and subscription ping messages are different mechanisms. * Alert on repeated disconnects, decode errors, growing queues, stalled progress, and write failures. * Test interruption and recovery with your actual downstream database before relying on the consumer. ## Related guides # Read Solana entry metadata with Yellowstone gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/entry-monitoring Stream entry hashes, indexes, and transaction counts. Use transaction or block subscriptions when you need transaction payloads. The entry stream exposes Proof of History entry metadata: hashes, indexes, and transaction counts. It does not contain transaction bodies, execution logs, or per-transaction success flags. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Subscribe to entry metadata ```typescript entries.mts theme={null} import { subscribe } from "./stream.mts"; for await (const update of subscribe({ entry: { entries: {} } })) { const entry = update.entry; if (!entry) continue; console.log({ slot: entry.slot, index: entry.index, hash: Buffer.from(entry.hash).toString("hex"), numHashes: entry.numHashes, transactionCount: entry.executedTransactionCount, startingTransactionIndex: entry.startingTransactionIndex, }); } ``` ```bash theme={null} npx tsx entries.mts ``` ## Read entry fields * `slot` and `index` locate the entry within a slot. * `hash` is binary; the example displays it as hex. * `numHashes` records the hash count for the entry. * `executedTransactionCount` is a count, not a transaction array. * `startingTransactionIndex` locates its first transaction within the block. Keep 64-bit values as strings or `BigInt`. A zero transaction count is valid. ## Filter and correlate The entry filter has no account or program fields. Filter by slot or sample updates in your consumer. For instruction parsing, vote filtering, or execution results, join transaction or block data by slot and transaction index. Do not infer those details from entry counts. ## Related guides # Decode Pump.fun bonding curves with Yellowstone gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/examples/pumpfun-accounts Stream Pump.fun bonding curve accounts, decode them with the bundled Anchor IDL, and preserve raw reserve amounts. Subscribe to Pump.fun bonding curve account writes and decode their reserves and completion flag. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Install the decoder and IDL ```bash theme={null} npm install @coral-xyz/anchor @solana/web3.js curl -L https://docs.solanatracker.io/idl/pump.json -o pump.json ``` Use the [bundled Pump.fun IDL](/idl/pump.json) with this example. It supplies the program address, discriminators, and field names; check compatibility when updating it. ## Decode updates ```typescript pump-accounts.mts theme={null} import { readFileSync } from "node:fs"; import { BorshAccountsCoder, type Idl } from "@coral-xyz/anchor"; import bs58 from "bs58"; import { subscribe } from "./stream.mts"; const idl = JSON.parse(readFileSync("pump.json", "utf8")) as Idl; const coder = new BorshAccountsCoder(idl); const definition = idl.accounts?.find(account => account.name === "BondingCurve"); if (!definition) throw new Error("BondingCurve is missing from the IDL"); const discriminator = Buffer.from(definition.discriminator); for await (const update of subscribe({ accounts: { curves: { account: [], owner: [idl.address], filters: [{ memcmp: { offset: "0", bytes: discriminator } }], }, }, })) { const account = update.account?.account; if (!account) continue; try { const curve = coder.decode("BondingCurve", Buffer.from(account.data)); console.log({ address: bs58.encode(account.pubkey), slot: update.account!.slot, complete: curve.complete, quoteMint: curve.quote_mint.toString(), virtualTokenReserves: curve.virtual_token_reserves.toString(), virtualQuoteReserves: curve.virtual_quote_reserves.toString(), }); } catch (error) { console.error("Bonding curve decode failed; check IDL compatibility", error); } } ``` ```bash theme={null} npx tsx pump-accounts.mts ``` ## Read reserves without rounding The example prints raw reserve integers as strings. Derive display amounts with the token and quote mint decimals. A raw reserve ratio is not a price in SOL per token, and `quote_mint` is not always SOL. Check the current mint data before formatting a price. ## Handle layout changes The discriminator filter identifies the account type without assuming a fixed total size. Decode errors remain visible rather than silently dropping updates. A completed curve does not provide the full migrated pool state; use the PumpSwap reference or Data API for the new pool. ## Related guides # Decode Pump.fun trades with Yellowstone gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/examples/pumpfun-transactions Subscribe to Pump.fun transactions, decode TradeEvent logs with Anchor, and extract traders, mints, and raw token amounts. Subscribe to executed Pump.fun transactions and decode `TradeEvent` logs. Each transaction can contain more than one trade event. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Install the decoder and IDL ```bash theme={null} npm install @coral-xyz/anchor @solana/web3.js curl -L https://docs.solanatracker.io/idl/pump.json -o pump.json ``` Use the [bundled Pump.fun IDL](/idl/pump.json) with this example. It supplies the program address, discriminators, and field names; check compatibility when updating it. ## Decode updates ```typescript pump-trades.mts theme={null} import { readFileSync } from "node:fs"; import { BorshCoder, EventParser, type Idl } from "@coral-xyz/anchor"; import { PublicKey } from "@solana/web3.js"; import bs58 from "bs58"; import { subscribe } from "./stream.mts"; const idl = JSON.parse(readFileSync("pump.json", "utf8")) as Idl; const parser = new EventParser(new PublicKey(idl.address), new BorshCoder(idl)); for await (const update of subscribe({ transactions: { pump: { vote: false, failed: false, accountInclude: [idl.address], accountExclude: [], accountRequired: [], }, }, })) { const transaction = update.transaction?.transaction; if (!transaction || transaction.meta?.err) continue; try { let eventIndex = 0; for (const event of parser.parseLogs(transaction.meta?.logMessages ?? [])) { const index = eventIndex++; if (event.name !== "TradeEvent") continue; console.log({ signature: bs58.encode(transaction.signature), slot: update.transaction!.slot, eventIndex: index, side: event.data.is_buy ? "buy" : "sell", mint: event.data.mint.toString(), trader: event.data.user.toString(), tokenAmountRaw: event.data.token_amount.toString(), quoteMint: event.data.quote_mint.toString(), quoteAmountRaw: event.data.quote_amount.toString(), }); } } catch (error) { console.error("Trade event decode failed; check IDL compatibility", error); } } ``` ```bash theme={null} npx tsx pump-trades.mts ``` ## Interpret trade events `EventParser` follows the program invocation stack, so another program’s data logs are not treated as Pump.fun events. Missing or truncated logs can still leave a transaction without a decoded event. Track decode errors and reconcile against transaction history when completeness matters. Keep raw amounts as strings. Apply the decimals of each mint when displaying values. Use signature plus event index for event-level deduplication; one signature can contain several fills. This example observes trades and does not submit swaps. ## Related guides # Yellowstone gRPC for Solana Source: https://docs.solanatracker.io/yellowstone-grpc/index Stream Solana accounts, transactions, slots, blocks, and entry metadata with Yellowstone gRPC. Choose a subscription and connect with an API token. Yellowstone gRPC delivers validator data over a persistent connection. Choose the payload your app needs, then filter on the server before decoding it. ## Choose a stream Balances and account data, filtered by address or program owner. Executed transactions, logs, fees, and token balance metadata. Slot status, block metadata, or selected block contents. Entry hashes and transaction counts for ordering analysis. ## Connect and authenticate Get your token from the [RPC dashboard](https://www.solanatracker.io/account/rpc). Pass it as `x-token` through the client constructor. * **EU:** `https://grpc.solanatracker.io` * **US:** `https://grpc-us.solanatracker.io` Compare both endpoints from the server that will run your consumer. Subscription access and allowances are listed under [pricing and limits](/pricing). ## Choose a commitment `PROCESSED` exposes node-processed updates that may be rolled back. `CONFIRMED` waits for cluster voting; `FINALIZED` waits for finality. Set the level explicitly and keep it consistent with any RPC snapshots you combine with the stream. ## Related guides # Yellowstone gRPC quickstart Source: https://docs.solanatracker.io/yellowstone-grpc/quickstart Connect a TypeScript client to Yellowstone gRPC, authenticate, handle pings, and receive your first Solana block updates. Start with block metadata to verify the connection without downloading full blocks. The helper below is reused by the other Yellowstone guides. ## Install and configure Use Node.js 20 or later. These examples target `@triton-one/yellowstone-grpc` 7.0.1. Keep the `.mts` extension when running them with `tsx`. ```bash theme={null} npm install @triton-one/yellowstone-grpc@7.0.1 bs58 npm install --save-dev typescript tsx @types/node export GRPC_ENDPOINT="https://grpc.solanatracker.io" export GRPC_API_TOKEN="YOUR_API_TOKEN" ``` ## Create the subscription helper Save this as `stream.mts`. It fills in the required request maps, replies to server pings, and closes the stream when the consumer exits. Disconnects are surfaced to the caller. ```typescript stream.mts theme={null} import Yellowstone, { CommitmentLevel, type SubscribeRequest, type SubscribeUpdate, } from "@triton-one/yellowstone-grpc"; const Client = typeof Yellowstone === "function" ? Yellowstone : Yellowstone.default; export function makeRequest( filters: Partial = {}, ): SubscribeRequest { return { accounts: {}, slots: {}, transactions: {}, transactionsStatus: {}, blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [], commitment: CommitmentLevel.CONFIRMED, ...filters, }; } export async function* subscribe( filters: Partial, ): AsyncGenerator { const token = process.env.GRPC_API_TOKEN; if (!token) throw new Error("Set GRPC_API_TOKEN before starting"); const endpoint = process.env.GRPC_ENDPOINT ?? "https://grpc.solanatracker.io"; // This helper exposes disconnects to the caller instead of auto-reconnecting. const client = new Client(endpoint, token, undefined, { enabled: false }); const stream = await client.subscribe(makeRequest(filters)); try { for await (const update of stream) { if (update.ping) { await new Promise((resolve, reject) => { stream.write(makeRequest({ ping: { id: 1 } }), (error?: Error | null) => { if (error) reject(error); else resolve(); }); }); continue; } if (!update.pong) yield update; } } finally { stream.destroy(); } } ``` ## Receive block metadata ```typescript blocks.mts theme={null} import { subscribe } from "./stream.mts"; for await (const update of subscribe({ blocksMeta: { blocks: {} } })) { if (!update.blockMeta) continue; console.log({ slot: update.blockMeta.slot, blockhash: update.blockMeta.blockhash, transactions: update.blockMeta.executedTransactionCount, }); } ``` ```bash theme={null} npx tsx blocks.mts ``` Each row contains a slot, blockhash, and executed transaction count. Stop with Ctrl+C. If nothing arrives, check the token and endpoint in the [authentication guide](/yellowstone-grpc/authentication). ## Read the payload correctly Public keys and signatures arrive as bytes; encode them with base58 for display. The client represents protobuf 64-bit integers as strings. Keep raw balances as strings or `BigInt` until formatting them. ## Related guides # Recent changes Source: https://docs.solanatracker.io/yellowstone-grpc/recent-changes New endpoints, added features, and fixes for Yellowstone gRPC. [View the full changelog](/changelog) No product-specific releases have been posted yet. New entries will appear here when they are added to the changelog. # Stream Solana slots and blocks with gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/slot-block-monitoring Choose slot updates, block metadata, or filtered block payloads with Yellowstone gRPC. Track commitment changes and handle gaps. Use slot updates for progress and status, block metadata for hashes and counts, and full blocks when you need the included transactions or account writes. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Subscribe to slots and metadata ```typescript slots.mts theme={null} import { subscribe } from "./stream.mts"; for await (const update of subscribe({ slots: { slots: { filterByCommitment: true } }, blocksMeta: { blocks: {} }, })) { if (update.slot) { console.log("slot", update.slot.slot, update.slot.parent, update.slot.status); } if (update.blockMeta) { console.log("block", update.blockMeta.slot, update.blockMeta.blockhash, update.blockMeta.executedTransactionCount); } } ``` ```bash theme={null} npx tsx slots.mts ``` `filterByCommitment: true` aligns slot notifications with the request commitment. A slot can have several status updates; keep status as well as slot number when recording transitions. ## Request filtered blocks ```typescript filtered-blocks.mts theme={null} import { subscribe } from "./stream.mts"; const address = process.env.WATCH_ADDRESS; if (!address) throw new Error("Set WATCH_ADDRESS"); for await (const update of subscribe({ blocks: { selected: { accountInclude: [address], includeTransactions: true, includeAccounts: false, includeEntries: false, }, }, })) { if (!update.block) continue; console.log(update.block.slot, update.block.transactions.length); } ``` The three include flags control transactions, accounts, and entries independently. A filtered transaction array can be smaller than the block’s total executed transaction count. ## Handle missing slots Slots are opportunities to produce blocks; some have no block. A gap can also come from a disconnect, filtering, or lag. Compare commitment and RPC block availability before counting a gap as lost data. Measure actual slot intervals instead of assuming a fixed delivery time. ## Related guides # Stream Solana transactions with gRPC Source: https://docs.solanatracker.io/yellowstone-grpc/transaction-monitoring Filter Yellowstone gRPC transactions by account or program, inspect execution metadata, and distinguish failed transactions from successful ones. Filter executed transactions by the accounts they reference. Use the execution metadata for fees, logs, errors, and token balances; decode instructions or events for program-specific trade details. Save the [quickstart helper](/yellowstone-grpc/quickstart) as `stream.mts` in the same directory. These examples use the same environment variables and dependencies. ## Subscribe by program or account ```typescript transactions.mts theme={null} import bs58 from "bs58"; import { subscribe } from "./stream.mts"; const address = process.env.WATCH_ADDRESS; if (!address) throw new Error("Set WATCH_ADDRESS to a program or account"); for await (const update of subscribe({ transactions: { selected: { vote: false, failed: false, accountInclude: [address], accountExclude: [], accountRequired: [], }, }, })) { const transaction = update.transaction?.transaction; if (!transaction) continue; console.log({ signature: bs58.encode(transaction.signature), slot: update.transaction!.slot, feeLamports: transaction.meta?.fee, error: transaction.meta?.err, logs: transaction.meta?.logMessages, }); } ``` ```bash theme={null} export WATCH_ADDRESS="YOUR_PROGRAM_OR_ACCOUNT_ADDRESS" npx tsx transactions.mts ``` ## Combine transaction filters * `accountInclude`: match at least one listed account. * `accountRequired`: require every listed account. * `accountExclude`: reject transactions that reference any listed account. * `vote: false`: exclude validator votes. * `failed: false`: successful executions only. Use `true` for failures, or omit it for both. * `signature`: select one transaction signature. The include, required, and exclude conditions work together. An empty include list does not restrict the set by itself. ## Interpret the result The signature is binary; convert it with base58. The slot is on `update.transaction`, while execution details are on `update.transaction.transaction.meta`. A balance difference can include fees, rent, or several instructions, so it is not automatically a transfer amount. ## Track duplicates and gaps For confirmed or finalized transaction indexing, use the signature as a deduplication key. If you consume processed updates, retain slot/fork context so later confirmation can reconcile provisional results. A reconnect does not by itself recover missed history. ## Related guides