Bulk fundamentals

Download financial statements and ratios for every company as CSV files. Each file holds one fiscal year in one cadence: annual, quarterly, or trailing twelve months. One route lists every file together with a signed download link. Add year and period to get one file.

Signed download URLs are valid for one hour after URL generation. Start each file download within this window. If a URL expires, request a new one.

GET/v3.0.0/fundamental/bulk

Plan Access

Free

(Your plan)

Individual

$29/mo

Professional

$89/mo

Request
curl "https://api.roic.ai/v3.0.0/fundamental/bulk?apikey=YOUR_API_KEY"
Response
200 OK
{
  "data": [
    {
      "id": "bulk_tapriP_JZJiF3a_bg2LFze",
      "dataset": "fundamentals",
      "year": 2026,
      "period": "annual",
      "format": "csv",
      "compression": "gzip",
      "size": 27075542,
      "sha256": "b298e1d390981967ac505a5ce727498dbfa4f4d9c0a0059d760209b6197f3e62",
      "updated_at": "2026-09-08T01:30:42.469Z",
      "url": "https://bulk.roic.ai/fundamentals/v3/annual/2026.csv.gz?verify=1789064631-<mac>",
      "expires_at": "2026-09-08T19:23:51.178Z"
    },
    {
      "id": "bulk_0DH0HCx7d894zzXGjQbN01",
      "dataset": "fundamentals",
      "year": 2026,
      "period": "quarterly",
      "format": "csv",
      "compression": "gzip",
      "size": 170317736,
      "sha256": "f2f581cf314e8ef017f04de4b1e4f8af2e33ab83b33875c9a5977aab6791bd0d",
      "updated_at": "2026-09-08T01:31:03.348Z",
      "url": "https://bulk.roic.ai/fundamentals/v3/quarterly/2026.csv.gz?verify=1789064631-<mac>",
      "expires_at": "2026-09-08T19:23:51.178Z"
    }
  ],
  "next_page_url": null,
  "previous_page_url": null
}

Available files

Browse the files and download them from the browser. Downloads require a Professional or Enterprise plan. The route returns the same list with your API key.

Files140 files, 14.37 GB compressed

