Oracle & prices
Two public endpoints return the current oracle price for Noether’s markets: GET /v1/oracle/prices (all assets at once) and GET /v1/markets/{asset}/price (one asset). Both are live chain reads — the gateway queries the Noeracle shim contract’s lastprice function over Soroban RPC, so you get the same price the market contract itself trades against, not an indexer projection.
Base URL: https://noetherapi-production.up.railway.app. No authentication is required. Responses are cached in the gateway for 3 seconds per asset.
These prices come from the Noeracle oracle system running on Stellar testnet. For the full price chain — who signs prices, how they land on-chain, and the guards around them — see Oracle & price feeds.
Price format
Every price object has the same shape:
| Field | Type | Meaning |
|---|---|---|
asset | string | Asset symbol, e.g. BTC |
price | string | Price as a 7-decimal fixed-point integer, serialized as a string. Divide by 10,000,000 to get dollars: "632824877778" = $63,282.4877778 |
priceFloat | number | The same price pre-converted to a float, for convenience |
timestamp | integer | Unix seconds — the attestation time of the price currently stored on-chain |
Use the price string when you need exact math (it round-trips the on-chain integer value losslessly); use priceFloat for display. This 7-decimal string convention applies to money, price, and size fields across the API — the one exception is candle OHLC values, which are plain floats.
GET /v1/oracle/prices
Returns the current oracle price for all 14 supported assets: BTC, ETH, XLM, SOL, XRP, ADA, BNB, TRX, HYPE, DOGE, ZEC, LINK, BCH, LTC.
Auth: none. Parameters: none.
curl -s https://noetherapi-production.up.railway.app/v1/oracle/pricesResponse 200 (excerpt):
{
"prices": [
{ "asset": "BTC", "price": "632977577778", "priceFloat": 63297.7577778, "timestamp": 1783630712 },
{ "asset": "ETH", "price": "17486044444", "priceFloat": 1748.6044444, "timestamp": 1783630712 }
]
}The full response contains one entry per supported asset.
GET /v1/markets/{asset}/price
Returns the current oracle price for a single asset.
Auth: none.
| Parameter | In | Type | Notes |
|---|---|---|---|
asset | path | string | Asset symbol, e.g. BTC. Case-insensitive (uppercased server-side). Validated against the supported list — unknown symbols return 404 |
curl -s https://noetherapi-production.up.railway.app/v1/markets/BTC/priceResponse 200:
{ "asset": "BTC", "price": "632824877778", "priceFloat": 63282.4877778, "timestamp": 1783630283 }Response 404 for an unsupported asset:
{ "error": "Unknown asset", "asset": "FOO" }The same price object is also embedded in GET /v1/markets and GET /v1/markets/{asset} as the oracle field — see Markets. If you need every asset, prefer /v1/oracle/prices over N single-asset calls.
Staleness semantics
The timestamp field is the attestation time of the price currently stored on-chain, not the time of your HTTP request. Under normal operation the keeper pushes fresh signed prices every 30 seconds (its default cadence), so the timestamp is usually well under a minute old.
Two things to know when consuming it:
- The gateway never rejects a stale price on these read endpoints. It returns whatever the shim last stored, with its timestamp. If you need a freshness guarantee, compare
timestampagainst your own clock. - The chain enforces freshness for trading. The market contract rejects risk-increasing operations (opening positions, executing entry orders) when the on-chain price is older than 60 seconds, returning contract error 30 (
PriceStale). Risk-reducing operations — closes and liquidations — are never blocked by staleness. Trades placed through the web app go through the Noether Router, which relays a fresh signed price in the same transaction, so they can’t hit this limit. Transactions built by the API’s prepare/submit flow call the market contract directly and rely on the keeper’s regular price pushes instead — if the on-chain price has gone stale, a submit can fail with error 30. Details in Oracle & price feeds.
Allow up to 3 seconds of additional lag from the gateway’s per-asset cache.
For a streaming feed instead of polling, subscribe to the ticker.<ASSET> channel on the WebSocket API — it pushes the same shim-read price on a 3-second cadence. See WebSocket.
Rate limits
Both endpoints count against the public tier: 60 requests per minute per IP. Sending a valid API key (even on these public endpoints) moves you to your key’s bucket at 600 requests per minute. Every response carries X-RateLimit-Tier and X-RateLimit-Remaining headers; exceeding the limit returns 429 with a Retry-After header.
Next steps
- Markets — market list, stats, trades, and candles
- Trading — the prepare → sign → submit flow that uses these prices
- Oracle & price feeds — the full on-chain price chain