Jupiter V6 API Documentation: Complete Guide for Traders
Master Jupiter V6 API to build Solana DEX aggregator tools, execute swaps programmatically, and integrate real-time liquidity routing into your trading bots.
Master Jupiter V6 API to build Solana DEX aggregator tools, execute swaps programmatically, and integrate real-time liquidity routing into your trading bots.
Jupiter is Solana's dominant DEX aggregator, routing trades through dozens of liquidity sources to give you the best execution price. Version 6 of their API is a significant upgrade — cleaner endpoints, better error handling, and a new Priority Fee system that matters a lot when the network is congested. If you're running a trading bot or building anything that touches Solana DeFi, Jupiter V6 is where you start. Traders on centralized venues like Binance or Bybit are used to well-documented REST APIs with predictable behavior. Jupiter V6 brings that same level of polish to on-chain Solana execution.
Jupiter V6 replaced the previous Quote API v4/v5 with a unified, more stable interface. The key changes that affect anyone building on it: the base URL shifted to quote-api.jup.ag/v6, the swap instruction endpoint now returns a versioned transaction by default, and slippage control was refined with a new dynamic slippage mode. Dynamic slippage automatically adjusts tolerance based on route complexity — a massive upgrade for bots that were getting wrecked by manual slippage misconfiguration during volatile markets.
Jupiter's public API is free with no API key required for standard use. For high-volume production bots hitting rate limits, Jupiter offers a paid tier through their partnership program. Always check the current rate limit headers in responses (x-ratelimit-remaining) before scaling.
The /quote endpoint is where everything starts. You pass in the input token mint, output token mint, the amount in the input token's smallest denomination (lamports for SOL, or the token's decimal-adjusted unit), and your slippage tolerance. The response gives you the best route across all liquidity sources Jupiter aggregates — Orca, Raydium, Meteora, and more. Compare this to how Binance's order book works: instead of matching against a single venue's liquidity, Jupiter is simultaneously checking every major Solana DEX.
import requests
# Token mints
SOL_MINT = "So11111111111111111111111111111111111111112"
USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
# Amount: 0.1 SOL = 100_000_000 lamports
amount = 100_000_000
slippage_bps = 50 # 0.5%
params = {
"inputMint": SOL_MINT,
"outputMint": USDC_MINT,
"amount": amount,
"slippageBps": slippage_bps,
"dynamicSlippage": "true", # Let Jupiter auto-adjust if needed
}
response = requests.get("https://quote-api.jup.ag/v6/quote", params=params)
if response.status_code != 200:
print(f"Error: {response.status_code} - {response.text}")
else:
quote = response.json()
print(f"Input: {quote['inAmount']} lamports")
print(f"Output: {quote['outAmount']} USDC units")
print(f"Price Impact: {quote['priceImpactPct']}%")
print(f"Route: {[r['swapInfo']['label'] for r in quote['routePlan']]}")
The priceImpactPct field is critical. A price impact above 1% on a SOL/USDC swap is a red flag — you're likely trading a thin liquidity route. For smaller cap tokens, 2-5% is common and sometimes acceptable, but you need to be tracking this number in your bot logic. Many traders using platforms like OKX or Coinbase for spot trading underestimate how different on-chain liquidity dynamics are from centralized order books.
Once you have a quote, the /swap endpoint takes that quote response plus your wallet's public key and returns a base64-encoded versioned transaction ready to sign and broadcast. Jupiter handles all the complexity of routing through multiple DEX pools, wrapping/unwrapping SOL, and computing ATAs (associated token accounts). Your job is just to sign and send.
import requests
import base64
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
from solana.rpc.api import Client
from solana.rpc.types import TxOpts
# Setup
rpc_client = Client("https://api.mainnet-beta.solana.com")
wallet = Keypair.from_base58_string("YOUR_PRIVATE_KEY_HERE") # Never hardcode in prod
# Step 1: Get quote (from previous example)
quote = requests.get(
"https://quote-api.jup.ag/v6/quote",
params={
"inputMint": "So11111111111111111111111111111111111111112",
"outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount": 100_000_000,
"slippageBps": 50,
}
).json()
# Step 2: Build the swap transaction
swap_payload = {
"quoteResponse": quote,
"userPublicKey": str(wallet.pubkey()),
"wrapAndUnwrapSol": True, # Auto-handle wSOL
"prioritizationFeeLamports": 10000, # Priority fee for faster inclusion
"dynamicComputeUnitLimit": True, # Optimize compute units automatically
}
swap_response = requests.post(
"https://quote-api.jup.ag/v6/swap",
json=swap_payload
)
if swap_response.status_code != 200:
raise Exception(f"Swap build failed: {swap_response.text}")
swap_data = swap_response.json()
tx_bytes = base64.b64decode(swap_data["swapTransaction"])
# Step 3: Deserialize, sign, and send
tx = VersionedTransaction.from_bytes(tx_bytes)
signed_tx = wallet.sign_message(bytes(tx.message))
# For production, use proper versioned transaction signing
print(f"Transaction ready. Last valid block: {swap_data['lastValidBlockHeight']}")
Always use the lastValidBlockHeight from the swap response. Solana transactions expire after a block window (~90 seconds). If your bot retries a failed transaction after this window, the tx will be rejected regardless. Fetch a fresh quote and rebuild the transaction instead of resubmitting the old one.
Jupiter V6 returns structured error objects, but the edge cases that catch developers off guard are usually at the RPC layer, not the Jupiter API layer. Network congestion on Solana can cause transactions to drop even when Jupiter built them correctly. Here's a production-grade pattern for handling the most common failure modes, adapted from patterns used by active Solana trading bots.
import requests
import time
from typing import Optional
JUPITER_BASE = "https://quote-api.jup.ag/v6"
def get_quote_with_retry(
input_mint: str,
output_mint: str,
amount: int,
slippage_bps: int = 50,
max_retries: int = 3
) -> Optional[dict]:
"""
Fetch a Jupiter quote with exponential backoff on failure.
Returns None if all retries exhausted.
"""
for attempt in range(max_retries):
try:
resp = requests.get(
f"{JUPITER_BASE}/quote",
params={
"inputMint": input_mint,
"outputMint": output_mint,
"amount": amount,
"slippageBps": slippage_bps,
"dynamicSlippage": "true",
},
timeout=10 # Always set a timeout
)
if resp.status_code == 429:
# Rate limited — back off
wait = 2 ** attempt
print(f"Rate limited. Waiting {wait}s before retry {attempt + 1}")
time.sleep(wait)
continue
if resp.status_code == 400:
error = resp.json()
# Common: TOKEN_NOT_TRADABLE, COULD_NOT_FIND_ANY_ROUTE
if error.get("error") == "COULD_NOT_FIND_ANY_ROUTE":
print("No route found — pair may have no liquidity")
return None
raise ValueError(f"Bad request: {error}")
resp.raise_for_status()
quote = resp.json()
# Sanity check price impact before returning
if float(quote.get("priceImpactPct", 0)) > 5.0:
print(f"WARNING: High price impact {quote['priceImpactPct']}% — skipping")
return None
return quote
except requests.exceptions.Timeout:
print(f"Timeout on attempt {attempt + 1}/{max_retries}")
time.sleep(1)
return None
# Usage
quote = get_quote_with_retry(
input_mint="So11111111111111111111111111111111111111112",
output_mint="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amount=500_000_000, # 0.5 SOL
slippage_bps=30
)
if quote:
print(f"Got quote: {quote['outAmount']} output units")
else:
print("Could not get a safe quote — skipping this trade")
The price impact guard in the example above is not optional for production bots. During volatile market moves — the kind that VoiceOfChain's signal alerts flag in real time — liquidity on DEX pools drains fast. A bot without impact protection can execute a 10%+ slippage trade on a token that spiked on a signal and watch the position immediately go underwater. Pair VoiceOfChain signal data with this kind of pre-flight check to avoid chasing moves into thin liquidity.
On Solana, unlike fee markets on Ethereum where Bybit's on-chain bridge transactions compete with ERC-20 transfers via gas price, compute units and priority fees work differently. Jupiter V6 exposes two mechanisms: prioritizationFeeLamports (a flat tip to validators) and dynamicComputeUnitLimit (auto-sizing compute based on the actual route complexity). Both matter for getting swaps included during high-traffic periods.
| Scenario | Recommended Priority Fee | Notes |
|---|---|---|
| Low traffic, simple route | 1,000–5,000 lamports | Fine for non-urgent swaps |
| Normal conditions, 2-hop route | 10,000–50,000 lamports | Most common production setting |
| High congestion or time-sensitive | 100,000–500,000 lamports | Signal-driven trades during pumps |
| Extreme congestion (network events) | 1,000,000+ lamports | Rare; verify before deploying |
Jupiter also offers a priority fee estimation endpoint. Before hardcoding a fee tier, you can fetch current network conditions and set fees dynamically. This is especially important if you're building a bot that reacts to VoiceOfChain signals — those alerts often fire during high-activity windows where the network is already busy, and a too-low priority fee means your trade lands after the move has already played out.
Jupiter V6 API documentation is genuinely one of the more developer-friendly interfaces in crypto, but the gap between a working prototype and a production-ready trading bot is where most builders stall. The three things that separate bots that survive in the wild from the ones that bleed out: proper error handling with retries, dynamic priority fee management, and pre-flight price impact validation. Traders who come from centralized venues like Binance, Gate.io, or KuCoin are used to APIs that abstract away infrastructure concerns — on Solana, those concerns are your problem, and Jupiter V6 gives you the tools to handle them properly. Combine that with a real-time signal layer like VoiceOfChain and you have the foundation for a serious on-chain trading operation.