Fiscal yearPeriodSize
2027
Quarterly
12.7 MB
2027
TTM
12.8 MB
2026
Annual
31.2 MB
2026
Quarterly
208.7 MB
2026
TTM
206.0 MB
2025
Annual
128.9 MB
2025
Quarterly
343.4 MB
2025
TTM
342.0 MB
2024
Annual
131.4 MB
2024
Quarterly
371.8 MB
2024
TTM
372.6 MB
2023
Annual
130.8 MB
2023
Quarterly
368.6 MB
2023
TTM
369.6 MB
2022
Annual
129.1 MB
2022
Quarterly
360.6 MB
2022
TTM
360.6 MB
2021
Annual
125.3 MB
2021
Quarterly
344.2 MB
2021
TTM
342.6 MB
2020
Annual
118.7 MB
2020
Quarterly
323.5 MB
2020
TTM
321.7 MB
2019
Annual
114.4 MB
2019
Quarterly
308.6 MB
2019
TTM
306.9 MB
2018
Annual
108.9 MB
2018
Quarterly
291.8 MB
2018
TTM
291.9 MB
2017
Annual
104.6 MB
2017
Quarterly
279.8 MB
2017
TTM
279.7 MB
2016
Annual
100.2 MB
2016
Quarterly
268.9 MB
2016
TTM
269.2 MB
2015
Annual
96.5 MB
2015
Quarterly
260.0 MB
2015
TTM
260.7 MB
2014
Annual
92.5 MB
2014
Quarterly
247.8 MB
2014
TTM
248.1 MB
2013
Annual
88.3 MB
2013
Quarterly
235.5 MB
2013
TTM
234.2 MB
2012
Annual
84.7 MB
2012
Quarterly
218.3 MB
2012
TTM
216.6 MB
2011
Annual
80.9 MB
2011
Quarterly
207.6 MB
2011
TTM
207.1 MB
2010
Annual
76.5 MB
2010
Quarterly
185.0 MB
2010
TTM
178.2 MB
2009
Annual
72.4 MB
2009
Quarterly
144.2 MB
2009
TTM
123.6 MB
2008
Annual
67.4 MB
2008
Quarterly
110.5 MB
2008
TTM
109.3 MB
2007
Annual
60.2 MB
2007
Quarterly
98.6 MB
2007
TTM
98.3 MB
2006
Annual
52.5 MB
2006
Quarterly
97.0 MB
2006
TTM
93.5 MB
2005
Annual
46.9 MB
2005
Quarterly
87.7 MB
2005
TTM
87.1 MB
2004
Annual
39.1 MB
2004
Quarterly
81.9 MB
2004
TTM
81.3 MB
2003
Annual
34.4 MB
2003
Quarterly
76.1 MB
2003
TTM
74.8 MB
2002
Annual
31.0 MB
2002
Quarterly
69.3 MB
2002
TTM
66.8 MB
2001
Annual
25.5 MB
2001
Quarterly
61.0 MB
2001
TTM
59.0 MB
2000
Annual
22.9 MB
2000
Quarterly
54.9 MB
2000
TTM
52.1 MB
1999
Annual
19.8 MB
1999
Quarterly
45.4 MB
1999
TTM
44.2 MB
1998
Annual
17.7 MB
1998
Quarterly
40.3 MB
1998
TTM
39.4 MB
1997
Annual
15.3 MB
1997
Quarterly
36.0 MB
1997
TTM
35.1 MB
1996
Annual
13.3 MB
1996
Quarterly
32.1 MB
1996
TTM
31.9 MB
1995
Annual
11.8 MB
1995
Quarterly
29.3 MB
1995
TTM
29.5 MB
1994
Annual
10.5 MB
1994
Quarterly
26.6 MB
1994
TTM
26.5 MB
1993
Annual
9.1 MB
1993
Quarterly
22.9 MB
1993
TTM
23.2 MB
1992
Annual
8.0 MB
1992
Quarterly
21.1 MB
1992
TTM
21.1 MB
1991
Annual
7.4 MB
1991
Quarterly
19.3 MB
1991
TTM
19.5 MB
1990
Annual
6.5 MB
1990
Quarterly
16.4 MB
1990
TTM
15.5 MB
1989
Annual
5.8 MB
1989
Quarterly
8.8 MB
1989
TTM
8.2 MB
1988
Annual
4.3 MB
1988
Quarterly
5.3 MB
1988
TTM
5.6 MB
1987
Annual
4.1 MB
1987
Quarterly
5.0 MB
1987
TTM
5.3 MB
1986
Annual
3.8 MB
1986
Quarterly
4.7 MB
1986
TTM
5.0 MB
1985
Annual
3.5 MB
1985
Quarterly
4.4 MB
1985
TTM
4.3 MB
1984
Annual
3.1 MB
1984
Quarterly
3.1 MB
1984
TTM
1.4 MB
1983
Annual
2.9 MB
1983
Quarterly
92 KB
1983
TTM
3 KB
1982
Annual
2.7 MB
1982
Quarterly
3 KB
1981
Annual
2.4 MB
1980
Annual
2.4 MB
1979
Annual
1.9 MB
1978
Annual
56 KB

Parameters

Query parameters

yearintegeroptional

Return only the files of this year. Fundamentals and earnings calls use the fiscal year, stock prices use the calendar year. A year without files returns an empty list.

Example: 2026Min: 1900Max: 2100
periodstringoptional

Return only the files of this financial cadence. annual holds fiscal-year statements, quarterly holds the four fiscal quarters, and ttm holds trailing-twelve-month values at each quarter end.

Example: quarterlyValues: annualquarterlyttm

Response

Each item is one file with its size, its SHA-256 digest, and a signed url. Items are sorted newest fiscal year first, then annual, quarterly, ttm. Without filters the list holds every file, so the page URLs are always null. The example response is cut after two files. The response is not cached because every link expires one hour after the request.

Response fields

dataarray of objects

Array of file resources, newest year first. Without filters the array holds every available file, so the page URLs are always null.

+ Show child attributes
idstring

Stable identifier of the file, prefixed bulk_. It is derived from the storage path, so a rebuilt file keeps the same ID.

datasetstring

Dataset the file belongs to: fundamentals, earnings-calls, or stock-prices. The value is plural even for the singular /fundamental/bulk route.

yearnumber

Year of the data in the file. Fundamentals and earnings calls use the fiscal year. Stock prices use the calendar year.

periodstring

Slice of the year in the file. Fundamentals: annual, quarterly, or ttm. Earnings calls: q1 through q4. Stock prices: two-digit month 01 through 12.

formatstring

Always csv. The first row is a header row, and values obey RFC 4180.

compressionstring

Always gzip. Decompress the file before you read the CSV.

sizenumber

