Excel & Google Sheets
Pull data into a spreadsheet as CSV with a formula or Power Query.
CSV from any data endpoint
Add format=csv to a GET data endpoint and the response is its rows as CSV with a header row. Spreadsheets can load that directly. Spreadsheet tools usually cannot send an Authorization header, so GET requests also accept the key as the api_key query parameter.
https://api.ohlc.io/v1/eod?symbols=XNAS:AAPL&from=2026-01-01&limit=500&format=csv&api_key=YOUR_API_KEYGoogle Sheets
Paste the URL into IMPORTDATA. The rows fill the sheet from that cell.
=IMPORTDATA("https://api.ohlc.io/v1/eod?symbols=XNAS:AAPL&from=2026-01-01&limit=500&format=csv&api_key=YOUR_API_KEY")Anyone who can view the sheet can read the formula, and the key in it. For a shared sheet, keep the key in Apps Script instead (Extensions, Apps Script) and call a custom function. Save the key under Project Settings, Script properties, as OHLC_API_KEY. Sheet viewers cannot see it; editors can.
function OHLC(path) {
const key = PropertiesService.getScriptProperties().getProperty("OHLC_API_KEY");
const url = "https://api.ohlc.io" + path + (path.includes("?") ? "&" : "?") + "format=csv";
const response = UrlFetchApp.fetch(url, { headers: { Authorization: "Bearer " + key } });
return Utilities.parseCsv(response.getContentText())
.map((row) => row.map((v) => (v !== "" && !isNaN(v) ? Number(v) : v)));
}=OHLC("/v1/eod?symbols=XNAS:AAPL&from=2026-01-01&limit=500")Excel
Use Power Query: Data, Get Data, From Web. Choose Advanced, enter the URL with format=csv and without the key, then add an HTTP request header named Authorization with the value Bearer YOUR_API_KEY. The key then stays out of the URL, and Refresh reloads the data.
https://api.ohlc.io/v1/eod?symbols=XNAS:AAPL&from=2026-01-01&limit=500&format=csvTools that only take a URL can use the api_key parameter instead, as in Google Sheets.
What the CSV contains
| JSON | CSV |
|---|---|
| Each record in data | One row; the first row holds the column names |
| Nested object, such as address | Dotted columns: address.city, address.region |
| List | JSON text in one cell, such as ["a","b"] |
| null | Empty cell |
| true / false | true / false |
| Decimal string, such as "-1.50" | The same digits, unrounded |
| Text that starts with =, +, - or @ | Prefixed with ' so the spreadsheet shows it rather than running it as a formula |
Files are UTF-8 with CRLF line endings. Values and timestamps are the same as in the JSON response, in UTC. Errors keep the JSON problem format described in Errors & retries.
Rows per request
A CSV response holds one page, up to limit rows. The maximum limit is 500. For longer history, narrow from and to and use one formula per range. The next page cursor is sent in the X-Next-Cursor response header, which scripts can pass back as cursor, and symbols that returned no rows are listed as JSON in X-Meta-Errors. For whole markets or years of history, use Flat files or exports.
Keys and usage
Use a separate key for each spreadsheet so you can revoke one without breaking the others. Every recalculation or refresh is a request and counts toward your plan limits. Google Sheets fetches from Google's servers, not your network, so a key with an IP allowlist will be refused there. Excel Power Query runs on your computer, so allowlists work with it. If a sheet or URL with a key is shared by mistake, revoke the key in the portal.