Load daily bars with Power Query
- In Excel, choose Data → Get Data → From Other Sources → From Web, then Advanced.
- Enter the URL without your key:
https://api.ohlc.io/v1/eod?symbols=XNAS:AAPL&from=2026-01-01&limit=500&format=csv. - Under HTTP request header parameters, add
Authorizationwith the valueBearer YOUR_API_KEY. - If Excel asks how to connect, choose Anonymous: the header already carries the key.
- In the preview, choose Transform Data, set
open,high,low,closeandvolumeto Decimal Number anddateto Date, then Close & Load. - Use Refresh (or Refresh All) to fetch new bars. Each refresh is one request.
The same query in Power Query's formula language, if you prefer to paste it into the Advanced Editor:
let
Source = Csv.Document(
Web.Contents(
"https://api.ohlc.io/v1/eod",
[
Query = [symbols = "XNAS:AAPL,XNYS:JNJ", from = "2026-01-01", limit = "500", format = "csv"],
Headers = [Authorization = "Bearer YOUR_API_KEY"]
]
),
[Delimiter = ",", Encoding = 65001, QuoteStyle = QuoteStyle.Csv]
),
Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
Typed = Table.TransformColumnTypes(
Promoted,
{{"date", type date}, {"open", type number}, {"high", type number},
{"low", type number}, {"close", type number}, {"volume", Int64.Type}},
"en-US"
)
in
TypedA single value with WEBSERVICE
For one number in a cell, such as the latest close, WEBSERVICE can fetch CSV directly. It only takes a URL, so the key goes in the api_key query parameter. WEBSERVICE works in Excel for Windows (it returns no results on Mac) and fails with #VALUE! past 32,767 characters, so keep the request to a row or two. TEXTSPLIT, TAKE and XMATCH need Microsoft 365.
=LET(
csv, WEBSERVICE("https://api.ohlc.io/v1/eod?symbols=XNAS:AAPL&order=desc&limit=1&format=csv&api_key=YOUR_API_KEY"),
t, TEXTSPLIT(csv, ",", CHAR(13)&CHAR(10), TRUE),
VALUE(INDEX(t, 2, XMATCH("close", TAKE(t, 1))))
)Looking the column up by name with XMATCH keeps the formula working if columns are added. The value is the most recent end-of-day close; for a delayed intraday price use /v1/quotes and the last_price column, which is at least 15 minutes old.
Other endpoints worth loading
Power Query handles any GET data endpoint the same way: change the path and query, keep format=csv and the header. A few that suit workbooks:
/v1/eod?symbols=...&adjustment=total_returnfor return calculations that include dividends. See adjusted stock prices./v1/quotes?symbols=...for a watchlist of delayed prices, withlast_priceandlast_atcolumns in UTC./v1/dividends?symbols=...&from=2021-01-01for ex-dates, pay dates and amounts./v1/financials/metrics?symbols=...for valuation ratios, market capitalization and dividend yield, at 50 credits per symbol.
Nested objects become dotted columns such as address.city, lists arrive as JSON text in one cell, and text that starts with =, +, - or @ is prefixed with an apostrophe so Excel shows it instead of running it. Timestamps are UTC; daily bars use the exchange-local trading date.
Rows, pages and credits
- A CSV response holds one page of up to 500 rows (
limit=500). For longer history, split the range withfromandtoand use one query per range. - The next page's cursor is in the
X-Next-Cursorresponse header, and symbols that returned no rows are listed inX-Meta-Errors. - Every refresh or recalculation is a request: daily bars cost 5 credits per symbol, so a 20-symbol query costs 100 credits per refresh.
- For whole markets or years of history, use flat files on Pro and above, or exports on Commercial and Scale.
Use a separate API key for each workbook so you can revoke one without breaking the others. A key in a WEBSERVICE URL is visible to anyone who opens the file; prefer Power Query with a header for shared workbooks.