{"openapi":"3.1.0","info":{"title":"LNbits Price Aggregator","description":"Real-time BTC price aggregator that polls **Coinbase**, **Kraken**, **Bitfinex**,\n**Bitstamp**, **Binance**, **Coinmate**, and **Gemini**\non a configurable interval (default: 60 s) and serves the results from an in-memory cache.\n\nPer-currency statistics (min, max, median) are computed across all exchanges\nthat successfully returned a price in the most recent fetch cycle.\n\n## Notes\n\n- A `null` exchange value means the exchange does not list that currency pair\n  (e.g. Coinbase has no BTC-CHF), or the exchange has never successfully returned\n  a price since startup. Failed fetches preserve the last known value.\n- Statistics exclude `null` sources — with two live sources the median equals their mean.\n- The `timestamp` field reflects when the last background fetch completed.\n- Polling interval and currencies are set via environment variables (`.env`);\n  exchange URLs, supported pairs, and timeouts are set in `exchanges.json`.\n\n## Machine-readable schema\n\nThe full OpenAPI schema is available at [`/openapi.json`](/openapi.json).\n","license":{"name":"MIT"},"version":"1.0.0"},"paths":{"/rates":{"get":{"tags":["rates"],"summary":"Get current BTC prices","description":"Returns the most recent BTC prices fetched from Coinbase, Kraken, Bitfinex, Bitstamp,\nBinance, and Coinmate, broken down per currency and per exchange.\n\nPrices are refreshed every `FETCH_INTERVAL_SECONDS` seconds (default: 60) by a\nbackground task. This endpoint always returns the **cached** values — it never\nblocks on a live exchange request.\n\nExchange values are `null` when:\n- The exchange does not list that currency pair (Coinbase has no BTC-CHF).\n- The exchange has never successfully returned a price since startup.\n\nFailed fetches retain the last known value rather than flipping to `null`.\n\nStatistics (`min`, `max`, `median`) are computed only from non-null exchange prices.","operationId":"get_rates_rates_get","responses":{"200":{"description":"Price snapshot returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RatesResponse"}}}},"503":{"description":"No price data available yet. The server is still completing its first fetch after startup."}}}},"/rate/{currency}":{"get":{"tags":["rates"],"summary":"Get BTC price for one currency","description":"Returns the full exchange breakdown and statistics for a single currency. Use the `currency` path parameter to select the currency (e.g. `USD`, `EUR`, `CZK`).","operationId":"get_rate_rate__currency__get","parameters":[{"name":"currency","in":"path","required":true,"schema":{"type":"string","title":"Currency"}}],"responses":{"200":{"description":"Rate data returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyRateResponse"}}}},"404":{"description":"Currency not configured on this server."},"503":{"description":"No price data available yet."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rate/{currency}/{amount}":{"get":{"tags":["rates"],"summary":"Convert fiat amount to satoshis","description":"Converts `amount` units of `currency` to satoshis using the current median BTC price. The result is floored to the nearest whole satoshi.\n\nReturns `503` if no price data is available yet, or if all exchanges returned `null` for the requested currency.","operationId":"convert_to_sats_rate__currency___amount__get","parameters":[{"name":"currency","in":"path","required":true,"schema":{"type":"string","title":"Currency"}},{"name":"amount","in":"path","required":true,"schema":{"type":"number","title":"Amount"}}],"responses":{"200":{"description":"Conversion result returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertResponse"}}}},"404":{"description":"Currency not configured on this server."},"503":{"description":"No price data available yet or no median for this currency."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["ops"],"summary":"Health check","description":"Returns `{\"status\": \"ok\"}` when the server is running. Used by Docker HEALTHCHECK and load balancers.","operationId":"health_health_get","responses":{"200":{"description":"Server is healthy.","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}}},"components":{"schemas":{"ConvertResponse":{"properties":{"timestamp":{"type":"string","format":"date-time","title":"Timestamp","description":"UTC timestamp of the last successful background fetch."},"currency":{"type":"string","title":"Currency","description":"ISO 4217 currency code of the input amount."},"amount":{"type":"number","title":"Amount","description":"Input amount in the given currency."},"sats":{"type":"integer","title":"Sats","description":"Equivalent value in satoshis (floored)."},"rate":{"type":"number","title":"Rate","description":"Median BTC/{currency} price used for the conversion."}},"type":"object","required":["timestamp","currency","amount","sats","rate"],"title":"ConvertResponse","description":"Result of converting a fiat amount to satoshis."},"CurrencyRateResponse":{"properties":{"timestamp":{"type":"string","format":"date-time","title":"Timestamp","description":"UTC timestamp of the last successful background fetch."},"base":{"type":"string","const":"BTC","title":"Base","description":"The base asset. Always `BTC`."},"currency":{"type":"string","title":"Currency","description":"The requested ISO 4217 currency code."},"rates":{"$ref":"#/components/schemas/ExchangeRates","description":"Exchange breakdown and statistics for this currency."}},"type":"object","required":["timestamp","base","currency","rates"],"title":"CurrencyRateResponse","description":"BTC price data for a single requested currency."},"ExchangeRates":{"properties":{"median":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Median","description":"Median price across all exchanges that returned data. With two sources this equals their mean. `null` if no exchange returned data.","readOnly":true},"min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min","description":"Lowest price across all exchanges that returned data. `null` if no exchange returned data.","readOnly":true},"max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max","description":"Highest price across all exchanges that returned data. `null` if no exchange returned data.","readOnly":true},"coinbase":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Coinbase","description":"Last traded price on Coinbase Exchange. `null` if the pair is unlisted or no price has been received since startup."},"kraken":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kraken","description":"Last traded price on Kraken. `null` if the pair is unlisted or no price has been received since startup."},"bitfinex":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bitfinex","description":"Last traded price on Bitfinex. `null` if the pair is unlisted or no price has been received since startup."},"bitstamp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bitstamp","description":"Last traded price on Bitstamp. `null` if the pair is unlisted or no price has been received since startup."},"binance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Binance","description":"Last traded price on Binance. USD uses BTCUSDT. `null` if the pair is unlisted or no price has been received since startup."},"coinmate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Coinmate","description":"Last traded price on Coinmate (Czech exchange). CZK and EUR only. `null` if the pair is unlisted or no price has been received since startup."},"gemini":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Gemini","description":"Last traded price on Gemini. USD, EUR, and GBP only. `null` if the pair is unlisted or no price has been received since startup."}},"type":"object","required":["coinbase","kraken","bitfinex","bitstamp","binance","coinmate","gemini"],"title":"ExchangeRates","description":"BTC price data for a single fiat currency, broken down by exchange."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"RatesResponse":{"properties":{"timestamp":{"type":"string","format":"date-time","title":"Timestamp","description":"UTC timestamp of the last successful background fetch."},"base":{"type":"string","const":"BTC","title":"Base","description":"The base asset. Always `BTC`."},"rates":{"additionalProperties":{"$ref":"#/components/schemas/ExchangeRates"},"type":"object","title":"Rates","description":"Per-currency price breakdown keyed by ISO 4217 currency code (e.g. `USD`, `EUR`, `CHF`, `GBP`, `CZK`). Configured via the `CURRENCIES` env var."}},"type":"object","required":["timestamp","base","rates"],"title":"RatesResponse","description":"BTC price snapshot across all configured fiat currencies."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"rates","description":"BTC price data aggregated from multiple exchanges."},{"name":"ops","description":"Operational endpoints for health checks and monitoring."}]}