Skip to main content
Raptor is Solana Tracker’s DEX aggregator and swap API. A DEX aggregator checks many decentralized exchanges and finds a route for your swap. The flow is: request a quote, build a swap transaction from that quote, sign it client-side, then submit the signed transaction to Raptor’s sender.
HTTP Base URL: https://raptor-beta.solanatracker.io
WebSocket Base URL: wss://raptor-beta.solanatracker.io
Raptor is currently in public beta.

Supported Routing

Raptor routes across venues and pool types including Raydium, Meteora, Orca Whirlpool, Pump.fun, Pumpswap, MoonIt, Boopfun, FluxBeam, PancakeSwap V3, and more. Use dexes when you want to restrict routing to a subset of supported venues.

1. Get a Quote

Use Get swap quote to fetch the best route. Raptor expects:
  • inputMint
  • outputMint
  • amount in smallest units, which means blockchain integer amounts with no decimals
  • optional slippageBps in basis points, where 50 means 0.5%
  • optional routing controls like dexes, pools, and maxHops
curl "https://raptor-beta.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50"

Restrict Routes

curl "https://raptor-beta.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=dynamic&dexes=raydium,meteora,pumpfun&maxHops=2"

2. Build a Swap Transaction

Use Build swap transaction to create a serialized transaction. Send this request body:
  • userPublicKey
  • quoteResponse from /quote
  • optional transaction tuning like priorityFee, txVersion, computeUnitLimit, tipLamports, and platform fee fields
const quote = await fetch(
  "https://raptor-beta.solanatracker.io/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50"
).then(r => r.json());

const swap = await fetch("https://raptor-beta.solanatracker.io/swap", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userPublicKey: "YOUR_WALLET_ADDRESS",
    wrapUnwrapSol: true,
    txVersion: "v0",
    priorityFee: "medium",
    maxPriorityFee: 1000000,
    quoteResponse: quote
  })
}).then(r => r.json());

console.log(`Swap tx: ${swap.swapTransaction}`);
console.log(`Last valid block height: ${swap.lastValidBlockHeight}`);
console.log(`Priority fee: ${swap.prioritizationFeeLamports}`);

Transaction Controls

FieldPurpose
txVersionlegacy or v0
priorityFeepriority level like medium, high, veryHigh or exact microlamports
maxPriorityFeecap dynamic priority fees
computeUnitPriceMicroLamportsPriority fee: override compute-unit price directly
computeUnitLimitoverride CU limit
tipAccount / tipLamportsadd optional SOL tip
feeAccount / feeBps / feeFromInput / chargeBpsplatform fee controls

Token accounts and SOL wrapping

The /swap response is a ready-to-sign transaction that already includes everything needed for the swap to land on-chain:
  • Associated Token Accounts (ATAs) — Raptor adds createAssociatedTokenAccountIdempotent instructions to setupInstructions for any input, output, or intermediate mint where the user does not already have an ATA. You do not need to pre-create ATAs for the output token; the rent (~0.00203 SOL per account) is paid by userPublicKey. If you build your own transaction from /swap-instructions, keep the setupInstructions and cleanupInstruction arrays — that is where ATA creation and SOL wrap/unwrap live.
  • SOL wrappingwrapUnwrapSol defaults to true. Raptor wraps SOL into wSOL in setupInstructions when SOL is the input, and unwraps any remaining wSOL back to native SOL in cleanupInstruction when SOL is the output. Set wrapUnwrapSol: false only if you are managing a long-lived wSOL account yourself.

3. Quote and Build in One Request

Use Quote and swap in one request if you want a single request instead of separate /quote and /swap calls.
const result = await fetch("https://raptor-beta.solanatracker.io/quote-and-swap", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userPublicKey: "YOUR_WALLET_ADDRESS",
    inputMint: "So11111111111111111111111111111111111111112",
    outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    amount: 100000000,
    slippageBps: "dynamic",
    txVersion: "v0",
    priorityFee: "high",
    maxHops: 2,
    dexes: "raydium,meteora,whirlpool"
  })
}).then(r => r.json());

console.log(result.quote.amountOut);
console.log(result.swapTransaction);

4. Sign Client-Side

Raptor returns swapTransaction as base64. Sign it in the wallet, then send the signed base64 transaction.
import { VersionedTransaction } from "@solana/web3.js";

const txBytes = Uint8Array.from(atob(swap.swapTransaction), c => c.charCodeAt(0));
const tx = VersionedTransaction.deserialize(txBytes);

const signed = await wallet.signTransaction(tx);
const signedBase64 = btoa(String.fromCharCode(...signed.serialize()));

5. Send the Signed Transaction

Send signed transactions with raptor/transactions: POST /send-transaction.
const sendResult = await fetch("https://raptor-beta.solanatracker.io/send-transaction", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ transaction: signedBase64 })
}).then(r => r.json());

console.log(`Signature: ${sendResult.signature}`);
console.log(`Accepted: ${sendResult.success}`);
Raptor sends through Yellowstone Jet TPU and retries in the background until the transaction confirms or expires.

Track Status

const status = await fetch(
  `https://raptor-beta.solanatracker.io/transaction/${sendResult.signature}`
).then(r => r.json());

console.log(`Status: ${status.status}`);
console.log(`Latency: ${status.latency_ms}ms`);
console.log(`Slot: ${status.slot}`);
Valid statuses are pending, confirmed, failed, and expired.

6. Build Instructions Only

