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, 13.06 GB compressed

Fiscal yearPeriodSize
2027
Quarterly
7.9 MB
2027
TTM
7.9 MB
2026
Annual
27.5 MB
2026
Quarterly
174.9 MB
2026
TTM
173.0 MB
2025
Annual
122.5 MB
2025
Quarterly
314.5 MB
2025
TTM
312.8 MB
2024
Annual
122.4 MB
2024
Quarterly
343.5 MB
2024
TTM
344.1 MB
2023
Annual
120.2 MB
2023
Quarterly
338.2 MB
2023
TTM
338.9 MB
2022
Annual
118.0 MB
2022
Quarterly
329.5 MB
2022
TTM
329.4 MB
2021
Annual
114.1 MB
2021
Quarterly
314.1 MB
2021
TTM
313.0 MB
2020
Annual
107.8 MB
2020
Quarterly
295.4 MB
2020
TTM
294.0 MB
2019
Annual
104.1 MB
2019
Quarterly
281.8 MB
2019
TTM
280.4 MB
2018
Annual
99.1 MB
2018
Quarterly
265.6 MB
2018
TTM
265.9 MB
2017
Annual
95.0 MB
2017
Quarterly
254.3 MB
2017
TTM
254.4 MB
2016
Annual
91.1 MB
2016
Quarterly
244.4 MB
2016
TTM
244.7 MB
2015
Annual
87.6 MB
2015
Quarterly
236.1 MB
2015
TTM
236.6 MB
2014
Annual
83.9 MB
2014
Quarterly
224.7 MB
2014
TTM
224.8 MB
2013
Annual
79.9 MB
2013
Quarterly
213.3 MB
2013
TTM
212.2 MB
2012
Annual
76.5 MB
2012
Quarterly
198.0 MB
2012
TTM
196.8 MB
2011
Annual
73.1 MB
2011
Quarterly
189.0 MB
2011
TTM
188.5 MB
2010
Annual
68.9 MB
2010
Quarterly
168.0 MB
2010
TTM
161.6 MB
2009
Annual
65.3 MB
2009
Quarterly
130.7 MB
2009
TTM
112.0 MB
2008
Annual
60.7 MB
2008
Quarterly
100.1 MB
2008
TTM
99.0 MB
2007
Annual
54.3 MB
2007
Quarterly
89.2 MB
2007
TTM
88.7 MB
2006
Annual
47.1 MB
2006
Quarterly
88.0 MB
2006
TTM
84.5 MB
2005
Annual
42.2 MB
2005
Quarterly
79.3 MB
2005
TTM
78.6 MB
2004
Annual
35.3 MB
2004
Quarterly
73.9 MB
2004
TTM
73.3 MB
2003
Annual
31.1 MB
2003
Quarterly
68.7 MB
2003
TTM
67.4 MB
2002
Annual
28.0 MB
2002
Quarterly
62.4 MB
2002
TTM
60.0 MB
2001
Annual
23.0 MB
2001
Quarterly
54.8 MB
2001
TTM
52.9 MB
2000
Annual
20.7 MB
2000
Quarterly
49.6 MB
2000
TTM
47.1 MB
1999
Annual
17.9 MB
1999
Quarterly
41.3 MB
1999
TTM
40.1 MB
1998
Annual
16.0 MB
1998
Quarterly
36.8 MB
1998
TTM
35.8 MB
1997
Annual
13.9 MB
1997
Quarterly
33.0 MB
1997
TTM
32.2 MB
1996
Annual
12.1 MB
1996
Quarterly
29.5 MB
1996
TTM
29.2 MB
1995
Annual
10.8 MB
1995
Quarterly
27.0 MB
1995
TTM
27.1 MB
1994
Annual
9.6 MB
1994
Quarterly
24.7 MB
1994
TTM
24.5 MB
1993
Annual
8.4 MB
1993
Quarterly
21.2 MB
1993
TTM
21.5 MB
1992
Annual
7.4 MB
1992
Quarterly
19.6 MB
1992
TTM
19.5 MB
1991
Annual
6.8 MB
1991
Quarterly
17.9 MB
1991
TTM
18.1 MB
1990
Annual
6.0 MB
1990
Quarterly
15.2 MB
1990
TTM
14.3 MB
1989
Annual
5.3 MB
1989
Quarterly
8.2 MB
1989
TTM
7.6 MB
1988
Annual
4.0 MB
1988
Quarterly
4.9 MB
1988
TTM
5.2 MB
1987
Annual
3.8 MB
1987
Quarterly
4.7 MB
1987
TTM
4.9 MB
1986
Annual
3.5 MB
1986
Quarterly
4.4 MB
1986
TTM
4.6 MB
1985
Annual
3.2 MB
1985
Quarterly
4.1 MB
1985
TTM
4.0 MB
1984
Annual
2.9 MB
1984
Quarterly
2.9 MB
1984
TTM
1.3 MB
1983
Annual
2.7 MB
1983
Quarterly
83 KB
1983
TTM
3 KB
1982
Annual
2.5 MB
1982
Quarterly
3 KB
1981
Annual
2.3 MB
1980
Annual
2.2 MB
1979
Annual
1.8 MB
1978
Annual
54 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.