Luzia - Cryptocurrency Price API
Luzia provides real-time cryptocurrency price data aggregated from multiple exchanges (Binance, Coinbase, Kraken, Bybit, OKX) through a unified REST API, WebSocket streaming, and a TypeScript SDK. Use this skill to fetch ticker prices, compare prices across exchanges, and explore available markets.
Configuration
Before using this skill, you need a Luzia API key. Get one at https://luzia.dev
Set your API key in the skill configuration:
{
"skills": {
"entries": {
"luzia": {
"enabled": true,
"env": {
"LUZIA_API_KEY": "lz_your_api_key_here",
"LUZIA_BASE_URL": "https://api.luzia.dev"
}
}
}
}
}
TypeScript SDK
The official SDK (@luziadev/sdk) provides a type-safe client with automatic retries, rate limit handling, and WebSocket support.
Installation
npm install @luziadev/sdk
# or
bun add @luziadev/sdk
Quick Start
import { Luzia } from '@luziadev/sdk'
const luzia = new Luzia({
apiKey: 'lz_your_api_key',
// Optional:
baseUrl: 'https://api.luzia.dev', // default
timeout: 30000, // default (ms)
retry: {
maxRetries: 3,
initialDelayMs: 1000,
maxDelayMs: 30000,
backoffMultiplier: 2,
jitter: true,
},
})
// List exchanges
const exchanges = await luzia.exchanges.list()
// Get a single ticker
const ticker = await luzia.tickers.get('binance', 'BTC/USDT')
console.log(`BTC/USDT: $${ticker.last}`)
// List tickers for an exchange (paginated)
const { tickers, total } = await luzia.tickers.list('binance', { limit: 50 })
// Get specific tickers across exchanges
const { tickers } = await luzia.tickers.listFiltered({
exchange: 'binance',
symbols: ['BTC/USDT', 'ETH/USDT'],
})
// List markets with filters
const { markets } = await luzia.markets.list('binance', {
base: 'BTC',
quote: 'USDT',
active: true,
limit: 100,
})
Error Handling (SDK)
import { Luzia, LuziaError } from '@luziadev/sdk'
try {
const ticker = await luzia.tickers.get('binance', 'BTC/USDT')
} catch (error) {
if (error instanceof LuziaError) {
switch (error.code) {
case 'auth': // Invalid API key
case 'rate_limit': // Rate limited (error.retryAfter has seconds to wait)
case 'not_found': // Resource not found
case 'validation': // Invalid parameters (error.details)
case 'server': // Exchange temporarily unavailable
case 'network': // Network connectivity issue
case 'timeout': // Request timed out
}
}
}
Rate Limit Info (SDK)
const ticker = await luzia.tickers.get('binance', 'BTC/USDT')
const info = luzia.rateLimitInfo
// { remaining, limit, reset, dailyRemaining?, dailyLimit? }
The SDK automatically retries on rate limit (429), timeout (408), server errors (500/502/503/504), and network errors. Non-retryable errors (400, 401, 403, 404) are thrown immediately.
WebSocket (Real-Time Updates)
Stream live ticker updates over WebSocket. Requires Pro plan or higher.
Quick Start (SDK)
const luzia = new Luzia({ apiKey: 'lz_your_api_key' })
const ws = luzia.createWebSocket({
autoReconnect: true, // default: true
maxReconnectAttempts: 10, // default: 10, 0 = infinite
reconnectDelayMs: 1000, // default: 1000ms
maxReconnectDelayMs: 30000, // default: 30000ms
heartbeatIntervalMs: 30000, // default: 30000ms, 0 = disabled
})
ws.on('connected', (info) => {
console.log(`Connected (${info.tier}), max subs: ${info.limits.maxSubscriptions}`)
ws.subscribe(['ticker:binance:BTC/USDT', 'ticker:coinbase:ETH/USDT'])
})
ws.on('ticker', (data) => {
console.log(`${data.exchange} ${data.symbol}: $${data.data.last}`)
})
ws.on('error', (err) => {
console.error(`WebSocket error [${err.code}]: ${err.message}`)
})
ws.connect()
Channel Format
ticker:{exchange}:{symbol}- Specific pair (e.g.,ticker:binance:BTC/USDT)ticker:{exchange}- All tickers from an exchange (e.g.,ticker:binance)
Subscription Management
ws.subscribe(['ticker:binance:BTC/USDT', 'ticker:kraken:ETH/USDT'])
ws.unsubscribe(['ticker:binance:BTC/USDT'])
console.log(ws.subscriptions) // ReadonlySet<string>
console.log(ws.state) // 'disconnected' | 'connecting' | 'connected' | 'reconnecting'
ws.disconnect() // Graceful close, disables auto-reconnect
WebSocket Events
| Event | Payload | Description |
|---|---|---|
connected | { tier, limits } | Connection established |
ticker | { exchange, symbol, data, timestamp } | Price update |
subscribed | { channel } | Subscription confirmed |
unsubscribed | { channel } | Unsubscription confirmed |
error | { code, message } | Error occurred |
disconnected | { code, reason } | Connection closed |
reconnecting | { attempt, delayMs } | Reconnect attempt |
WebSocket Connection Limits
| Tier | Connections | Subscriptions / Connection |
|---|---|---|
| Free | Not available | -- |
| Pro | 5 | 50 |
| Enterprise | 25 | 500 |
Raw WebSocket Endpoint
GET /v1/ws?apiKey=lz_your_api_key
Requires WebSocket upgrade. Authentication via ?apiKey= query param or Authorization: Bearer header. Returns 101 Switching Protocols on success, 401 on auth failure, 403 if tier does not support WebSocket.
REST API Endpoints
Base URL: ${LUZIA_BASE_URL}/v1 (default: https://api.luzia.dev/v1)
All authenticated requests require the header: Authorization: Bearer ${LUZIA_API_KEY}
Get Single Ticker Price
Fetch the current price for a specific trading pair on an exchange.
GET /v1/ticker/:exchange/:symbol
Parameters:
exchange- Exchange identifier (e.g.,binance,coinbase,kraken,bybit,okx)symbol- Trading pair in formatBASE-QUOTE(e.g.,BTC-USDT,ETH-USD)maxAge(query, optional) - Maximum data age in ms (default: 120000)
Example Request:
curl -H "Authorization: Bearer ${LUZIA_API_KEY}" \
"${LUZIA_BASE_URL}/v1/ticker/binance/BTC-USDT"
Example Response:
{
"exchange": "binance",
"symbol": "BTC-USDT",
"last": "43250.50",
"bid": "43249.00",
"ask": "43251.00",
"high": "43800.00",
"low": "42500.00",
"volume": "12543.234",
"timestamp": "2024-01-15T10:30:00Z"
}
Get All Tickers for Exchange
Fetch all available ticker prices from a specific exchange (paginated).
GET /v1/tickers/:exchange
Parameters:
exchange- Exchange identifierlimit(query, optional) - Max results, default 20, max 50offset(query, optional) - Pagination offsetmaxAge(query, optional) - Maximum data age in ms
Example Request:
curl -H "Authorization: Bearer ${LUZIA_API_KEY}" \
"${LUZIA_BASE_URL}/v1/tickers/binance?limit=50"
Example Response:
{
"tickers": [
{
"symbol": "BTC-USDT",
"exchange": "binance",
"last": "43250.50",
"bid": "43249.00",
"ask": "43251.00",
"volume": "12543.234"
}
],
"total": 350,
"limit": 50,
"offset": 0
}
Get Multiple Tickers (Bulk)
Fetch tickers across exchanges with filtering.
GET /v1/tickers
Parameters (all query, optional):
exchange- Filter by exchangesymbols- Comma-separated symbol list (e.g.,BTC-USDT,ETH-USDT)limit- Max results, default 20, max 50offset- Pagination offsetmaxAge- Maximum data age in ms
Example Request:
curl -H "Authorization: Bearer ${LUZIA_API_KEY}" \
"${LUZIA_BASE_URL}/v1/tickers?exchange=binance&symbols=BTC-USDT,ETH-USDT"
List Supported Exchanges
Get a list of all supported cryptocurrency exchanges. No authentication required.
GET /v1/exchanges
Example Request:
curl "${LUZIA_BASE_URL}/v1/exchanges"
Example Response:
{
"exchanges": [
{ "id": "binance", "name": "Binance", "status": "active" },
{ "id": "coinbase", "name": "Coinbase", "status": "active" },
{ "id": "kraken", "name": "Kraken", "status": "active" },
{ "id": "bybit", "name": "Bybit", "status": "active" },
{ "id": "okx", "name": "OKX", "status": "active" }
]
}
List Markets for Exchange
Get all available trading pairs on a specific exchange.
GET /v1/markets/:exchange
Parameters:
exchange- Exchange identifierbase(query, optional) - Filter by base currency (e.g.,BTC)quote(query, optional) - Filter by quote currency (e.g.,USDT)active(query, optional) - Filter by active statuslimit(query, optional) - Max results, default 100, max 100offset(query, optional) - Pagination offset
Example Request:
curl -H "Authorization: Bearer ${LUZIA_API_KEY}" \
"${LUZIA_BASE_URL}/v1/markets/binance?quote=USDT"
Example Response:
{
"exchange": "binance",
"markets": [
{ "symbol": "BTC-USDT", "base": "BTC", "quote": "USDT", "active": true },
{ "symbol": "ETH-USDT", "base": "ETH", "quote": "USDT", "active": true }
],
"total": 2,
"limit": 100,
"offset": 0
}
Usage Examples
When users ask about cryptocurrency prices, use the Luzia API:
"What's the current Bitcoin price?"
-
Fetch from Binance (most liquid):
GET ${LUZIA_BASE_URL}/v1/ticker/binance/BTC-USDT Headers: Authorization: Bearer ${LUZIA_API_KEY} -
Report the price with bid/ask spread
"Compare ETH prices across exchanges"
-
Fetch from multiple exchanges in parallel:
GET ${LUZIA_BASE_URL}/v1/ticker/binance/ETH-USDT GET ${LUZIA_BASE_URL}/v1/ticker/coinbase/ETH-USD GET ${LUZIA_BASE_URL}/v1/ticker/kraken/ETH-USD -
Present a comparison table showing price differences and arbitrage opportunities
"What trading pairs are available on Coinbase?"
-
Fetch markets:
GET ${LUZIA_BASE_URL}/v1/markets/coinbase -
List the available pairs, optionally filtered by base currency
"Show me all crypto prices on Binance"
-
Fetch all tickers:
GET ${LUZIA_BASE_URL}/v1/tickers/binance?limit=50 -
Present as a formatted table sorted by volume or change
"Stream real-time BTC prices" (SDK only)
const luzia = new Luzia({ apiKey: 'lz_your_api_key' })
const ws = luzia.createWebSocket()
ws.on('connected', () => ws.subscribe(['ticker:binance:BTC/USDT']))
ws.on('ticker', (data) => console.log(`$${data.data.last}`))
ws.connect()
Rate Limits
Luzia enforces rate limits based on your subscription tier:
| Tier | Price | Requests/Minute | Requests/Day | WebSocket |
|---|---|---|---|---|
| Free | Free | 100 | 5,000 | No |
| Pro | $22.99/mo | 1,000 | 20,000 | Yes |
Rate limit headers are included in all responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067260
Retry-After: 30 (only on 429)
If you receive a 429 response, wait for the Retry-After duration before retrying.
Error Handling
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Invalid request (check symbol format) |
| 401 | Invalid or missing API key |
| 403 | Feature not available for your tier |
| 404 | Exchange or symbol not found |
| 429 | Rate limit exceeded |
| 503 | Exchange unavailable or stale data |
| 500 | Server error |
Supported Exchanges
| Exchange | ID | Ticker Pairs |
|---|---|---|
| Binance | binance | BTC-USDT, ETH-USDT, ... |
| Coinbase | coinbase | BTC-USD, ETH-USD, ... |
| Kraken | kraken | BTC-USD, ETH-USD, ... |
| Bybit | bybit | BTC-USDT, ETH-USDT, ... |
| OKX | okx | BTC-USDT, ETH-USDT, ... |
Tips
- Symbol format is always
BASE-QUOTE(e.g.,BTC-USDT, notBTCUSDT) - Use lowercase for exchange names (e.g.,
binance, notBinance) - The SDK uses
BASE/QUOTEformat (e.g.,BTC/USDT) while the REST API usesBASE-QUOTE(e.g.,BTC-USDT) - Cache responses when making multiple requests for the same data
- Compare prices across exchanges to find arbitrage opportunities
- Check the exchanges endpoint first to see which exchanges are currently active
- Use the bulk tickers endpoint (
GET /v1/tickers) to fetch multiple tickers in a single request - For real-time streaming, use the WebSocket API via the SDK (Pro tier required)
- The SDK automatically handles retries with exponential backoff for transient errors