Flat files
Nightly gzipped CSV files per trading date, with S3 push on Scale.
One file per dataset per trading date
Pro, Commercial and Scale plans receive nightly gzipped CSV files for the US market. Each file holds one dataset for one trading date, with the same raw, unadjusted values the REST API returns.
| Dataset | Contents | Same values as |
|---|---|---|
eod | Daily bars for every delivered instrument that traded, except mutual funds | GET /v1/eod |
corporate-actions | Dividends and splits with that ex_date | GET /v1/corporate-actions |
Files are kept once published. They start at the first trading date the nightly build produced, which is the oldest file the list returns; for earlier history use GET /v1/eod or an export. There are no intraday files: intraday bars are collected at five-minute intervals and served by GET /v1/intraday for 30 days. The knowledge cutoff of every file is its build time. Files for the last five trading days are rebuilt nightly, and the last two hourly, so a later correction republishes the file with a new sha256.
File format and columns
UTF-8 CSV with a header row, comma separated with RFC 4180 quoting, then gzip. An empty cell is null. Timestamps are UTC ISO 8601 with microseconds, such as 2026-09-24T20:00:00.000000Z. Prices and volumes are exact decimal strings with trailing zeros trimmed, such as 189.5. Booleans are true or false.
symbol is the exchange-qualified MIC:TICKER effective on that trading date; instrument_id is the stable ID that survives ticker changes, the same instrument_id the REST endpoints return. security_id holds the same value and is deprecated; it stays for readers that use it. Rows are sorted by symbol, then event time. eod rows carry the exchange-local trading date instead of timestamps.
symbol,exchange_mic,security_id,currency_code,date,open,high,low,close,volume,trade_count,instrument_idsymbol,exchange_mic,security_id,action_type,ex_date,record_date,pay_date,effective_at,announced_at,declaration_date,frequency,is_cancelled,cash_amount,cash_currency,ratio_numerator,ratio_denominator,legs,knowable_at,instrument_idaction_type is cash_dividend, stock_dividend or split. cash_amount, cash_currency, ratio_numerator and ratio_denominator come from the first leg; legs is the full JSON array of legs exactly as GET /v1/corporate-actions returns it.
List and download
GET /v1/flat-files lists available files, newest date first. dataset is optional (eod or corporate-actions); without it, only datasets your key is entitled to are listed. from and to are inclusive dates (YYYY-MM-DD), so from equal to to selects one day. limit is 1 to 500, default 100; follow meta.next_cursor for more.
{
"data": [
{
"dataset": "eod",
"market": "us",
"date": "2026-09-24",
"rows": 11234,
"bytes": 3456789,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"generated_at": "2026-09-25T05:31:02.123456Z",
"download_path": "/v1/flat-files/eod/2026-09-24?download=true"
}
],
"meta": {
"timezone": "UTC",
"next_cursor": null
}
}GET /v1/flat-files/{dataset}/{date} returns one file's metadata. Add download=true to get the file: it normally responds 302 with a Location header pointing at a presigned storage URL that is valid for 5 minutes; follow the redirect. The presigned URL needs no API key, so don't forward your Authorization header to it. Some deployments stream the file directly with 200 and application/gzip.
curl -sSL -H "Authorization: Bearer $OHLC_API_KEY" \
-o eod-2026-09-24.csv.gz \
"https://api.ohlc.io/v1/flat-files/eod/2026-09-24?download=true"Each download costs 500 credits (listing and metadata requests 5) and is recorded in the delivery audit like other deliveries.
List flat files reference Download a flat file referenceVerify every file
Download responses carry X-Content-SHA256, the hex SHA-256 of the .csv.gz. The same value is the sha256 in the listing. Compare it before loading the file.
curl -sSL -D headers.txt -H "Authorization: Bearer $OHLC_API_KEY" \
-o eod-2026-09-24.csv.gz \
"https://api.ohlc.io/v1/flat-files/eod/2026-09-24?download=true"
expected=$(grep -i "^x-content-sha256:" headers.txt | tail -1 | tr -d "\r" | cut -d" " -f2)
echo "$expected eod-2026-09-24.csv.gz" | shasum -a 256 -c -Schedule and corrections
Files are built nightly at 01:30 New York time for the previous trading day, so a trading date's files appear after the nightly build that follows it. Each run also re-checks the last 5 trading days and republishes a file only when its content changed, for example after a provider correction. A republished file has a new sha256 and generated_at; compare sha256 to find changes.
Access
Flat files require a Pro, Commercial or Scale plan. The API key needs flat-files.read plus the dataset capability (eod.read or corporate-actions.read), an entitled US market, and a date within your plan's history depth.
Errors are RFC 9457 problems: 403 capability-not-entitled, market-not-entitled or history-not-entitled; 404 flat-file-not-found; 422 invalid-request.
Plan comparisonS3 push on Scale
Scale accounts can have the same files pushed to one S3 or S3-compatible bucket, such as Cloudflare R2, MinIO or Wasabi. Workspace owners and admins add it in the portal under Settings, S3 delivery: bucket, region, an optional custom endpoint and path-style addressing, an optional prefix, and an access key ID and secret. The secret is stored encrypted and never shown again.
{prefix}/us/{dataset}/{YYYY}/{YYYY-MM-DD}.csv.gz
ohlc/us/eod/2026/2026-09-24.csv.gzThe prefix is omitted when empty. Send test file writes and deletes a small {prefix}/.ohlc-verification-<random>.txt object and marks the destination verified; only verified destinations receive files. Changing the bucket, region, endpoint or prefix clears verification, and every file is sent again once you re-verify; new keys also need a new test.
The key needs s3:PutObject, s3:PutObjectAcl and s3:DeleteObject on the prefix; DeleteObject is only used by the test. Delivery runs nightly at 02:30 New York time after the build, with a retry pass at 06:30. Only new or changed files are sent, failures retry on the next pass, and the portal shows the last error.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-bucket/ohlc/*"
}
]
}