Jupiter API Guide: Free Solana Price Data for Your Apps
What You’ll Need
- n8n Cloud or self-hosted n8n
- Hetzner VPS or Contabo VPS for self-hosting
- DigitalOcean as an alternative hosting option
- A Jupiter API key (free tier available)
- Node.js 16+ or Python 3.8+ for local testing
- Basic understanding of REST APIs and webhooks
Table of Contents
- Understanding Jupiter API and Why It Matters
- Getting Your Free Jupiter API Key
- Building Your First Price Data Query
- Real-Time Solana Price Monitoring with n8n
- Storing Price Data in Google Sheets
- Advanced: Historical Data Analysis
- Getting Started
Understanding Jupiter API and Why It Matters
I’ve been working with Solana ecosystem APIs for about three years now, and I can tell you that Jupiter API is one of the best-kept secrets for developers who need reliable, free Solana price data. Jupiter is the largest DEX aggregator on Solana, and their API exposes real-time pricing information that powers some of the most sophisticated trading bots and analytics platforms in the space.
What makes Jupiter different from other price APIs? Speed, accuracy, and zero rate limits for reasonable usage. You’re not dealing with a centralized price feed—you’re tapping directly into on-chain liquidity data from Solana’s most liquid markets. This means you get true price discovery rather than some aggregated guess.
The use cases are endless: build portfolio dashboards, create alert systems when tokens hit certain prices, automate trading decisions, or feed price data into machine learning models. I’ve personally used Jupiter API to power everything from Discord bots that alert traders to automated portfolio rebalancers.
Getting Your Free Jupiter API Key
First, head to the Jupiter API documentation. They don’t require traditional API keys—the API is public and free to use. This is one of the beauties of the Solana ecosystem. However, you’ll want to understand rate limiting and best practices.
Here’s the base endpoint you’ll be working with:
https://price.jup.ag/v4/price
No authentication needed. Let me show you the anatomy of a real request:
curl -X GET "https://price.jup.ag/v4/price?ids=So11111111111111111111111111111111111111112&vsToken=EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md"
Breaking this down:
ids= the token mint address you want price data for (SOL in this case)vsToken= what you’re pricing against (USDC in this example)
The response looks like this:
{
"data": {
"So11111111111111111111111111111111111111112": {
"id": "So11111111111111111111111111111111111111112",
"type": "derivedPrice",
"price": "175.50",
"decimals": 2,
"time": 1704067200000
}
},
"timeTaken": 0.0001
}
Clean, fast, and immediately actionable. You get the price, decimal precision, and timestamp.
Building Your First Price Data Query
Let me walk you through a practical example. I’m going to show you how to query multiple tokens at once and parse the response in Node.js:
const https = require('https');
const tokenMints = {
SOL: 'So11111111111111111111111111111111111111112',
USDC: 'EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md',
USDT: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenYes',
RAY: '4k3Dyjzvzp8eMZWUXbBCjEvwSvsrH3xn5ZH3KD2Zcco',
JUP: 'JUPyiwrYJFskUPiHa7hkeR8NqtwybKHLo3xKc4CMycJ'
};
const vsToken = 'EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md';
async function getPrices() {
const mintIds = Object.values(tokenMints).join(',');
const url = `https://price.jup.ag/v4/price?ids=${mintIds}&vsToken=${vsToken}`;
return new Promise((resolve, reject) => {
https.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const parsed = JSON.parse(data);
resolve(parsed);
} catch (e) {
reject(e);
}
});
}).on('error', (e) => {
reject(e);
});
});
}
async function displayPrices() {
try {
const prices = await getPrices();
const tokenNames = Object.keys(tokenMints);
tokenNames.forEach((name, index) => {
const mint = Object.values(tokenMints)[index];
const priceData = prices.data[mint];
if (priceData) {
console.log(`${name}: $${priceData.price}`);
}
});
} catch (error) {
console.error('Error fetching prices:', error);
}
}
displayPrices();
Save this as get-prices.js and run it:
node get-prices.js
You’ll get output like:
SOL: $175.50
USDC: $1.00
USDT: $0.99
RAY: $1.25
JUP: $0.45
The beauty here is that you’re making one request to get multiple token prices. This is efficient and respects Jupiter’s infrastructure.
Real-Time Solana Price Monitoring with n8n
Now let’s automate this. I’m going to show you how to build a workflow in n8n Cloud that queries Jupiter API every minute and stores results.
💡 Fast-Track Your Project: Don’t want to configure this yourself? I build custom n8n pipelines and bots. Message me with code SYS3-HUGO.
Here’s your n8n workflow configuration (exportable JSON):
{
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"intervalValue": 1,
"intervalUnit": "minutes"
}
]
}
},
"id": "fd5a4d6c-8c2e-4bbb-9f3e-2a1b3c4d5e6f",
"name": "Trigger",
"type": "n8n-nodes-base.cron",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"url": "https://price.jup.ag/v4/price",
"options": {},
"specialParameters": {
"queryParameters": {
"ids": "So11111111111111111111111111111111111111112,EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md,Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenYes",
"vsToken": "EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md"
}
}
},
"id": "a1b2c3d4-e5f6-4g7h-8i9j-0k1l2m3n4o5p",
"name": "Fetch Jupiter Prices",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
500,
300
]
},
{
"parameters": {
"functionCode": "const data = $input.first().json.data;\nconst prices = {};\n\nconst tokenMap = {\n 'So11111111111111111111111111111111111111112': 'SOL',\n 'EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md': 'USDC',\n 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenYes': 'USDT'\n};\n\nObject.keys(data).forEach(mint => {\n const tokenName = tokenMap[mint];\n if (tokenName) {\n prices[tokenName] = {\n price: data[mint].price,\n timestamp: new Date(data[mint].time).toISOString()\n };\n }\n});\n\nreturn { prices, timestamp: new Date().toISOString() };"
},
"id": "b2c3d4e5-f6g7-4h8i-9j0k-1l2m3n4o5p6q",
"name": "Transform Prices",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
750,
300
]
}
],
"connections": {
"Trigger": {
"main": [
[
{
"node": "Fetch Jupiter Prices",
"type": "main",
"index": 0
}
]
]
},
"Fetch Jupiter Prices": {
"main": [
[
{
"node": "Transform Prices",
"type": "main",
"index": 0
}
]
]
}
}
}
After you create this workflow in n8n, you can extend it by adding a webhook that triggers alerts when prices move by more than 5%. Here’s the alert logic you’d add to the Transform Prices function:
const data = $input.first().json.data;
const prices = {};
const tokenMap = {
'So11111111111111111111111111111111111111112': 'SOL',
'EPjFWaJgt46ggsuKpQSetg69YXiGBkSstw2HYPi81md': 'USDC',
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenYes': 'USDT'
};
const previousPrices = {
SOL: 175.00,
USDC: 1.00,
USDT: 0.99
};
Object.keys(data).forEach(mint => {
const tokenName = tokenMap[mint];
if (tokenName) {
const currentPrice = parseFloat(data[mint].price);
const previousPrice = previousPrices[tokenName];
Want to automate this yourself?
Start with n8n Cloud (free tier available) or self-host on a Hetzner VPS for full control.
📬 Get Weekly Automation Tips
One email per week with tutorials, tools, and workflows. No spam, unsubscribe anytime.