Comprehensive guidance for integrating Jupiter APIs (Ultra Swap, Lend, Perps, Trigger, Recurring, Tokens, Price, Portfolio, Prediction Markets, Send, Studio, Lock, Routing).
86
Quality
84%
Does it follow best practices?
Impact
91%
1.85xAverage score across 5 eval scenarios
Single skill for all Jupiter APIs, optimized for fast routing and deterministic execution.
Base URL: https://api.jup.ag
Auth: x-api-key from portal.jup.ag (required for Jupiter REST endpoints)
Use when:
Do not use when:
Triggers: swap, quote, gasless, best route, lend, borrow, earn, liquidation, perps, leverage, long, short, position, limit order, trigger, price condition, dca, recurring, scheduled swaps, token metadata, token search, verification, shield, price, valuation, price feed, portfolio, positions, holdings, prediction markets, market odds, event market, invite transfer, send, clawback, create token, studio, claim fee, vesting, distribution lock, unlock schedule, dex integration, rfq integration, routing engine
import { Connection, Keypair, VersionedTransaction } from '@solana/web3.js';
const API_KEY = process.env.JUPITER_API_KEY!; // from portal.jup.ag
if (!API_KEY) throw new Error('Missing JUPITER_API_KEY');
const BASE = 'https://api.jup.ag';
const headers = { 'x-api-key': API_KEY };
async function jupiterFetch<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
...init,
headers: { ...headers, ...init?.headers },
});
if (res.status === 429) throw { code: 'RATE_LIMITED', retryAfter: 10 };
if (!res.ok) {
const raw = await res.text();
let body: any = { message: raw || `HTTP_${res.status}` };
try {
body = raw ? JSON.parse(raw) : body;
} catch {
// keep text fallback body
}
throw { status: res.status, ...body };
}
return res.json();
}
// Sign and send any Jupiter transaction
async function signAndSend(
txBase64: string,
wallet: Keypair,
connection: Connection,
additionalSigners: Keypair[] = []
): Promise<string> {
const tx = VersionedTransaction.deserialize(Buffer.from(txBase64, 'base64'));
tx.sign([wallet, ...additionalSigners]);
const sig = await connection.sendRawTransaction(tx.serialize(), {
maxRetries: 0,
skipPreflight: true,
});
return sig;
}| User intent | API family | First action |
|---|---|---|
| Swap/quote | Ultra Swap | GET /ultra/v1/order -> sign -> POST /ultra/v1/execute |
| Lend/borrow/yield | Lend | POST /lend/v1/earn/deposit or /withdraw |
| Leverage/perps | Perps | On-chain via Anchor IDL (no REST API yet) |
| Limit orders | Trigger | POST /trigger/v1/createOrder -> sign -> POST /trigger/v1/execute |
| DCA/recurring buys | Recurring | POST /recurring/v1/createOrder -> sign -> POST /recurring/v1/execute |
| Token search/verification | Tokens | GET /tokens/v2/search?query={mint} |
| Price lookup | Price | GET /price/v3?ids={mints} |
| Portfolio/positions | Portfolio | GET /portfolio/v1/positions/{address} |
| Prediction market integration | Prediction Markets | GET /prediction/v1/events -> POST /prediction/v1/orders |
| Invite send/clawback | Send | POST /send/v1/craft-send -> sign -> send to RPC |
| Token creation/fees | Studio | POST /studio/v1/dbc-pool/create-tx -> upload -> submit |
| Vesting/distribution | Lock | On-chain program LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn |
| DEX/RFQ integration | Routing | Choose DEX (AMM trait) vs RFQ (webhook) path |
Use each block as a minimal execution contract. Fetch the linked refs for full request/response shapes, TypeScript interfaces, and parameter details.
https://api.jup.ag/ultra/v1swap, quote, gasless, best route/order (GET), /execute (POST), /holdings/{account} (GET), /shield (GET), /search (GET), /routers (GET)https://api.jup.ag/lend/v1lend, borrow, earn, liquidationjup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9, Borrow jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi@jup-ag/lend (TypeScript)/earn/deposit (POST), /earn/withdraw (POST), /earn/mint (POST), /earn/redeem (POST), /earn/deposit-instructions (POST), /earn/withdraw-instructions (POST), /earn/tokens (GET), /earn/positions (GET), /earn/earnings (GET)VersionedTransaction.perps, leverage, long, short, positionhttps://api.jup.ag/trigger/v1limit order, trigger, price condition/createOrder (POST), /cancelOrder (POST), /cancelOrders (POST, max 5 per tx), /execute (POST), /getTriggerOrders (GET)slippageBps for "Ultra" mode with higher fill rate.https://api.jup.ag/recurring/v1dca, recurring, scheduled swaps/createOrder (POST), /cancelOrder (POST), /execute (POST), /getRecurringOrders (GET)params.time only.https://api.jup.ag/tokens/v2token metadata, token search, verification, shield/search?query={q} (GET, comma-separate mints, max 100), /tag?query={tag} (GET, verified or lst), /{category}/{interval} (GET, categories: toporganicscore, toptraded, toptrending; intervals: 5m, 1h, 6h, 24h), /recent (GET)audit.isSus and organicScore in UX.https://api.jup.ag/price/v3price, valuation, price feed/price/v3?ids={mints} (GET, comma-separated)null or are omitted (not an error). Fail closed on missing/low-confidence data for safety-sensitive actions. Use confidenceLevel field.https://api.jup.ag/portfolio/v1portfolio, positions, holdings/positions/{address} (GET), /positions/{address}?platforms={ids} (GET), /platforms (GET), /staked-jup/{address} (GET)multiple, liquidity, trade, leverage, borrowlend.https://api.jup.ag/prediction/v1prediction markets, market odds, event marketJuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD), USDC/events (GET), /events/search (GET), /markets/{marketId} (GET), /orderbook/{marketId} (GET), /orders (POST), /orders/status/{pubkey} (GET), /positions (GET), /positions/{pubkey} (DELETE), /positions/{pubkey}/claim (POST), /history (GET), /leaderboards (GET)position.claimable before claiming. Winners get $1/contract.https://api.jup.ag/send/v1invite transfer, send, clawback/craft-send (POST), /craft-clawback (POST), /pending-invites (GET), /invite-history (GET)https://api.jup.ag/studio/v1create token, studio, claim fee/dbc-pool/create-tx (POST), /dbc-pool/submit (POST, multipart/form-data), /dbc-pool/addresses/{mint} (GET), /dbc/fee (POST), /dbc/fee/create-tx (POST)/dbc-pool/submit/dbc-pool/submit (not externally) for token to get a Studio page on jup.ag. Error codes: 403 = not authorized for pool, 404 = proxy account not found.LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjnvesting, distribution lock, unlock schedulecli/src/bin/instructions directory.dex integration, rfq integration, routing enginejupiter-amm-interface crate. Critical: No network calls in implementation (accounts are pre-batched and cached). Ref impl: github.com/jup-ag/rust-amm-implementation/jupiter/rfq/quote (POST, 250ms), /jupiter/rfq/swap (POST), /jupiter/rfq/tokens (GET). Reqs: 95% fill rate, 250ms response, 55s expiry. SDK: github.com/jup-ag/rfq-webhook-toolkitUltra Swap (dynamic, volume-based):
| 24h Execute Volume | Requests per 10s window |
|---|---|
| $0 | 50 |
| $10,000 | 51 |
| $100,000 | 61 |
| $1,000,000 | 165 |
Quotas recalculate every 10 minutes. Pro plan does NOT increase Ultra limits.
Other APIs: Managed at portal level. Check portal rate limits.
On HTTP 429: Exponential backoff with jitter: delay = min(baseDelay * 2^attempt + random(0, jitter), maxDelay). Wait for 10s sliding window refresh. Do NOT burst aggressively.
x-api-key is missing or invalid./execute accepts same signedTransaction + requestId for up to 2 min without duplicate execution.requestId, API family, endpoint, latency, status, and error code.retry, adjust params, insufficient balance, rate limited).interface JupiterResult<T> {
ok: boolean;
result?: T;
error?: { code: string | number; message: string; retryable: boolean };
}
async function jupiterAction<T>(action: () => Promise<T>): Promise<JupiterResult<T>> {
try {
const result = await action();
return { ok: true, result };
} catch (error: any) {
const code = error?.code ?? error?.status ?? 'UNKNOWN';
// Rate limit — retry with backoff
if (code === 429 || code === 'RATE_LIMITED') {
return { ok: false, error: { code: 'RATE_LIMITED', message: 'Rate limited', retryable: true } };
}
// Ultra execute errors (negative codes)
if (typeof code === 'number' && code < 0) {
const retryable = [-1, -1000, -1001, -1005, -1006, -2000, -2003, -2005].includes(code);
return { ok: false, error: { code, message: error?.error ?? 'Execute failed', retryable } };
}
// Program errors (positive codes like 6001 = slippage)
if (typeof code === 'number' && code > 0) {
return { ok: false, error: { code, message: error?.error ?? 'Program error', retryable: false } };
}
return { ok: false, error: { code, message: error?.message ?? 'UNKNOWN_ERROR', retryable: false } };
}
}Always fetch the freshest context from referenced docs/specs before executing a playbook.
Intent Router.x-api-key is required for Jupiter REST endpoints (not on-chain-only flows like Perps/Lock).Install with Tessl CLI
npx tessl i tessl-skill-index-evals/jup-ag__agent-skills__integrating-jupiter