◈   ⌘ api · Intermediate

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.

Uncle Solieditor · voc · 06.05.2026 ·views 108
◈   Contents
  1. → What Changed in Jupiter V6 and Why It Matters
  2. → Getting a Quote: Your First API Call
  3. → Building and Sending the Swap Transaction
  4. → Error Handling and Edge Cases That Will Break Your Bot
  5. → Priority Fees and Compute Units: Getting Your Transactions Included
  6. → Frequently Asked Questions
  7. → Putting It All Together

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.

What Changed in Jupiter V6 and Why It Matters

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.

Getting a Quote: Your First API Call

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.

Building and Sending the Swap Transaction

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.

Error Handling and Edge Cases That Will Break Your Bot

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.

Priority Fees and Compute Units: Getting Your Transactions Included

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.

Priority Fee Tiers for Jupiter Swaps
ScenarioRecommended Priority FeeNotes
Low traffic, simple route1,000–5,000 lamportsFine for non-urgent swaps
Normal conditions, 2-hop route10,000–50,000 lamportsMost common production setting
High congestion or time-sensitive100,000–500,000 lamportsSignal-driven trades during pumps
Extreme congestion (network events)1,000,000+ lamportsRare; 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.

Frequently Asked Questions

Do I need an API key to use Jupiter V6 API?
No, the public Jupiter V6 API at quote-api.jup.ag/v6 is free and requires no authentication. Rate limits apply — typically around 600 requests per minute for quotes. For higher throughput, Jupiter has a partnership program for production-scale projects.
Why does my Jupiter swap transaction keep expiring before it lands?
Solana transactions expire after their lastValidBlockHeight passes, which is roughly 90 seconds from when Jupiter built the transaction. If you're seeing expiry failures, fetch a fresh quote and rebuild the swap transaction rather than rebroadcasting the old one. Also increase your priority fee — low fees cause transactions to sit in the queue and miss their validity window.
What is the difference between /swap and /swap-instructions in Jupiter V6?
The /swap endpoint returns a fully built, serialized versioned transaction ready to sign. The /swap-instructions endpoint returns the raw Solana instructions so you can compose them into a custom transaction — useful if you need to add other instructions like memo logs or custom program calls alongside the swap.
How does Jupiter V6 compare to trading directly on Raydium or Orca?
Jupiter routes through Raydium, Orca, Meteora, and many other pools simultaneously, splitting orders across venues if it improves your execution price. Trading directly on a single DEX means you only access that venue's liquidity. For most token pairs, Jupiter will get you a better price, sometimes meaningfully so on less liquid pairs.
Can I use Jupiter V6 API to build a trading bot that reacts to signals?
Yes, and it's one of the most common use cases. The pattern is: receive a signal (for example from VoiceOfChain), call /quote to check if the route is viable and the price impact is acceptable, then call /swap to build and execute the transaction. The key is pre-flight checking price impact and using appropriate priority fees so your bot lands the trade before others react to the same signal.
What tokens are supported by Jupiter V6 API?
Jupiter supports thousands of Solana SPL tokens. You can fetch the full list via GET /tokens. Not every token will have a viable route — very new or very illiquid tokens may return COULD_NOT_FIND_ANY_ROUTE from the quote endpoint. Always handle this case gracefully in your bot rather than treating a missing route as a crash condition.

Putting It All Together

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.

◈   more on this topic
◉ basics Mastering the ccxt library documentation for crypto traders ⌂ exchanges Mastering the Binance CCXT Library for Crypto Traders ⌬ bots Best Crypto Trading Bots 2025: Profitable AI-Powered Strategies