Size of the compressed .csv.gz file in bytes. The decompressed CSV is about three to four times larger.

sha256string

SHA-256 hex digest of the compressed file exactly as delivered. Compare it with the digest of your download before you decompress.

updated_atstring

ISO 8601 timestamp of the last rebuild of this file.

urlstring

Signed download link on bulk.roic.ai. Send a plain GET request without your API key and keep the verify token intact. Treat the link as a secret. The file host refuses links without a valid token.

expires_atstring

ISO 8601 timestamp after which url stops working, one hour after the request. Call the route again for fresh links if they expire before you start a download.

next_page_urlnullable

Relative URL of the next page, or null on the last page. Never contains your API key.

previous_page_urlnullable

Relative URL of the previous page, or null on the first page.

File contents

Each file is a gzip-compressed CSV with a header row and 301 columns. Rows are sorted by symbol, then by period end date. One row is one fiscal period of one company. The first 10 columns identify the period. The other 291 columns are the metrics of the income statement, balance sheet, cash flow, financial ratio, and valuation routes. The column names are the same as the API field names.

ColumnTypeMeaning
idstringStable period ID with the fnd_ prefix, the same as the API.
symbolstringExchange-qualified ticker, for example NASDAQ:AAPL.
period_typestringannual, quarterly, or ttm. Equal to the period of the file.
period_end_datedateLast day of the fiscal period in YYYY-MM-DD format.
fiscal_yearintegerFiscal year of the period. Equal to the year of the file.
period_labelstringFY for annual rows, or Q1 to Q4 for quarterly and TTM rows.
currencystringISO 4217 code of the reporting currency of the statements.
price_currencystringISO 4217 code of the trading currency of the ticker.
fx_appliedbooleant when values were converted from the reporting currency, otherwise f.
calculated_atstringISO 8601 timestamp of the last calculation of the row.
291 metric columnsnumberStatement line items and ratios, for example is_sales_revenue_turnover.

The first rows of the fiscal 2026 annual file, cut after the first metric columns:

id,symbol,period_type,period_end_date,fiscal_year,period_label,currency,price_currency,fx_applied,calculated_at,is_sales_revenue_turnover,is_sales_and_services_revenues,is_cogs,...
fnd_cZOVRrNs6h3KHE,AMEX:AXIL,annual,2026-05-31,2026,FY,USD,USD,f,2026-09-05T19:54:43.659Z,30847570,30847570,9467823,...
fnd_icLvMp8obR6OFF,AMEX:BGI,annual,2026-03-31,2026,FY,USD,USD,t,2026-09-07T23:44:51.514Z,147714787.01067105,147714787.01067105,90796588.71918774,...

Empty cells mean that the company did not report the metric. An empty cell is not zero. The header row in the file is authoritative for the column order.

Fiscal years run ahead of calendar years for some companies, so files for the next fiscal year can already exist. The route is the authoritative answer for what exists.

Download, verify, and decompress

Run these commands to download one file, verify the digest, and decompress it. Replace YOUR_API_KEY with your key.

# 1. Get the link and the digest of one file
RESP=$(curl -s -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.roic.ai/v3.0.0/fundamental/bulk?year=2026&period=quarterly")
URL=$(echo "$RESP" | jq -r '.data[0].url')
SHA=$(echo "$RESP" | jq -r '.data[0].sha256')
 
# 2. Download the file before the link expires
curl -o roic-fundamentals-2026-quarterly.csv.gz "$URL"
 
# 3. Verify the digest
echo "$SHA  roic-fundamentals-2026-quarterly.csv.gz" | shasum -a 256 -c
 
# 4. Decompress and keep the archive for the examples below
gunzip -k roic-fundamentals-2026-quarterly.csv.gz

To load a file into PostgreSQL, stream the decompressed CSV into COPY. The header row supplies the column list.

gunzip -c roic-fundamentals-2026-quarterly.csv.gz | \
  psql "$DATABASE_URL" -c "\copy fundamentals FROM STDIN WITH (FORMAT csv, HEADER true)"

Errors

StatusCodeCause
400invalid_parameterperiod is not annual, quarterly, or ttm, or year is not a number.
401authentication_requiredThe API key is missing. Related codes: invalid_api_key and multiple_authentication_methods.
402bulk_download_restrictedThe plan does not include bulk downloads.
429rate_limit_exceededThe request limit is reached. Retry after Retry-After.

A year without files returns an empty data array. The file host bulk.roic.ai blocks a link without a valid verify token or after expires_at. Call the route again for fresh links.