XBRL API Options for SEC Financial Data: SEC vs SecFeed
How to pull XBRL financial statement data from the SEC's own API and from SecFeed, with real requests, real responses, and where each one falls short.
- The SEC publishes XBRL data for free through data.sec.gov, with endpoints for one company's full fact set, one concept over time, and one concept across every company for a period.
- The SEC's XBRL API returns data by tag, not by financial statement, so you still have to know which GAAP concepts make up a balance sheet or income statement.
- SecFeed's /v1/xbrl-to-json reassembles a filing's statements in the order the company presented them, with the cover page attached.
- Both sources are free; a paid API like SecFeed buys you statement structure and indexing, not data the SEC withholds.
An "XBRL API" usually means one of two things: the SEC's own free API at data.sec.gov, which returns tagged facts, or a service like SecFeed that reassembles those facts back into the statements a company actually filed. Which one you want depends on whether you need a specific number or a readable financial statement.
This guide covers both: what the SEC's XBRL endpoints return, what they leave for you to build, and how to get the same data back as structured statements in one call.
What XBRL is, briefly
Every 10-K, 10-Q, 20-F, 40-F, 6-K and 8-K with financial statements carries inline XBRL (iXBRL): every number and label in the statements is tagged with a standard concept from the US GAAP taxonomy (or IFRS for foreign private issuers), plus the SEC's own dei tags for cover page facts like fiscal year end and entity name. That tagging is what makes the data machine readable instead of just HTML text.
The SEC's own XBRL API
The SEC exposes this tagged data through three JSON endpoints at data.sec.gov, documented on its developer resources page:
| Endpoint | What it returns |
|---|---|
/api/xbrl/companyfacts/CIK##########.json | Every XBRL concept a company has ever reported, across all its filings |
/api/xbrl/companyconcept/CIK##########/us-gaap/{concept}.json | One concept's full history for one company, for example Revenues |
/api/xbrl/frames/us-gaap/{concept}/{unit}/{period}.json | One concept across every company that reported it for a given period, for example all companies' Assets for CY2024Q4I |
The frames period uses CY#### for a full year, CY####Q# for a quarter, and a trailing I (for example CY2024Q4I) for an instant-in-time concept like a balance sheet total rather than a flow like revenue. Units follow XBRL convention: USD for dollar amounts, shares for share counts, and a hyphenated form like USD-per-shares for per-share ratios.
User-Agent header with a company name and contact. SecFeed's own ingestion respects the same limit.What the SEC's API does not do for you
The SEC's companyfacts and companyconcept responses are organized by tag, not by statement. A balance sheet is not one API response, it is dozens of individual concepts (AssetsCurrent, Liabilities, StockholdersEquity, and so on) that you have to know to ask for and reassemble in the right order. Two companies can also use slightly different tags for conceptually similar lines, so cross-company comparison means mapping tags yourself. For a single filing's statements in the order the company filed them, you need a separate step.
Get this data as clean JSON
SecFeed turns SEC filings into structured data with one API call: GET /v1/xbrl-to-json. 125 free calls to start.
Getting whole statements instead of tags
SecFeed's XBRL-to-JSON converter takes a filing's accession number and returns every statement, in the company's own presentation order, with the cover page facts attached, instead of a flat bag of tags.
curl "https://secfeedapi.com/v1/xbrl-to-json?accessionNo=0000320193-26-000020&cik=320193" \
-H "Authorization: Bearer YOUR_API_KEY"
This is the real shape of that response for an Apple 10-Q (trimmed to the cover page and the start of the balance sheet):
{
"CoverPage": {
"DocumentType": [{ "value": "10-Q", "period": { "startDate": "2025-09-28", "endDate": "2026-06-27" } }],
"EntityRegistrantName": [{ "value": "Apple Inc.", "period": { "startDate": "2025-09-28", "endDate": "2026-06-27" } }],
"DocumentPeriodEndDate": [{ "value": "2026-06-27", "period": { "startDate": "2025-09-28", "endDate": "2026-06-27" } }]
},
"BalanceSheets": {
"CashAndCashEquivalentsAtCarryingValue": [
{ "value": "29943000000", "period": { "endDate": "2026-06-27" } }
]
}
}
Every statement (CoverPage, BalanceSheets, StatementsOfIncome, StatementsOfCashFlows, and whatever else the filing includes) comes back as its own key, with each line item keyed by its XBRL tag and an array of values across the periods the filing reports.
In Python, with the SecFeed SDK:
from secfeed import Client
sf = Client("YOUR_API_KEY")
xbrl = sf.xbrl_to_json(accession_no="0000320193-26-000020", cik="320193")
balance_sheet = xbrl["BalanceSheets"]
for tag, facts in balance_sheet.items():
print(tag, facts[-1]["value"])
If you want one concept across many companies instead of one filing's full statements, SecFeed's frames endpoint mirrors the SEC's own frames call (/v1/xbrl/frames?concept=Assets&period=CY2025Q4I), and /v1/xbrl/company-concept and /v1/xbrl/company-facts mirror the other two, so switching providers does not mean relearning the concept model, only getting statement structure as an extra option.
Choosing between them
| Need | Use |
|---|---|
| One filing's statements, structured and in order | /v1/xbrl-to-json |
| A single company's full reporting history for one concept | /v1/xbrl/company-concept or the SEC's companyconcept |
| One concept across every reporting company for a period | /v1/xbrl/frames or the SEC's frames |
| Multiple years of a filing's income statement, balance sheet and cash flow totals, pre-aggregated | /v1/financial-statements |
Limits to know
XBRL tagging became mandatory for large accelerated filers earliest, with smaller companies phased in later, so coverage before roughly 2009 to 2011 is thinner the further back you go, and some very small or recently registered filers may have gaps. Two companies can legitimately use different tags for a similar concept (a custom extension tag instead of a standard one), which means a cross-company query by tag can miss a company that tagged the same fact differently. For a deeper walkthrough of parsing and common tagging quirks, see how to convert XBRL to JSON in Python and the XBRL to JSON financial statements tutorial.
Frequently asked questions
Is there a free XBRL API?
Yes. The SEC publishes XBRL data for free at data.sec.gov through the companyfacts, companyconcept and frames endpoints, with no API key required, subject to the 10 requests per second fair access limit and a declared User-Agent header. SecFeed's equivalent endpoints are also free to call on every plan.
What is the difference between XBRL and the SEC's XBRL API?
XBRL is the tagging standard built into a filing's inline document: every number and label is marked with a standard concept. The "XBRL API" is a separate HTTP interface, at data.sec.gov or through a third party like SecFeed, that extracts those tags and returns them as JSON instead of requiring you to parse the filing's HTML or XML yourself.
Does the SEC's XBRL API return whole financial statements?
Not directly. The companyfacts and companyconcept endpoints return data organized by individual XBRL tag, across a company's full filing history. Reconstructing a single filing's balance sheet, income statement and cash flow statement as they were presented means collecting the right tags for that filing and ordering them yourself, or using an endpoint like SecFeed's /v1/xbrl-to-json that does that reassembly.
How far back does XBRL data go?
Mandatory XBRL tagging phased in by filer size starting with large accelerated filers around 2009, with smaller reporting companies required to tag starting around 2011. Filings from before a company's phase-in date generally do not carry structured XBRL, so coverage is thinner the further back you query.
Get this data as clean JSON
SecFeed turns SEC filings into structured data with one API call: GET /v1/xbrl-to-json. 125 free calls to start.
For information only, not investment advice. Data from public SEC filings; verify important figures on SEC.gov. See our AI Disclosure.