Exchange Rates API
Get current Bitcoin exchange rates for supported currencies.
Overview
Lightning Enable provides real-time Bitcoin exchange rates via OpenNode. Use these endpoints to:
- Display BTC equivalent prices to customers
- Calculate payment amounts in local currency
- Build currency converters
note
Exchange rates are cached for 60 seconds to reduce API calls. For the most accurate rates at payment time, use the rate returned in the payment response.
Get All Rates
Get Bitcoin exchange rates for all supported currencies.
GET /api/rates
Request Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your merchant API key |
Response
{
"BTC": {
"USD": 42500.00,
"EUR": 39200.00,
"GBP": 33800.00,
"CAD": 57500.00,
"AUD": 65200.00,
"JPY": 6375000.00,
"CHF": 37800.00,
"CNY": 306000.00,
"INR": 3540000.00,
"BRL": 210000.00
},
"timestamp": "2024-12-29T12:00:00Z",
"source": "opennode"
}
Example
curl https://api.lightningenable.com/api/rates \
-H "X-API-Key: le_merchant_abc123"
Get Rate for Currency
Get Bitcoin exchange rate for a specific currency.
GET /api/rates/{currency}
Parameters
| Parameter | Type | Description |
|---|---|---|
currency | string | Currency code (USD, EUR, etc.) |
Response
{
"currency": "USD",
"rate": 42500.00,
"inverse": 0.00002353,
"timestamp": "2024-12-29T12:00:00Z"
}
Fields
| Field | Description |
|---|---|
currency | Currency code |
rate | 1 BTC = X currency |
inverse | 1 currency = X BTC |
timestamp | Rate timestamp |
Example
curl https://api.lightningenable.com/api/rates/USD \
-H "X-API-Key: le_merchant_abc123"
Supported Currencies
| Code | Currency | Symbol |
|---|---|---|
USD | US Dollar | $ |
EUR | Euro | Euro |
GBP | British Pound | Pound Sterling |
CAD | Canadian Dollar | C$ |
AUD | Australian Dollar | A$ |
JPY | Japanese Yen | Yen |
CHF | Swiss Franc | CHF |
CNY | Chinese Yuan | Yuan |
INR | Indian Rupee | Rupee |
BRL | Brazilian Real | R$ |
Currency Conversion
Convert Fiat to Satoshis
async function fiatToSats(amount, currency) {
const response = await fetch(
`https://api.lightningenable.com/api/rates/${currency}`,
{ headers: { 'X-API-Key': API_KEY } }
);
const { inverse } = await response.json();
// Convert to BTC, then to satoshis
const btc = amount * inverse;
const sats = Math.round(btc * 100000000);
return sats;
}
// Example: $50 USD to satoshis
const sats = await fiatToSats(50, 'USD');
console.log(`$50 = ${sats} sats`);
Convert Satoshis to Fiat
async function satsToFiat(sats, currency) {
const response = await fetch(
`https://api.lightningenable.com/api/rates/${currency}`,
{ headers: { 'X-API-Key': API_KEY } }
);
const { rate } = await response.json();
// Convert satoshis to BTC, then to fiat
const btc = sats / 100000000;
const fiat = btc * rate;
return fiat.toFixed(2);
}
// Example: 100000 sats to USD
const usd = await satsToFiat(100000, 'USD');
console.log(`100000 sats = $${usd}`);
Code Examples
JavaScript - Price Display
class PriceDisplay {
constructor(apiKey) {
this.apiKey = apiKey;
this.rates = null;
this.lastFetch = 0;
}
async getRates() {
// Cache for 60 seconds
if (this.rates && Date.now() - this.lastFetch < 60000) {
return this.rates;
}
const response = await fetch('https://api.lightningenable.com/api/rates', {
headers: { 'X-API-Key': this.apiKey }
});
this.rates = await response.json();
this.lastFetch = Date.now();
return this.rates;
}
async formatPrice(amountUsd) {
const { BTC } = await this.getRates();
const btc = amountUsd / BTC.USD;
const sats = Math.round(btc * 100000000);
return {
usd: `$${amountUsd.toFixed(2)}`,
btc: `${btc.toFixed(8)} BTC`,
sats: `${sats.toLocaleString()} sats`
};
}
}
// Usage
const display = new PriceDisplay('le_merchant_abc123');
const price = await display.formatPrice(49.99);
console.log(price);
// { usd: '$49.99', btc: '0.00117624 BTC', sats: '117,624 sats' }
C#
public class ExchangeRateService
{
private readonly HttpClient _client;
private ExchangeRates? _cachedRates;
private DateTime _cacheTime;
public async Task<decimal> ConvertToSats(decimal amount, string currency)
{
var rate = await GetRateAsync(currency);
var btc = amount * rate.Inverse;
return Math.Round(btc * 100_000_000m);
}
public async Task<RateResponse> GetRateAsync(string currency)
{
var response = await _client.GetAsync($"/api/rates/{currency}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<RateResponse>();
}
}
Python
import requests
from functools import lru_cache
from datetime import datetime, timedelta
class ExchangeRates:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://api.lightningenable.com'
self._cache = {}
self._cache_time = None
def get_rates(self):
# Return cached if less than 60 seconds old
if self._cache_time and datetime.now() - self._cache_time < timedelta(seconds=60):
return self._cache
response = requests.get(
f'{self.base_url}/api/rates',
headers={'X-API-Key': self.api_key}
)
response.raise_for_status()
self._cache = response.json()
self._cache_time = datetime.now()
return self._cache
def usd_to_sats(self, usd_amount):
rates = self.get_rates()
btc_rate = rates['BTC']['USD']
btc = usd_amount / btc_rate
return int(btc * 100_000_000)
def sats_to_usd(self, sats):
rates = self.get_rates()
btc_rate = rates['BTC']['USD']
btc = sats / 100_000_000
return round(btc * btc_rate, 2)
Error Responses
Invalid Currency
{
"error": "Bad Request",
"message": "Unsupported currency: XYZ",
"code": "INVALID_CURRENCY"
}
Rate Unavailable
{
"error": "Service Unavailable",
"message": "Exchange rates temporarily unavailable",
"code": "RATES_UNAVAILABLE"
}
Rate Limits
| Endpoint | Limit |
|---|---|
GET /api/rates | 100 requests/minute |
GET /api/rates/{currency} | 100 requests/minute |
tip
Cache exchange rates client-side for 30-60 seconds to reduce API calls and improve performance.
Best Practices
Display Both Currencies
Show customers both fiat and Bitcoin amounts:
<div class="price">
<span class="fiat">$49.99 USD</span>
<span class="btc">~117,624 sats</span>
</div>
Handle Rate Volatility
Bitcoin prices can change quickly. Consider:
- Lock rates at payment time - Use the rate from payment response
- Show approximate amounts - Use "~" prefix for estimates
- Refresh rates regularly - Update displayed rates every 30-60 seconds
Graceful Degradation
If rate API is unavailable, handle gracefully:
async function displayPrice(amountUsd) {
try {
const sats = await convertToSats(amountUsd);
return `$${amountUsd} (~${sats} sats)`;
} catch {
return `$${amountUsd}`;
}
}
Next Steps
- Payments API - Create payments with exchange rates
- Authentication - API key setup
- Errors - Error handling