The SEC Filings API delivers parsed filings for US-listed companies straight from SEC EDGAR: annual reports (10-K), quarterly reports (10-Q), and material-event reports (8-K). Financial statements are extracted from XBRL into a flat, ready-to-use field set, and material events are broken down into item sections and exhibits. Filings are refreshed daily and history reaches back to 1994.
You can try these endpoints without an account using the demo API token (api_token=demo). For SEC filings the demo token is limited to three tickers: AAPL.US, TSLA.US, and AMZN.US.
API Endpoints
| Method | Endpoint | Returns |
|---|---|---|
| GET | /api/sec-filings/{symbol} | Filing overview: counts and latest date per form type |
| GET | /api/sec-filings/{symbol}/10k | Annual reports (10-K) with parsed financials |
| GET | /api/sec-filings/{symbol}/10q | Quarterly reports (10-Q) with parsed financials |
| GET | /api/sec-filings/{symbol}/8k | Material-event reports (8-K) with item sections and exhibits |
Coverage
Filings are sourced from SEC EDGAR for US-listed companies and refreshed daily, with history reaching back to 1994. Every completed filing maps to exactly one data row.
| Report | Filings | Companies | History |
|---|---|---|---|
| 10-K annual | 49,000+ | 4,400+ | 1994 to present |
| 10-Q quarterly | 147,000+ | 4,400+ | 1994 to present |
| 8-K material events | 526,000+ | 4,500+ | 1994 to present |
Depth per company varies: large, long-listed issuers have decades of filings, while recently listed companies have shorter histories.
Path Parameter
symbol
string
required
Query Parameters
api_token
string
required
page[offset]
integer
optional
page[limit]
integer
optional
Response Envelope
Every response is a JSON object with three top-level members: data (the payload), meta (result metadata, including pagination totals on the list endpoints), and links (the next-page URL, or null on the last page). The overview endpoint is not paginated and returns empty meta and links.
{
"data": [ ... ],
"meta": { "total": 34, "page": { "offset": 0, "limit": 20 } },
"links": { "next": "https://eodhd.com/api/sec-filings/AAPL.US/10q?page[offset]=20&page[limit]=20" }
}
Filing Overview
GET /api/sec-filings/{symbol} returns a per-company summary: identification fields plus a count and latest filing date for each available form type.
Request Example
https://eodhd.com/api/sec-filings/AAPL.US?api_token=YOUR_API_TOKEN
curl --location "https://eodhd.com/api/sec-filings/AAPL.US?api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/sec-filings/AAPL.US?api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/sec-filings/AAPL.US?api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/sec-filings/AAPL.US?api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Example
{
"data": {
"ticker": "AAPL",
"exchange": "US",
"name": "Apple Inc.",
"cik": "0000320193",
"filings": {
"10k": { "count": 11, "latest": "2025-10-31", "url": "https://eodhd.com/api/sec-filings/AAPL.US/10k" },
"10q": { "count": 34, "latest": "2026-05-01", "url": "https://eodhd.com/api/sec-filings/AAPL.US/10q" },
"8k": { "count": 107, "latest": "2026-04-30", "url": "https://eodhd.com/api/sec-filings/AAPL.US/8k" },
"form4": { "count": 597, "latest": "2026-06-17", "url": "https://eodhd.com/api/sec-filings/AAPL.US/form4" }
}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| ticker | string | Company ticker |
| exchange | string | Exchange code, US for US listings |
| name | string | Company name |
| cik | string | SEC Central Index Key, zero-padded |
| filings | object | Per-form summary keyed by form type (10k, 10q, 8k, form4), each with count, latest, and url |
Annual Reports (10-K)
GET /api/sec-filings/{symbol}/10k returns a paginated list of annual reports, newest first. Each entry carries filing metadata and financial-statement fields parsed from the filing XBRL. All monetary values are in the reporting currency (USD for US filers), stated in whole units. A field is null when the value is not reported or not tagged in the source filing.
Request Example
https://eodhd.com/api/sec-filings/AAPL.US/10k?api_token=YOUR_API_TOKEN
curl --location "https://eodhd.com/api/sec-filings/AAPL.US/10k?api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/sec-filings/AAPL.US/10k?api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/sec-filings/AAPL.US/10k?api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/sec-filings/AAPL.US/10k?api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Example
{
"data": [
{
"accession_number": "0000320193-25-000079",
"filed_at": "2025-10-31",
"period_of_report": "2025-09-27",
"fiscal_year_end": "2025-09-27T00:00:00.000000Z",
"revenue": 416161000000,
"net_income": 112010000000,
"eps_diluted": 7.46,
"total_assets": 359241000000,
"operating_cash_flow": 111482000000,
"free_cash_flow": 98767000000
}
],
"meta": { "total": 11, "page": { "offset": 0, "limit": 20 } },
"links": { "next": null }
}
Response Fields
Fields are grouped for readability; expand each group to see its fields.
Filing metadata
| Field | Type | Description |
|---|---|---|
| accession_number | string | SEC accession number of the filing |
| filed_at | string | Filing date, YYYY-MM-DD |
| period_of_report | string | Reporting period end date, YYYY-MM-DD |
| fiscal_year_end | string | Fiscal year end, ISO 8601 datetime |
Income statement
| Field | Type | Description |
|---|---|---|
| revenue | integer | Total revenue |
| cost_of_revenue | integer | Cost of revenue |
| gross_profit | integer | Gross profit |
| research_and_development | integer | Research and development expense |
| selling_general_admin | integer | Selling, general and administrative expense |
| operating_expenses | integer | Total operating expenses |
| operating_income | integer | Operating income |
| interest_expense | integer or null | Interest expense |
| interest_income | integer or null | Interest income |
| income_before_tax | integer | Pre-tax income |
| income_tax_expense | integer | Income tax expense |
| net_income | integer | Net income |
| ebitda | integer | Earnings before interest, taxes, depreciation and amortization |
| depreciation_amortization | integer | Depreciation and amortization |
| eps_basic | number | Basic earnings per share |
| eps_diluted | number | Diluted earnings per share |
| weighted_avg_shares_basic | integer | Weighted average basic shares outstanding |
| weighted_avg_shares_diluted | integer | Weighted average diluted shares outstanding |
| shares_outstanding | integer | Shares outstanding |
Balance sheet
| Field | Type | Description |
|---|---|---|
| cash_and_equivalents | integer | Cash and cash equivalents |
| short_term_investments | integer | Short-term investments |
| accounts_receivable | integer | Accounts receivable |
| inventory | integer | Inventory |
| total_current_assets | integer | Total current assets |
| property_plant_equipment | integer | Property, plant and equipment, net |
| goodwill | integer or null | Goodwill |
| intangible_assets | integer or null | Intangible assets |
| total_assets | integer | Total assets |
| accounts_payable | integer | Accounts payable |
| short_term_debt | integer | Short-term debt |
| total_current_liabilities | integer | Total current liabilities |
| long_term_debt | integer | Long-term debt |
| total_liabilities | integer | Total liabilities |
| common_stock | integer | Common stock and additional paid-in capital |
| retained_earnings | integer | Retained earnings, can be negative |
| stockholders_equity | integer | Stockholders equity |
| total_equity | integer | Total equity |
Cash flow
| Field | Type | Description |
|---|---|---|
| operating_cash_flow | integer | Net cash from operating activities |
| capital_expenditure | integer | Capital expenditure |
| free_cash_flow | integer | Free cash flow |
| investing_cash_flow | integer | Net cash from investing activities |
| financing_cash_flow | integer | Net cash from financing activities |
| dividends_paid | integer | Dividends paid |
| share_repurchase | integer | Share repurchases |
Quarterly Reports (10-Q)
GET /api/sec-filings/{symbol}/10q returns a paginated list of quarterly reports, newest first. Each entry carries the same financial-statement fields as the 10-K endpoint (see the Annual Reports groups above), with two differences in the metadata block.
Request Example
https://eodhd.com/api/sec-filings/AAPL.US/10q?api_token=YOUR_API_TOKEN
curl --location "https://eodhd.com/api/sec-filings/AAPL.US/10q?api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/sec-filings/AAPL.US/10q?api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/sec-filings/AAPL.US/10q?api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/sec-filings/AAPL.US/10q?api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Fields
| Field | Type | Description |
|---|---|---|
| fiscal_quarter_end | string | Quarter end date, ISO 8601 datetime, replaces fiscal_year_end |
| fiscal_quarter | integer | Quarter number 1 to 4, see the caveat below |
fiscal_quarter is derived from the calendar quarter of period_of_report (1 = Jan-Mar, 2 = Apr-Jun, 3 = Jul-Sep, 4 = Oct-Dec). For companies whose fiscal year does not end in December, this differs from the true fiscal quarter. For example, a Microsoft 10-Q for a period ending 31 March returns fiscal_quarter 1, although it is Microsoft’s fiscal Q3. Use period_of_report together with fiscal_year_end from the 10-K when the exact fiscal quarter matters.
Material Events (8-K)
GET /api/sec-filings/{symbol}/8k returns a paginated list of 8-K material-event reports, newest first. Each 8-K lists the SEC item codes it covers, the parsed text of each item section, and any attached exhibits.
Request Example
https://eodhd.com/api/sec-filings/AAPL.US/8k?api_token=YOUR_API_TOKEN
curl --location "https://eodhd.com/api/sec-filings/AAPL.US/8k?api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/sec-filings/AAPL.US/8k?api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/sec-filings/AAPL.US/8k?api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/sec-filings/AAPL.US/8k?api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Example
{
"data": [
{
"accession_number": "0000320193-26-000011",
"filed_at": "2026-04-30",
"period_of_report": "2026-04-30",
"items": ["2.02", "9.01"],
"item_sections": [
{
"item": "2.02",
"title": "Results of Operations and Financial Condition",
"text": "On April 30, 2026, Apple Inc. issued a press release regarding Apple's financial results ..."
}
],
"exhibits": [
{ "number": "99.1", "description": "Press release" }
]
}
],
"meta": { "total": 107, "page": { "offset": 0, "limit": 20 } },
"links": { "next": "https://eodhd.com/api/sec-filings/AAPL.US/8k?page[offset]=20&page[limit]=20" }
}
Response Fields
| Field | Type | Description |
|---|---|---|
| accession_number | string | SEC accession number of the filing |
| filed_at | string | Filing date, YYYY-MM-DD |
| period_of_report | string | Event or report date, YYYY-MM-DD |
| items | array | List of SEC item codes covered, for example 2.02, 9.01 |
| item_sections | array | One object per item, each with item, title, and text |
| exhibits | array | One object per exhibit, each with number and description |
Common 8-K item codes:
| Item | Meaning |
|---|---|
| 1.01 | Entry into a material definitive agreement |
| 2.02 | Results of operations and financial condition |
| 5.02 | Departure or appointment of directors or officers |
| 7.01 | Regulation FD disclosure |
| 8.01 | Other events |
| 9.01 | Financial statements and exhibits |
Response Codes
| Code | Meaning |
|---|---|
| 200 | Success; filing data returned |
| 401 | Unauthorized; missing or invalid API token |
| 402 | Daily API request limit exceeded |
| 403 | Plan does not include SEC filings access |
| 404 | Symbol not found |
| 422 | Invalid query parameters |
| 429 | Too many requests; rate limit exceeded |
Known Limitations
- Coverage. US-listed companies that file with SEC EDGAR. Filing history reaches back to 1994; depth per company varies.
- Calendar vs fiscal quarter. The fiscal_quarter field reflects the calendar quarter of period_of_report and may differ from the company’s fiscal quarter when the fiscal year does not end in December.
- Null financial fields. Financials are parsed from XBRL, so a line item is null when it is not reported or not tagged in the source filing. This is expected for items a company does not report (for example inventory for a bank, or research and development where there is none), and is more common for older filings from before XBRL was mandated. Check for null before relying on a value.
- 8-K exhibits and section text. The exhibits array is populated for the large majority of 8-K filings. In the rare case where item 9.01 is present but exhibits is empty, the exhibit list is still available in the text of the 9.01 item section. Some item sections that only point to an attached press release (often 2.02 or 7.01) may carry a short or empty text field, with the detail in the referenced exhibit.
- Control characters in 8-K text. The text field of 8-K item sections is taken from the source filing and can contain raw newlines and tabs. Parse it with a lenient JSON reader.