Market Data Integration Guide
Complete guide to integrating real-time cryptocurrency prices into your application.
Overview
This guide covers everything you need to integrate Rach Market Data API, from basic price fetching to real-time WebSocket streams.
Prerequisites
- Basic HTTP API knowledge
- (Optional) WebSocket experience for real-time updates
- (Optional) JWT authentication for favorites feature
API Base URL
Production: https://p2p.rach.finance/api/v1/market/
WebSocket: wss://p2p.rach.finance/ws/coins/Step 1: Fetch All Coin Prices
The simplest way to get started - fetch all 100+ cryptocurrencies:
bash
curl 'https://p2p.rach.finance/api/v1/market/prices/' \
-H 'Accept: application/json'javascript
async function getAllPrices() {
const response = await fetch('https://p2p.rach.finance/api/v1/market/prices/');
const coins = await response.json();
return coins;
}
// Usage
const prices = await getAllPrices();
console.log(`Total coins: ${prices.length}`);
console.log(`Bitcoin price: $${prices.find(c => c.symbol === 'btc')?.price}`);python
import requests
def get_all_prices():
url = 'https://p2p.rach.finance/api/v1/market/prices/'
response = requests.get(url)
return response.json()
# Usage
coins = get_all_prices()
print(f"Total coins: {len(coins)}")
btc = next(c for c in coins if c['symbol'] == 'btc')
print(f"Bitcoin: ${btc['price']:,.2f}")go
package main
import (
"encoding/json"
"net/http"
)
type Coin struct {
Name string `json:"name"`
Symbol string `json:"symbol"`
Price float64 `json:"price"`
}
func GetAllPrices() ([]Coin, error) {
resp, err := http.Get("https://p2p.rach.finance/api/v1/market/prices/")
if err != nil {
return nil, err
}
defer resp.Body.Close()
var coins []Coin
json.NewDecoder(resp.Body).Decode(&coins)
return coins, nil
}Step 2: Query Specific Coins
Single Coin Price
Get price for one specific cryptocurrency:
javascript
async function getCoinPrice(coinId) {
const response = await fetch(`https://p2p.rach.finance/api/v1/market/prices/${coinId}/`);
const data = await response.json();
return data[coinId].usd;
}
// Usage
const btcPrice = await getCoinPrice('bitcoin');
console.log(`BTC: $${btcPrice}`);Multiple Coins (Efficient)
Get multiple coins in a single request:
javascript
async function getMultiplePrices(symbols) {
const symbolsParam = symbols.join(',');
const response = await fetch(
`https://p2p.rach.finance/api/v1/market/prices/multi-prices/?symbols=${symbolsParam}`
);
return await response.json();
}
// Usage
const prices = await getMultiplePrices(['btc', 'eth', 'bnb', 'sol']);
console.log('BTC:', prices.btc.usd);
console.log('ETH:', prices.eth.usd);
console.log('BNB:', prices.bnb.usd);
console.log('SOL:', prices.sol.usd);Step 3: Real-Time Updates with WebSocket
For live price updates, use WebSocket instead of polling:
JavaScript / Browser
javascript
class CryptoMarketData {
constructor(onUpdate) {
this.onUpdate = onUpdate;
this.ws = null;
this.reconnectDelay = 1000;
}
connect() {
this.ws = new WebSocket('wss://p2p.rach.finance/ws/coins/');
this.ws.onopen = () => {
console.log('✅ Connected to market data stream');
this.reconnectDelay = 1000;
};
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
// data.text contains array of all coins
const coins = data.text;
// Callback with live data
this.onUpdate(coins);
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
this.ws.onclose = () => {
console.log('Disconnected. Reconnecting...');
setTimeout(() => this.connect(), this.reconnectDelay);
this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000);
};
}
disconnect() {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
}
// Usage
const marketData = new CryptoMarketData((coins) => {
// Update your UI with live prices
coins.forEach(coin => {
const element = document.getElementById(`price-${coin.symbol}`);
if (element) {
element.textContent = `$${coin.price?.toLocaleString()}`;
// Add visual indicator for price movement
element.className = coin.state; // 'raise', 'fail', or 'same'
}
});
});
marketData.connect();Python (WebSocket Client)
python
import asyncio
import websockets
import json
async def stream_market_data():
uri = "wss://p2p.rach.finance/ws/coins/"
async with websockets.connect(uri) as websocket:
print("Connected to market data stream")
while True:
message = await websocket.recv()
data = json.loads(message)
coins = data.get('text', [])
# Process live price updates
for coin in coins:
if coin.get('state') == 'raise':
print(f"📈 {coin['name']}: ${coin['price']}")
# Run
asyncio.run(stream_market_data())Step 4: Build a Portfolio Tracker
Complete example of a crypto portfolio tracker:
javascript
<!DOCTYPE html>
<html>
<head>
<title>Crypto Portfolio Tracker</title>
<style>
.coin { display: flex; justify-content: space-between; padding: 10px; }
.raise { color: green; }
.fail { color: red; }
.same { color: gray; }
</style>
</head>
<body>
<h1>Live Crypto Prices</h1>
<div id="portfolio"></div>
<script>
// Your portfolio holdings
const portfolio = {
'btc': 0.5,
'eth': 2.0,
'bnb': 10.0,
'sol': 50.0
};
// Connect to live prices
const ws = new WebSocket('wss://p2p.rach.finance/ws/coins/');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const coins = data.text;
let portfolioHTML = '';
let totalValue = 0;
coins.forEach(coin => {
const holding = portfolio[coin.symbol.toLowerCase()];
if (holding) {
const value = coin.price * holding;
totalValue += value;
portfolioHTML += `
<div class="coin ${coin.state}">
<img src="${coin.image}" width="24" />
<span>${coin.name} (${coin.symbol.toUpperCase()})</span>
<span>${holding} ${coin.symbol.toUpperCase()}</span>
<span>$${coin.price?.toLocaleString()} each</span>
<strong>$${value.toLocaleString()} total</strong>
</div>
`;
}
});
portfolioHTML += `<h2>Total Portfolio Value: $${totalValue.toLocaleString()}</h2>`;
document.getElementById('portfolio').innerHTML = portfolioHTML;
};
</script>
</body>
</html>Step 5: Manage Favorites (Authenticated)
For users to save favorite coins, you need authentication:
Get User's Favorites
javascript
async function getFavorites(jwtToken) {
const response = await fetch(
'https://p2p.rach.finance/api/v1/market/prices/coins/get/favorites/',
{
headers: {
'Authorization': `Bearer ${jwtToken}`
}
}
);
return await response.json();
}
// Usage
const favorites = await getFavorites(userToken);
favorites.forEach(fav => {
console.log(`${fav.coin_name}: $${fav.coin_price}`);
});Add to Favorites
javascript
async function addFavorite(jwtToken, coinId) {
const response = await fetch(
'https://p2p.rach.finance/api/v1/market/prices/coins/add/favorites/',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ coin_id: coinId })
}
);
return await response.json();
}
// Usage
await addFavorite(userToken, 'bitcoin');
console.log('Bitcoin added to favorites!');Remove from Favorites
javascript
async function removeFavorite(jwtToken, coinId) {
const response = await fetch(
'https://p2p.rach.finance/api/v1/market/prices/coins/remove/favorites/',
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ coin_id: coinId })
}
);
return await response.json();
}
// Usage
await removeFavorite(userToken, 'bitcoin');Performance Best Practices
1. Use WebSocket for Real-Time Data
❌ Don't Poll:
javascript
// BAD: Polling every second
setInterval(async () => {
const prices = await fetch('/api/v1/market/prices/');
// ...
}, 1000);✅ Do Use WebSocket:
javascript
// GOOD: Single persistent connection
const ws = new WebSocket('wss://p2p.rach.finance/ws/coins/');
ws.onmessage = (event) => {
// Instant updates
};2. Cache REST API Responses
javascript
// Cache API responses for 1 minute
const cache = new Map();
async function getCachedPrices() {
const cacheKey = 'all-prices';
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < 60000) {
return cached.data;
}
const data = await fetch('/api/v1/market/prices/').then(r => r.json());
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}3. Use Multi-Price Endpoint
javascript
// ❌ Multiple requests
const btc = await fetch('/api/v1/market/prices/bitcoin/');
const eth = await fetch('/api/v1/market/prices/ethereum/');
const bnb = await fetch('/api/v1/market/prices/binancecoin/');
// ✅ Single request
const prices = await fetch('/api/v1/market/prices/multi-prices/?symbols=btc,eth,bnb');Error Handling
javascript
async function safeFetchPrices() {
try {
const response = await fetch('https://p2p.rach.finance/api/v1/market/prices/');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('Failed to fetch prices:', error);
// Return fallback or cached data
return getCachedPrices();
}
}
// WebSocket error handling with reconnection
function connectWebSocket() {
const ws = new WebSocket('wss://p2p.rach.finance/ws/coins/');
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Connection lost. Reconnecting in 5s...');
setTimeout(connectWebSocket, 5000);
};
return ws;
}Complete React Example
javascript
import { useState, useEffect } from 'react';
function LiveCryptoPrices() {
const [coins, setCoins] = useState([]);
const [connected, setConnected] = useState(false);
const [filter, setFilter] = useState('');
useEffect(() => {
// Initial fetch
fetch('https://p2p.rach.finance/api/v1/market/prices/')
.then(res => res.json())
.then(setCoins);
// WebSocket for live updates
const ws = new WebSocket('wss://p2p.rach.finance/ws/coins/');
ws.onopen = () => setConnected(true);
ws.onclose = () => setConnected(false);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
setCoins(data.text);
};
return () => ws.close();
}, []);
const filteredCoins = coins.filter(coin =>
coin.name.toLowerCase().includes(filter.toLowerCase()) ||
coin.symbol.toLowerCase().includes(filter.toLowerCase())
);
return (
<div>
<div>
Status: {connected ? '🟢 Live' : '🔴 Disconnected'}
</div>
<input
type="text"
placeholder="Search coins..."
value={filter}
onChange={(e) => setFilter(e.target.value)}
/>
<table>
<thead>
<tr>
<th>Coin</th>
<th>Price</th>
<th>24h Change</th>
<th>Market Cap</th>
</tr>
</thead>
<tbody>
{filteredCoins.map(coin => (
<tr key={coin.symbol} className={coin.state}>
<td>
<img src={coin.image} width="20" alt={coin.name} />
{coin.name} ({coin.symbol.toUpperCase()})
</td>
<td>${coin.price?.toLocaleString()}</td>
<td className={coin.price_change_percentage_24h >= 0 ? 'green' : 'red'}>
{coin.price_change_percentage_24h?.toFixed(2)}%
</td>
<td>${(coin.market_cap / 1e9)?.toFixed(2)}B</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default LiveCryptoPrices;Next Steps
Need Help?
Join our community or contact support@rach.finance for integration assistance.
