Jupiter V6 Swap API Guide

·

The Jupiter V6 Swap API is one of the most powerful and developer-friendly tools for accessing decentralized liquidity on Solana. Whether you're building a DeFi application, integrating cross-chain swaps, or enabling automated trading strategies, this guide walks you through everything you need to know about leveraging the Jupiter V6 Swap API effectively.

With support for versioned transactions, address lookup tables, and flexible routing options, the API streamlines token swaps while offering advanced customization for experienced developers. Let’s dive into how you can integrate it seamlessly into your project.


Getting Started with the Jupiter V6 Swap API

To begin using the Jupiter V6 Swap API, ensure your development environment supports Node.js 16 or higher. You’ll also need to install a few essential libraries:

npm install @solana/web3.js cross-fetch @project-serum/anchor bs58

These packages provide core functionality for interacting with the Solana blockchain, handling HTTP requests, managing wallets, and decoding base58-encoded keys.

👉 Discover how to integrate high-performance swap functionality into your dApp today.


Setting Up Connection and Wallet

Start by importing required modules and establishing a connection to the Solana network:

import { Connection, Keypair, VersionedTransaction } from '@solana/web3.js';
import fetch from 'cross-fetch';
import { Wallet } from '@project-serum/anchor';
import bs58 from 'bs58';

// Replace with your own RPC endpoint for production use
const connection = new Connection('https://neat-hidden-sanctuary.solana-mainnet.discover.quiknode.pro/2af5315d336f9ae920028bbb90a73b724dc1bbed/');
Best Practice: Always use a private RPC provider in production to ensure reliability and avoid rate-limiting issues.

Next, configure your wallet. For testing purposes, you can load a keypair from an environment variable:

const wallet = new Wallet(Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')));

Never hardcode private keys in production applications—use secure key management systems instead.


Fetching a Swap Quote

To get a quote for swapping tokens, call the /quote endpoint. For example, to swap 0.1 SOL to USDC with 0.5% slippage:

const quoteResponse = await (
  await fetch(
    'https://quote-api.jup.ag/v6/quote?' +
    'inputMint=So11111111111111111111111111111111111111112&' +
    'outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&' +
    'amount=100000000&' +
    'slippageBps=50'
  )
).json();
Note: Amounts are passed as integers. For tokens with 6 decimals like USDC, multiply by 1,000,000 (e.g., 1 USDC = 1,000,000).

This returns optimal routing data including estimated output amount, route plan, and slippage protection settings.


Generating the Swap Transaction

Once you have a quote, generate the serialized transaction:

const { swapTransaction } = await (
  await fetch('https://quote-api.jup.ag/v6/swap', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      quoteResponse,
      userPublicKey: wallet.publicKey.toString(),
      wrapAndUnwrapSol: true,
    }),
  })
).json();

This returns a base64-encoded versioned transaction ready for signing.


Signing and Sending the Transaction

Deserialize and sign the transaction using your wallet:

const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
transaction.sign([wallet.payer]);

const rawTransaction = transaction.serialize();
const txid = await connection.sendRawTransaction(rawTransaction, {
  skipPreflight: true,
  maxRetries: 2,
});

await connection.confirmTransaction(txid);
console.log(`View transaction: https://solscan.io/tx/${txid}`);

Advanced Error Handling and AMM Exclusion

Some Automated Market Makers (AMMs) may fail during execution due to volatility or liquidity constraints. To prevent repeated failures, extract failing program IDs from failed transactions and exclude them in future quotes.

Using the @mercurial-finance/optimist package:

import { parseErrorForTransaction } from '@mercurial-finance/optimist';

const transaction = await connection.getTransaction(txid, {
  maxSupportedTransactionVersion: 0,
  commitment: 'confirmed',
});

const programIdToLabelHash = await (await fetch('https://quote-api.jup.ag/v6/program-id-to-label')).json();
const { programIds } = parseErrorForTransaction(transaction);

const excludeDexes = new Set();
if (programIds) {
  for (const programId of programIds) {
    const label = programIdToLabelHash[programId];
    if (label) excludeDexes.add(label);
  }
}

// Request new quote excluding problematic AMMs
const response = await (
  await fetch(
    `https://quote-api.jup.ag/v6/quote?inputMint=So1111...&outputMint=EPjF...&amount=100000000&excludeDexes=${Array.from(excludeDexes).join(',')}&slippageBps=50`
  )
).json();

This improves success rates by avoiding known problematic pools.


Using Instructions Instead of Full Transactions

For greater control, use /swap-instructions to receive raw instructions rather than a complete transaction:

const instructions = await (
  await fetch('https://quote-api.jup.ag/v6/swap-instructions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      quoteResponse,
      userPublicKey: wallet.publicKey.toBase58(),
    }),
  })
).json();

You can then compose these with other instructions in a custom transaction.


Managing Account Limits with maxAccounts

Solana transactions support up to 64 accounts. If your dApp uses additional programs, limit Jupiter's account usage:

const { data } = await (
  await fetch(
    'https://quote-api.jup.ag/v6/quote?inputMint=So11...&outputMint=EPjF...&amount=100000000&slippageBps=50&maxAccounts=54'
  )
).json();

This reserves space for your own program accounts.


Leveraging Token Ledger for Dynamic Inputs

When input amounts aren't known until runtime (e.g., after a withdrawal), use useTokenLedger: true:

body: JSON.stringify({
  quoteResponse,
  useTokenLedger: true,
})

This allows subsequent instructions (like withdrawals) to affect the swap input dynamically.

👉 Learn how real-time liquidity aggregation boosts trade efficiency in DeFi.


Setting Priority Fees for Faster Execution

During congestion, transactions may fail due to low fees. Use prioritizationFeeLamports to boost priority:

body: JSON.stringify({
  quoteResponse,
  userPublicKey: wallet.publicKey.toString(),
  prioritizationFeeLamports: 'auto', // or set custom value like 1000
})

Setting 'auto' lets Jupiter optimize fees dynamically (capped at ~0.005 SOL).


Frequently Asked Questions (FAQ)

Q: What is the difference between /swap and /swap-instructions?
A: /swap returns a fully serialized transaction ready to sign and send. /swap-instructions gives raw instructions so you can embed them in larger, custom transactions.

Q: Why am I getting versioned transaction errors?
A: Some wallets don’t support versioned transactions. Use asLegacyTransaction parameter where supported to generate legacy format transactions.

Q: How do I handle slippage properly?
A: Slippage is set via slippageBps (basis points). For 0.5%, use 50. Always validate output amounts before signing.

Q: Can I use this API for cross-chain swaps?
A: No—Jupiter operates only on Solana. For cross-chain functionality, consider integrating a bridge protocol separately.

Q: Is there a rate limit on the Jupiter API?
A: Public endpoints have soft rate limits. For high-frequency usage, consider running a dedicated instance or using enterprise access.

Q: How do I debug failed swaps?
A: Check the transaction on Solscan, inspect logs for program errors, and use excludeDexes to avoid faulty AMMs in retries.


Final Thoughts

The Jupiter V6 Swap API empowers developers with robust, efficient access to Solana’s deepest liquidity pools. From simple swaps to complex composability patterns involving token ledgers and dynamic routing, its flexibility makes it ideal for modern DeFi integrations.

👉 Start building smarter DeFi tools with powerful swap infrastructure now.