A fully self-hosted cryptocurrency price API that aggregates real-time data from multiple sources including on-chain DEX pools and external APIs. Deploy your own price feed infrastructure with a single command.
Most cryptocurrency price APIs come with limitations: rate limits, API keys, costs, and dependency on third-party services. This project gives you:
- Full Control - Your data, your infrastructure, your rules
- No Rate Limits - Query as often as you need
- No API Costs - Free after deployment
- Privacy - No tracking or data sharing
- Customization - Add any token, any chain, any source
- Reliability - Multiple data sources with automatic failover
- On-Chain DEX Pools - Direct price feeds from Uniswap V2/V3 pools
- CoinGecko - Free tier integration (pre-configured)
- CoinMarketCap - Optional with API key
- Extensible - Easy to add new sources
- Ethereum Mainnet
- Base
- Arbitrum One
- Polygon
- Optimism
- Easy to add more EVM chains
- REST API - Simple JSON endpoints
- WebSocket - Real-time price streaming
- Historical Data - OHLCV candles (1m, 5m, 15m, 1h, 1d)
- Multi-token - Track unlimited tokens
- Authentication - Optional API key system
- Rate Limiting - Configurable per-key limits
- Web-based configuration UI
- Pool management (add by contract address)
- Data source health monitoring
- API key management
- Price charts with historical data
- System settings
# Clone the repository
git clone https://github.com/UnHeardCoder/self-hosted-crypto-api.git
cd self-hosted-crypto-api
# Start the services
docker-compose up -d
# Check logs
docker-compose logs -fThat's it! Open http://localhost:3000 to access the dashboard.
On first visit, you'll create an admin account. The system comes pre-configured with:
- 5 EVM chains with public RPC endpoints
- CoinGecko as a default price source
Your database is stored in a Docker volume called crypto-price-data. This persists even if you delete containers or the project folder.
# View the volume
docker volume ls
# Reset everything (WARNING: deletes all data!)
docker-compose down -v- Add a Pool - Go to Pools → Add Pool → Enter a Uniswap pool address
- View Prices - Check the Dashboard for live prices
- Generate API Key - Go to API Keys to create access tokens
- Explore the API - Check API Docs for endpoint reference
┌─────────────────────────────────────────────────────────────────┐
│ Clients │
│ (Your Apps, Trading Bots, Websites) │
└─────────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Web Dashboard (React) │
│ http://localhost:3000 │
│ ┌──────────────────────────────────────────┐ │
│ │ Dashboard │ Charts │ Pools │ Settings │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────────────┘
│ nginx proxy
▼
┌─────────────────────────────────────────────────────────────────┐
│ API Server (Fastify) │
│ http://localhost:3001 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ REST API │ │ WebSocket │ │ Admin Routes │ │
│ │ /api/v1/* │ │ /ws │ │ /admin/* │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
└───────────┬─────────────────────────────────┬───────────────────┘
│ │
▼ ▼
┌───────────────────────┐ ┌───────────────────────────────┐
│ Background Worker │ │ SQLite Database │
│ ┌─────────────────┐ │ │ ┌─────────────────────────┐ │
│ │ CoinGecko Poller│ │ │ │ prices, candles, pools │ │
│ │ Pool Poller │ │────────▶│ │ tokens, sources, users │ │
│ │ Candle Builder │ │ │ │ api_keys, settings │ │
│ └─────────────────┘ │ │ └─────────────────────────┘ │
└───────────┬───────────┘ └───────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ External Data Sources │
│ ┌─────────────┐ ┌─────────────┐ ┌───────────────────────┐ │
│ │ CoinGecko │ │ CoinMarket │ │ On-Chain RPC Nodes │ │
│ │ API │ │ Cap API │ │ (Ethereum, Base...) │ │
│ └─────────────┘ └─────────────┘ └───────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
- Data Collection - Background workers poll external APIs and on-chain pools at configurable intervals
- Price Aggregation - Multiple sources are combined using weighted averages based on priority
- Candle Building - Raw price ticks are aggregated into OHLCV candles every minute
- API Serving - REST and WebSocket endpoints serve aggregated data to clients
- Real-time Updates - Price changes are broadcast via WebSocket to subscribed clients
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/prices |
Get all current prices |
GET |
/api/v1/prices/:symbol |
Get price for specific token |
GET |
/api/v1/prices/:symbol/history |
Get OHLCV candles |
GET |
/api/v1/pools |
List enabled pools |
GET |
/api/v1/sources |
List data sources |
GET |
/api/v1/health |
Health check |
curl http://localhost:3001/api/v1/prices{
"prices": [
{
"symbol": "ETH",
"price": 3245.67,
"timestamp": "2024-01-09T12:00:00.000Z",
"sourcesUsed": 2,
"change24h": {
"percent": 2.5,
"absolute": 79.12,
"high": 3300.00,
"low": 3150.00
}
}
],
"count": 1
}curl "http://localhost:3001/api/v1/prices/ETH/history?interval=1h&limit=24"{
"symbol": "ETH",
"interval": "1h",
"candles": [
{
"openTime": "2024-01-09T11:00:00.000Z",
"open": 3240.00,
"high": 3250.00,
"low": 3235.00,
"close": 3245.67,
"volume": 125000.50
}
],
"count": 24
}Connect to ws://localhost:3001/api/v1/ws for real-time updates:
const ws = new WebSocket('ws://localhost:3001/api/v1/ws');
// Subscribe to specific tokens
ws.send(JSON.stringify({
action: 'subscribe',
tokens: ['ETH', 'BTC']
}));
// Or subscribe to all prices
ws.send(JSON.stringify({
action: 'subscribe',
all: true
}));
// Receive updates
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(`${data.symbol}: $${data.price}`);
};For complete API documentation, see docs/API.md.
| Variable | Default | Description |
|---|---|---|
WEB_PORT |
3000 |
Dashboard port |
API_PORT |
3001 |
API server port |
DATABASE_URL |
./data/crypto-prices.db |
SQLite database path |
LOG_LEVEL |
info |
Log level (trace, debug, info, warn, error) |
SESSION_SECRET |
- | Session signing key (change in production!) |
Copy .env.example to .env and customize:
cp .env.example .env- Go to Chains in the dashboard
- Click Add Chain
- Enter chain details:
- Name:
My Custom Chain - Chain ID:
1234 - RPC URL:
https://rpc.example.com - WebSocket URL (optional):
wss://ws.example.com
- Name:
- Go to Pools in the dashboard
- Click Add Pool
- Select chain and enter pool address
- System auto-detects tokens and DEX type
- Enable to start price tracking
docker-compose up -dServices:
api- Backend API on port 3001web- Frontend dashboard on port 3000
# Backend
npm install
npm run build
npm start
# Frontend (separate terminal)
cd web
npm install
npm run build
npm run previewFor production, put behind a reverse proxy like nginx or Caddy:
# nginx example
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}For detailed deployment guides, see docs/DEPLOYMENT.md.
- Personal Portfolio Tracker - Track your holdings with real-time prices
- DeFi Application Backend - Power your DeFi app with reliable price data
- Trading Bot Data Source - Feed your trading algorithms with low-latency prices
- Price Oracle - Use as a price feed for smart contracts
- Research & Analytics - Historical data for backtesting and analysis
- Backend: Node.js, TypeScript, Fastify
- Frontend: React, Vite, TailwindCSS, Recharts
- Database: SQLite with Drizzle ORM
- Blockchain: viem for EVM interactions
- Deployment: Docker, Docker Compose
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with care for the self-hosted and crypto community.