Use Build swap instructions when you want instructions without a transaction wrapper.
const instructions = await fetch("https://raptor-beta.solanatracker.io/swap-instructions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userPublicKey: "YOUR_WALLET_ADDRESS",
    quoteResponse: quote,
    txVersion: "v0"
  })
}).then(r => r.json());

console.log(instructions.swapInstruction.programId);
console.log(instructions.addressLookupTableAddresses);

Atomic Buy → Sell in One Transaction (Token Ledger)

When you want to buy a token on one pool and sell it on another in the same transaction — for example, a two-hop arbitrage — you do not know the exact amount the sell leg will receive until the buy leg executes on-chain. The tokenLedgerInstruction returned by /swap-instructions solves this: it records the actual output of the buy leg at runtime, so the sell leg consumes whatever the buy produced. The flow is:
  1. Call /swap-instructions for the buy leg (e.g. SOL → TOKEN on pool 1). Use the returned tokenLedgerInstruction to capture the on-chain output amount.
  2. Call /swap-instructions for the sell leg (e.g. TOKEN → SOL on pool 2). The sell instruction reads its input amount from the token ledger written by the buy leg.
  3. Assemble both calls’ computeBudgetInstructions, setupInstructions, tokenLedgerInstruction, swapInstruction, and cleanupInstruction into a single VersionedTransaction. Deduplicate setup/cleanup instructions and combine the addressLookupTableAddresses from both responses.
  4. Sign once and submit through /send-transaction.
// 1. Buy leg: SOL -> TOKEN on pool 1
const buy = await fetch("https://raptor-beta.solanatracker.io/swap-instructions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userPublicKey: WALLET,
    quoteResponse: buyQuote,     // from /quote restricted to pool 1
    txVersion: "v0"
  })
}).then(r => r.json());

// 2. Sell leg: TOKEN -> SOL on pool 2.
//    amountIn in sellQuote is a placeholder — the ledger overrides it at runtime.
const sell = await fetch("https://raptor-beta.solanatracker.io/swap-instructions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userPublicKey: WALLET,
    quoteResponse: sellQuote,    // from /quote restricted to pool 2
    txVersion: "v0"
  })
}).then(r => r.json());

// 3. Assemble: compute budget + setup + tokenLedger + buy swap + sell swap + cleanup
const instructions = [
  ...buy.computeBudgetInstructions,
  ...dedupe([...buy.setupInstructions, ...sell.setupInstructions]),
  buy.tokenLedgerInstruction,    // present when the sell leg needs it
  buy.swapInstruction,
  sell.swapInstruction,
  sell.cleanupInstruction
].filter(Boolean);

const lookupTables = [
  ...buy.addressLookupTableAddresses,
  ...sell.addressLookupTableAddresses
];
Notes
  • tokenLedgerInstruction is null for ordinary single-swap responses — that is expected. It is populated when the swap is part of a chain where a later instruction needs to read the runtime output of an earlier one.
  • amountOut in a quote is the expected output and cannot be set to auto. The token ledger is the supported way to chain “sell whatever the buy produced” without knowing the amount ahead of time.
  • Keep both legs inside the compute unit budget. You may need to raise computeUnitLimit and computeUnitPriceMicroLamports when combining two swaps.

7. Stream Live Quotes

Use the Raptor WebSocket /stream endpoint for quote updates.
const ws = new WebSocket("wss://raptor-beta.solanatracker.io/stream");

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: "subscribe",
    id: "sol-usdc-quote",
    inputMint: "So11111111111111111111111111111111111111112",
    outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    amount: 100000000,
    slippageBps: "50",
    maxHops: 2,
    dexes: "raydium,meteora,whirlpool"
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === "subscribed") {
    console.log(`Subscribed: ${msg.id}`);
  }

  if (msg.type === "quote") {
    console.log(`Quote update: ${msg.data.amountOut}`);
  }
};

8. Stream Ready-to-Sign Swap Transactions

Use /stream/swap when you want live quote updates plus a fresh prebuilt transaction. This stream requires userPublicKey because Raptor builds the transaction for that wallet.
const ws = new WebSocket("wss://raptor-beta.solanatracker.io/stream/swap");

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: "subscribe",
    id: "sol-usdc-swap",
    inputMint: "So11111111111111111111111111111111111111112",
    outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    amount: 100000000,
    userPublicKey: "YOUR_WALLET_ADDRESS",
    slippageBps: "50",
    txVersion: "v0",
    priorityFee: "medium",
    wrapUnwrapSol: true,
    maxHops: 2
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === "swap") {
    console.log(`Updated quote: ${msg.quote.amountOut}`);
    console.log(`Swap tx: ${msg.swapTransaction}`);
    console.log(`Last valid block height: ${msg.lastValidBlockHeight}`);
  }
};
/stream/swap re-sends the latest transaction after 10 slots without an update to help avoid transaction expiry.

End-to-End Flow

  1. Call /quote with inputMint, outputMint, amount, and optional routing controls.
  2. Pass the returned quoteResponse into /swap with userPublicKey.
  3. Sign the returned swapTransaction in the wallet.
  4. Submit the signed base64 transaction to /send-transaction.
  5. Poll /transaction/{signature} for status.
If you want fewer round-trips, use /quote-and-swap instead of separate /quote and /swap calls.

Raptor Overview

Full endpoint reference, supported DEXs, routing controls, and WebSocket details.

Raptor Transactions

Send signed transactions and track confirmation status through Raptor.