BlockRun

Market Data (Pyth)

Spot prices and historical OHLC bars across four asset classes, grounded in Pyth Network on-chain feeds.

Crypto, FX and commodity prices are free. Equities — US and international — are $0.002 per call ($0.001 base plus the flat $0.001 transaction fee; the 402 quotes "0.0020"), because those feeds are broker-fed rather than open on-chain data. Every /list endpoint is free regardless of asset class.

Endpoints

EndpointMethodPriceDescription
/api/v1/crypto/listGETFreeAvailable crypto symbols
/api/v1/crypto/price/{symbol}GETFreeCrypto spot price
/api/v1/crypto/history/{symbol}GETFreeCrypto OHLC bars
/api/v1/fx/listGETFreeAvailable FX pairs
/api/v1/fx/price/{symbol}GETFreeFX spot rate
/api/v1/fx/history/{symbol}GETFreeFX OHLC bars
/api/v1/commodity/listGETFreeAvailable commodities
/api/v1/commodity/price/{symbol}GETFreeCommodity spot price
/api/v1/commodity/history/{symbol}GETFreeCommodity OHLC bars
/api/v1/usstock/listGETFreeUS tickers
/api/v1/usstock/price/{symbol}GET$0.002US equity spot price
/api/v1/usstock/history/{symbol}GET$0.002US equity OHLC bars
/api/v1/stocks/{market}/listGETFreeTickers for one non-US market
/api/v1/stocks/{market}/price/{symbol}GET$0.002Non-US equity spot price
/api/v1/stocks/{market}/history/{symbol}GET$0.002Non-US equity OHLC bars

GET and POST both work on the /price and /history paths; POST exists so callers that cannot attach headers to a GET still have a route. /list is GET only.

Symbol formats

Always resolve symbols from the matching /list endpoint rather than guessing.

Asset classFormatExamples
CryptoBASE-QUOTEBTC-USD, ETH-USD, SOL-USD
FXBASE-QUOTEEUR-USD, GBP-USD, JPY-USD
CommodityMETAL-USD / tickerXAU-USD (gold), XAG-USD (silver)
US equityPlain tickerAAPL, TSLA, NVDA, SPY
Non-US equityPer-market conventionHKEX -HK suffix (0005-HK), TSE 4-digit (7203), KRX 6-digit (005930), LSE/XETRA/Euronext alpha (HSBA, SAP, MC)

/list takes q (substring filter) and limit (max 2000, default 100) and returns { category, label, count, example, endpoints, symbols: [{ symbol, description }] }.

Markets

{market} for the /stocks/ family: us, hk, jp, kr, gb, de, fr, nl, ie, lu, cn, ca. An unknown market returns 404 with the supported list. /api/v1/usstock/* is a legacy alias for /api/v1/stocks/us/* and behaves identically.


Spot price

# Free — no payment header needed
curl https://blockrun.ai/api/v1/crypto/price/BTC-USD

# Paid — $0.002
curl https://blockrun.ai/api/v1/usstock/price/AAPL \
  -H "X-Payment: <x402_payment_token>"
ParameterInRequiredDescription
symbolpathYesAny symbol from the matching /list
sessionqueryNoEquity-only session hint — pre, post or on. Omit for regular hours; ignored for non-equity symbols

The response carries symbol, category, price, confidence (Pyth's interval around the price), publishTime (unix seconds), timestamp (ISO-8601), assetType, feedId and source: "pyth"; free feeds add free: true. Treat confidence as real: a wide interval means the feed is uncertain, not that the price is precise.


OHLC history

curl "https://blockrun.ai/api/v1/crypto/history/BTC-USD?resolution=D&from=1735689600&to=1738368000"
ParameterInRequiredDescription
symbolpathYesAny symbol from the matching /list
resolutionqueryNoBar size — 1, 5, 15, 60, 240, D, W, M. Default D; anything else is 400
fromqueryYesStart, unix seconds. Missing or non-positive is 400
toqueryNoEnd, unix seconds. Defaults to now; must be greater than from
sessionqueryNoEquity-only — pre, post or on

The response is { symbol, category, resolution, from, to, bars, source } where each bar is { t, o, h, l, c, v } (t = bar start in unix seconds). A valid symbol with no bars in the window returns 404 before any settlement, so an empty range is never charged.

On paid feeds the 402 is issued before parameter validation, so an unpaid probe always gets a clean payment challenge; validation errors only surface once a payment header is attached.


Discovery

Free endpoints answer HEAD with a 402 whose body is x402 discovery metadata ("error": "Payment Required (discovery)", free: true, amount 0) so indexers can register them — that is not a charge. A plain GET returns 200 and the data.

Paid feeds return a real 402 on an unpaid GET: the signed requirements are in the X-Payment-Required / PAYMENT-REQUIRED headers (and WWW-Authenticate), and the JSON body carries price.amount ("0.0020"), an example call and the same requirements under x402. Settled responses carry PAYMENT-RESPONSE and X-Payment-Receipt (transaction hash) headers.

Errors

StatusMeaningCharged?
400Bad resolution, missing/invalid from, or tofrom on /historyNo
402Payment required (paid feeds), or discovery metadata (HEAD/OPTIONS on free feeds)No
402error: "Payment verification failed"details has the verifier's reason. These feeds do not yet attach a machine-readable codeNo
402error: "Payment settlement failed" — data was fetched but settlement did not land; PAYMENT-RESPONSE carries errorReasonNo
404Symbol not found for that category (body has a hint), unknown {market}, or no bars in the requested windowNo
502Price feed upstream unavailable (5s timeout, one retry)No

What's next?