Claude-skill-registry coingecko
Complete CoinGecko Solana API integration for token prices, DEX pool data, OHLCV charts, trades, and market analytics. Use for building trading bots, portfolio trackers, price feeds, and on-chain data applications.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/coingecko" ~/.claude/skills/majiayu000-claude-skill-registry-coingecko && rm -rf "$T"
skills/data/coingecko/SKILL.mdCoinGecko Solana API Development Guide
A comprehensive guide for integrating CoinGecko's on-chain API for Solana. Access real-time token prices, DEX pool data, OHLCV charts, trade history, and market analytics across 1,700+ decentralized exchanges.
Overview
CoinGecko's Solana API provides:
- Token Prices: Real-time prices by contract address (single or batch)
- Pool Data: Liquidity pool information, trending pools, top pools
- OHLCV Charts: Candlestick data for technical analysis
- Trade History: Recent trades for any pool
- DEX Discovery: List all DEXes operating on Solana
- Search: Find pools by token name, symbol, or address
- Megafilter: Advanced filtering across pools, tokens, and DEXes
Key Features
| Feature | Description |
|---|---|
| 250+ Networks | Multi-chain support including Solana |
| 1,700+ DEXes | Raydium, Orca, Jupiter, Meteora, Pump.fun, etc. |
| 15M+ Tokens | Comprehensive token coverage |
| Real-time Data | Updates every 10-30 seconds |
| Historical Data | OHLCV charts and trade history |
Quick Start
Get Your API Key
- Demo API (Free): Visit coingecko.com/en/api
- Pro API (Paid): Visit coingecko.com/en/api/pricing
Environment Setup
# .env file COINGECKO_API_KEY=your_api_key_here COINGECKO_API_TYPE=demo # or 'pro'
API Configuration
// Configuration for both Demo and Pro APIs const CONFIG = { demo: { baseUrl: 'https://api.coingecko.com/api/v3/onchain', headerKey: 'x-cg-demo-api-key', rateLimit: 30, // calls per minute }, pro: { baseUrl: 'https://pro-api.coingecko.com/api/v3/onchain', headerKey: 'x-cg-pro-api-key', rateLimit: 500, // calls per minute (varies by plan) }, }; const apiType = process.env.COINGECKO_API_TYPE || 'demo'; const apiKey = process.env.COINGECKO_API_KEY; const BASE_URL = CONFIG[apiType].baseUrl; const HEADER_KEY = CONFIG[apiType].headerKey; // Solana network identifier const NETWORK = 'solana';
Basic Token Price Fetch
async function getTokenPrice(tokenAddress: string): Promise<number | null> { const url = `${BASE_URL}/simple/networks/${NETWORK}/token_price/${tokenAddress}`; const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey, 'Accept': 'application/json', }, }); if (!response.ok) { throw new Error(`API error: ${response.status}`); } const data = await response.json(); return data.data?.attributes?.token_prices?.[tokenAddress] ?? null; } // Usage const USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; const price = await getTokenPrice(USDC); console.log(`USDC Price: $${price}`);
API Endpoints Reference
Simple Token Price
Get token prices by contract address.
Endpoint:
GET /simple/networks/{network}/token_price/{addresses}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Network ID () |
| string | Yes | Comma-separated token addresses (max 30 Demo, 100 Pro) |
| boolean | No | Include market cap data |
| boolean | No | Include 24h volume |
| boolean | No | Include 24h price change % |
async function getTokenPrices(addresses: string[]): Promise<Record<string, TokenPriceData>> { const addressList = addresses.join(','); const url = `${BASE_URL}/simple/networks/${NETWORK}/token_price/${addressList}`; const params = new URLSearchParams({ include_market_cap: 'true', include_24hr_vol: 'true', include_24hr_price_change: 'true', }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.attributes || {}; }
Token Data by Address
Get detailed token information.
Endpoint:
GET /networks/{network}/tokens/{address}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Network ID |
| string | Yes | Token contract address |
| string | No | Include for liquidity data |
interface TokenData { address: string; name: string; symbol: string; decimals: number; image_url: string; price_usd: string; fdv_usd: string; market_cap_usd: string; total_supply: string; volume_usd: { h24: string; }; price_change_percentage: { h24: string; }; } async function getTokenData(address: string): Promise<TokenData> { const url = `${BASE_URL}/networks/${NETWORK}/tokens/${address}?include=top_pools`; const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.attributes; }
Multi-Token Data
Batch fetch multiple tokens.
Endpoint:
GET /networks/{network}/tokens/multi/{addresses}
async function getMultipleTokens(addresses: string[]): Promise<TokenData[]> { const addressList = addresses.join(','); const url = `${BASE_URL}/networks/${NETWORK}/tokens/multi/${addressList}`; const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; }
Pool Data by Address
Get detailed pool information.
Endpoint:
GET /networks/{network}/pools/{address}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | No | , , |
| boolean | No | Volume breakdown by timeframe |
interface PoolData { address: string; name: string; pool_created_at: string; base_token_price_usd: string; quote_token_price_usd: string; base_token_price_native_currency: string; fdv_usd: string; market_cap_usd: string; reserve_in_usd: string; price_change_percentage: { m5: string; h1: string; h6: string; h24: string; }; transactions: { m5: { buys: number; sells: number }; h1: { buys: number; sells: number }; h24: { buys: number; sells: number }; }; volume_usd: { m5: string; h1: string; h6: string; h24: string; }; } async function getPoolData(poolAddress: string): Promise<PoolData> { const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}`; const params = new URLSearchParams({ include: 'base_token,quote_token,dex', }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.attributes; }
Trending Pools
Get trending pools across all networks or filtered by network.
Endpoint:
GET /networks/trending_pools
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| string | | Attributes to include |
| integer | 1 | Page number |
| string | | , , , |
async function getTrendingPools(duration: '5m' | '1h' | '6h' | '24h' = '24h'): Promise<PoolData[]> { const url = `${BASE_URL}/networks/trending_pools`; const params = new URLSearchParams({ include: 'base_token,quote_token,dex,network', duration, page: '1', }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; } // Filter for Solana pools async function getSolanaTrendingPools(): Promise<PoolData[]> { const allPools = await getTrendingPools(); return allPools.filter(pool => pool.network === 'solana'); }
Top Pools on Network
Get top pools by volume on Solana.
Endpoint:
GET /networks/{network}/pools
async function getTopPools(page: number = 1): Promise<PoolData[]> { const url = `${BASE_URL}/networks/${NETWORK}/pools`; const params = new URLSearchParams({ include: 'base_token,quote_token,dex', page: page.toString(), }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; }
Search Pools
Search for pools by token name, symbol, or address.
Endpoint:
GET /search/pools
Parameters:
| Parameter | Type | Description |
|---|---|---|
| string | Search term (name, symbol, address) |
| string | Filter by network |
| integer | Page number |
async function searchPools(query: string): Promise<PoolData[]> { const url = `${BASE_URL}/search/pools`; const params = new URLSearchParams({ query, network: NETWORK, include: 'base_token,quote_token,dex', }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; } // Search for SOL pools const solPools = await searchPools('SOL');
Pool OHLCV Chart
Get candlestick data for technical analysis.
Endpoint:
GET /networks/{network}/pools/{pool_address}/ohlcv/{timeframe}
Timeframes:
day, hour, minute
Parameters:
| Parameter | Type | Description |
|---|---|---|
| integer | Candle aggregation (1, 5, 15 for minute; 1, 4, 12 for hour) |
| integer | Unix timestamp for pagination |
| integer | Number of candles (max 1000) |
| string | or |
interface OHLCVData { timestamp: number; open: number; high: number; low: number; close: number; volume: number; } async function getPoolOHLCV( poolAddress: string, timeframe: 'day' | 'hour' | 'minute' = 'hour', aggregate: number = 1, limit: number = 100 ): Promise<OHLCVData[]> { const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}/ohlcv/${timeframe}`; const params = new URLSearchParams({ aggregate: aggregate.toString(), limit: limit.toString(), currency: 'usd', }); const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.attributes?.ohlcv_list?.map((candle: number[]) => ({ timestamp: candle[0], open: candle[1], high: candle[2], low: candle[3], close: candle[4], volume: candle[5], })) || []; } // Get hourly candles const hourlyCandles = await getPoolOHLCV(poolAddress, 'hour', 1, 24); // Get 5-minute candles const fiveMinCandles = await getPoolOHLCV(poolAddress, 'minute', 5, 100);
Recent Trades
Get recent trades for a pool.
Endpoint:
GET /networks/{network}/pools/{pool_address}/trades
interface TradeData { block_number: number; block_timestamp: string; tx_hash: string; tx_from_address: string; from_token_amount: string; to_token_amount: string; price_from_in_currency_token: string; price_to_in_currency_token: string; price_from_in_usd: string; price_to_in_usd: string; kind: 'buy' | 'sell'; volume_in_usd: string; } async function getRecentTrades(poolAddress: string): Promise<TradeData[]> { const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}/trades`; const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; }
List DEXes on Solana
Get all decentralized exchanges on Solana.
Endpoint:
GET /networks/{network}/dexes
interface DexData { id: string; name: string; } async function getSolanaDexes(): Promise<DexData[]> { const url = `${BASE_URL}/networks/${NETWORK}/dexes`; const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => ({ id: item.id, name: item.attributes.name, })) || []; }
Megafilter (Advanced)
Advanced filtering for pools across networks, DEXes, and tokens.
Endpoint:
GET /pools/megafilter
Parameters:
| Parameter | Type | Description |
|---|---|---|
| string | Filter by network(s) |
| string | Filter by DEX(es) |
| string | Sort order (e.g., ) |
| number | Minimum liquidity |
| number | Minimum 24h volume |
async function getMegafilterPools(options: { dexes?: string[]; minLiquidity?: number; minVolume?: number; sort?: string; }): Promise<PoolData[]> { const url = `${BASE_URL}/pools/megafilter`; const params = new URLSearchParams({ networks: NETWORK, page: '1', }); if (options.dexes) { params.set('dexes', options.dexes.join(',')); } if (options.minLiquidity) { params.set('min_reserve_in_usd', options.minLiquidity.toString()); } if (options.minVolume) { params.set('min_h24_volume_usd', options.minVolume.toString()); } if (options.sort) { params.set('sort', options.sort); } const response = await fetch(`${url}?${params}`, { headers: { [HEADER_KEY]: apiKey }, }); const data = await response.json(); return data.data?.map((item: any) => item.attributes) || []; } // Get newest Pump.fun pools const pumpfunPools = await getMegafilterPools({ dexes: ['pump-fun'], sort: 'pool_created_at_desc', }); // Get high-volume Raydium pools const raydiumPools = await getMegafilterPools({ dexes: ['raydium'], minVolume: 100000, minLiquidity: 50000, });
Common Solana DEX Identifiers
| DEX | ID | Description |
|---|---|---|
| Raydium | | Leading AMM on Solana |
| Orca | | User-friendly DEX |
| Jupiter | | Aggregator with pools |
| Meteora | | Dynamic AMM |
| Pump.fun | | Memecoin launchpad |
| OpenBook | | Order book DEX |
| Lifinity | | Proactive market maker |
| Phoenix | | On-chain order book |
Common Token Addresses
| Token | Address |
|---|---|
| USDC | |
| USDT | |
| SOL (Wrapped) | |
| JUP | |
| BONK | |
| WIF | |
| PYTH | |
| RAY | |
| ORCA | |
Rate Limits
| Plan | Calls/Minute | Max Addresses/Request |
|---|---|---|
| Demo (Free) | 30 | 30 |
| Analyst | 500 | 50 |
| Lite | 500 | 50 |
| Pro | 1,000 | 100 |
| Enterprise | Custom | Custom |
Rate Limit Handling
class RateLimiter { private calls: number[] = []; private maxCalls: number; private windowMs: number = 60000; // 1 minute constructor(maxCallsPerMinute: number) { this.maxCalls = maxCallsPerMinute; } async waitForSlot(): Promise<void> { const now = Date.now(); this.calls = this.calls.filter(t => now - t < this.windowMs); if (this.calls.length >= this.maxCalls) { const oldestCall = this.calls[0]; const waitTime = this.windowMs - (now - oldestCall); await new Promise(resolve => setTimeout(resolve, waitTime)); } this.calls.push(Date.now()); } } // Usage const rateLimiter = new RateLimiter(30); // Demo API async function fetchWithRateLimit(url: string): Promise<any> { await rateLimiter.waitForSlot(); const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); return response.json(); }
Error Handling
async function safeApiCall<T>(url: string): Promise<T | null> { try { const response = await fetch(url, { headers: { [HEADER_KEY]: apiKey }, }); if (response.status === 401) { throw new Error('Invalid API key'); } if (response.status === 429) { throw new Error('Rate limit exceeded - wait before retrying'); } if (response.status === 404) { console.warn('Resource not found'); return null; } if (!response.ok) { throw new Error(`API error: ${response.status}`); } return response.json(); } catch (error) { console.error('CoinGecko API error:', error); throw error; } }
Common Error Codes
| Code | Meaning | Solution |
|---|---|---|
| 401 | Invalid API key | Check your API key |
| 429 | Rate limit exceeded | Wait and retry, or upgrade plan |
| 404 | Resource not found | Check address/network ID |
| 500+ | Server error | Retry with exponential backoff |
Best Practices
Security
- Never commit API keys to git
- Use environment variables
- Rotate keys periodically
- Use separate keys for dev/prod
Performance
- Batch token requests when possible
- Cache frequently accessed data
- Use appropriate timeframes for OHLCV
- Implement request queuing for rate limits
Data Quality
- Verify market cap data (may be null if unverified)
- Check pool liquidity before trusting prices
- Use multiple timeframes for price analysis
- Monitor last trade timestamp for activity
Resources
Skill Structure
coingecko/ ├── SKILL.md # This file ├── resources/ │ ├── api-reference.md # Complete API endpoint reference │ ├── network-dex-ids.md # Solana network and DEX identifiers │ └── token-addresses.md # Common Solana token addresses ├── examples/ │ ├── token-prices/ │ │ └── get-token-price.ts # Token price examples │ ├── pools/ │ │ └── pool-data.ts # Pool data examples │ ├── ohlcv/ │ │ └── ohlcv-charts.ts # OHLCV chart examples │ ├── trades/ │ │ └── recent-trades.ts # Trade history examples │ └── integration/ │ └── full-client.ts # Complete client example ├── templates/ │ └── coingecko-client.ts # Production-ready client template └── docs/ └── troubleshooting.md # Common issues and solutions