Skip to main content
All connectors

SEC EDGAR

sec.gov/edgar

  • MCP servers: use SEC EDGAR tools from ChatGPT, Claude and other MCP clients.
  • Tasks: call SEC EDGAR from Python in an automation.

About SEC EDGAR

EDGAR is the US Securities and Exchange Commission's filing system. Every US public company files its annual reports (10-K), quarterly reports (10-Q), current reports (8-K), proxy statements and insider trading forms there, along with XBRL financial data for each period. The qbash connector reads EDGAR's public APIs, which need no account. SEC asks every automated client to give a name and contact email, so the credential holds those two fields and qbash sends them with each request. The connector looks up companies by name, ticker or CIK. It lists and reads their filings as text, pulls one reported figure such as revenue across periods or across every company, and searches the full text of filings since 2001. Every call is a read. SEC allows 10 requests per second. A Python task can use it to post a company's new 8-Ks to Slack each morning, have a model summarize the risk factors in the latest 10-K, chart a competitor's quarterly revenue, or rank an industry by a figure such as total assets.

Build a SEC EDGAR MCP server with qbash

Connect SEC EDGAR to qbash, pick tools such as search companies, get company and list filings, and publish them on a hosted MCP server.

MCP clients such as ChatGPT, Claude, Claude Code, Codex, Cursor, Grok and Muse Code all connect to the same remote endpoint.

Build Tasks with SEC EDGAR

A qbash Task is a Python script that calls SEC EDGAR alongside model calls and other connectors. qbash deploys each Task to a managed runtime with version history, run logs and credentials shared across your organization.

Run it on a schedule, call it through an API or webhook, or start it from an MCP client.

SEC EDGAR Task SDK methods (9)

Call these from Python with qbash.integrations.sec_edgar.

qbash.integrations.sec_edgar.search_companies(...)

Find US public companies in SEC EDGAR by name, ticker or CIK, to get the CIK and ticker the other SEC EDGAR modes take.

search_companies(query: str | None = None, limit: int = 50, offset: int = 0)

Parameters

  • query: str | None = None

    A company name, ticker or CIK, such as "apple", "MSFT" or "320193". Omit to list every company.

  • limit: int = 50

    Most results to return, from 1 through 1000.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "count": int, "offset": int, "next_offset": int | None, "companies": list[dict]}

Notes

Searches SEC's file of companies with a listed ticker (www.sec.gov/files/company_tickers_exchange.json), about 10,000 rows, cached for six hours. An exact ticker match comes first, then names that start with the query, then names that contain it, each group in SEC's order, which puts the largest companies first. A ticker written with a dot, such as BRK.B, matches SEC's dash form BRK-B. Without a query, every row comes back in SEC's order. A company with several share classes has a row per ticker. Each company has cik, name, ticker and exchange. Funds, private companies and individuals have no ticker and are not in this file, so search_filings finds them by name. count is the number of matches. Pass next_offset back as offset until it is None.

qbash.integrations.sec_edgar.get_company(...)

Get a company's SEC EDGAR profile: name, tickers, exchanges, industry (SIC code), filer category, fiscal year end, state of incorporation, addresses and former names.

get_company(company: str | int)

Parameters

  • company: str | intrequired

    A ticker, such as AAPL or BRK.B, or a CIK, SEC's company number, such as 320193. search_companies finds either.

Returns

{"status": "success", "company": dict}

Notes

GET data.sec.gov/submissions/CIK##########.json, without its filing arrays, which list_filings reads. company has cik, name, tickers, exchanges, entity_type (operating for most companies), sic and sic_description (the industry code), category (such as Large accelerated filer), fiscal_year_end (MMDD, such as 0926), state_of_incorporation, ein, phone, business_address, mailing_address and former_names (each with name, from and to dates). Keys SEC leaves blank are left out.

qbash.integrations.sec_edgar.list_filings(...)

List a company's SEC filings, newest first, such as its 10-K annual reports, 10-Q quarterly reports, 8-K current reports, proxy statements or insider Form 4s, with a link to each document.

list_filings(company: str | int, form_types: list[str] | None = None, start_date: str | None = None, end_date: str | None = None, limit: int = 50, offset: int = 0)

Parameters

  • company: str | intrequired

    A ticker, such as AAPL or BRK.B, or a CIK, SEC's company number, such as 320193. search_companies finds either.

  • form_types: list[str] | None = None

    Form types to keep, such as ["10-K", "10-Q"] or ["8-K"]. An amendment is its own type, such as 10-K/A. A comma-separated string works too.

  • start_date: str | None = None

    First filing date, YYYY-MM-DD.

  • end_date: str | None = None

    Last filing date, YYYY-MM-DD.

  • limit: int = 50

    Most results to return, from 1 through 1000.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "cik": int, "name": str, "offset": int, "next_offset": int | None, "filings": list[dict]}

Notes

Reads data.sec.gov/submissions/CIK##########.json, which holds the latest year or 1,000 filings, and SEC's older pages when a filter or offset reaches past them, skipping pages outside the date range. Each filing has accession_number (the filing's ID), form, filing_date, report_date (the period it covers, or None), accepted_at, items (the item numbers of an 8-K, such as ["2.02", "9.01"], or None), description, primary_document, size in bytes, xbrl (whether it carries XBRL financial data), url (the primary document, which read_filing_document reads) and index_url (SEC's page for the filing). Pass accession_number to get_filing for every document in a filing (exhibits, XBRL), or url to read_filing_document for the text. The total is not known in advance. Pass next_offset back as offset until it is None.

qbash.integrations.sec_edgar.get_filing(...)

List every document in one SEC filing, such as the main 10-K, its exhibits and the XBRL financial statement pages, with a link to each.

get_filing(company: str | int, accession_number: str)

Parameters

  • company: str | intrequired

    A ticker, such as AAPL or BRK.B, or a CIK, SEC's company number, such as 320193. search_companies finds either.

  • accession_number: strrequired

    The filing's accession number from list_filings or search_filings, such as 0000320193-25-000079.

Returns

{"status": "success", "cik": int, "accession_number": str, "index_url": str, "documents": list[dict]}

Notes

GET the filing's folder listing (www.sec.gov/Archives/edgar/data/{cik}/{accession}/index.json). Each document has name, size in bytes (None for SEC's generated index pages), last_modified and url, which read_filing_document reads. In a filing with XBRL, R2.htm, R4.htm and the other R pages are the financial statements as SEC renders them, and the .txt named after the accession number is the full submission with every document.

qbash.integrations.sec_edgar.read_filing_document(...)

Read the text of an SEC filing document, such as a 10-K, 10-Q, 8-K or exhibit, from its www.sec.gov/Archives URL. Long documents come back in windows of 40,000 characters, so pass next_offset as offset to read on.

read_filing_document(url: str, offset: int = 0, max_chars: int = 40000)

Parameters

  • url: strrequired

    The document URL, such as https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/aapl-20250927.htm.

  • offset: int = 0

    The character to start from. Pass next_offset from the previous window.

  • max_chars: int = 40000

    Most characters to return, from 1 through 500000.

Returns

{"status": "success", "url": str, "content_type": str, "total_chars": int, "offset": int, "next_offset": int | None, "text": str}

Notes

Takes a url from list_filings, get_filing or search_filings, on www.sec.gov/Archives/edgar/data/. HTML comes back as plain text: block elements start a new line, table cells are joined by spaces, and the hidden inline XBRL data is dropped. Text, XML and JSON documents come back as they are, and images, PDFs and other binary files are refused. A 10-K runs to 300,000 characters or more, so read it a window at a time, or find the section with search_filings first. Each call downloads the whole document again.

qbash.integrations.sec_edgar.get_company_concept(...)

Get the history of one financial figure a company reported to the SEC in XBRL, such as revenue, net income, total assets or earnings per share, one value per period, newest first.

get_company_concept(company: str | int, tag: str, taxonomy: str = "us-gaap", unit: str | None = None, form_types: list[str] | None = None, all_filings: bool = False, limit: int = 100, offset: int = 0)

Parameters

  • company: str | intrequired

    A ticker, such as AAPL or BRK.B, or a CIK, SEC's company number, such as 320193. search_companies finds either.

  • tag: strrequired

    An XBRL concept name, case-sensitive, such as Revenues, NetIncomeLoss, Assets or EarningsPerShareBasic. list_company_concepts lists a company's concepts.

  • taxonomy: str = "us-gaap"

    The XBRL taxonomy: us-gaap (US companies), ifrs-full (foreign filers using IFRS), dei (cover page data such as shares outstanding) or srt.

  • unit: str | None = None

    The unit to return, such as USD, USD/shares or shares. Defaults to USD, or the unit with the most facts.

  • form_types: list[str] | None = None

    Form types to keep, such as ["10-K", "10-Q"] or ["8-K"]. An amendment is its own type, such as 10-K/A. A comma-separated string works too.

  • all_filings: bool = False

    Keep every report of a period, not only the latest filed.

  • limit: int = 100

    Most results to return, from 1 through 1000.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "cik": int, "entity_name": str, "taxonomy": str, "tag": str, "label": str, "description": str, "unit": str, "available_units": list[str], "count": int, "offset": int, "next_offset": int | None, "facts": list[dict]}

Notes

GET data.sec.gov/api/xbrl/companyconcept/CIK##########/{taxonomy}/{tag}.json. Each fact has start (None for a balance sheet value at one date), end, val, fy and fp (the fiscal year and period of the filing that reported it, such as 2025 and Q3), form, filed, frame (SEC's calendar period, such as CY2025Q2, when SEC matched one) and accession_number. A filing repeats earlier periods for comparison, so by default each period keeps only its latest filed value, which includes restatements. all_filings keeps every report. A 10-Q reports both the quarter and the year to date, which share an end date and differ in start. Companies use different tags for the same idea (Revenues, RevenueFromContractWithCustomerExcludingAssessedTax, SalesRevenueNet), so list_company_concepts shows which ones a company uses. unit defaults to USD when the concept has it. Pass next_offset back as offset until it is None.

qbash.integrations.sec_edgar.list_company_concepts(...)

List the XBRL financial concepts a company reports to the SEC, such as Revenues or NetIncomeLoss, with their units and latest period, to find the tag get_company_concept takes.

list_company_concepts(company: str | int, search: str | None = None, taxonomy: str | None = None, limit: int = 100, offset: int = 0)

Parameters

  • company: str | intrequired

    A ticker, such as AAPL or BRK.B, or a CIK, SEC's company number, such as 320193. search_companies finds either.

  • search: str | None = None

    Words to find in the tag or label, such as "revenue" or "per share".

  • taxonomy: str | None = None

    Only this taxonomy, such as us-gaap or dei.

  • limit: int = 100

    Most results to return, from 1 through 1000.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "cik": int, "entity_name": str, "count": int, "offset": int, "next_offset": int | None, "concepts": list[dict]}

Notes

Reads data.sec.gov/api/xbrl/companyfacts/CIK##########.json, which can run to several megabytes, and returns a line per concept without the values. Each concept has taxonomy, tag, label, units, fact_count and latest_end, the end date of its latest value. Concepts reported most recently come first, so ones a company stopped using sort last. count is the number of matches. Pass next_offset back as offset until it is None.

qbash.integrations.sec_edgar.get_frame(...)

Compare one XBRL financial figure, such as revenue or total assets, across every company that reported it for one calendar period, largest first.

get_frame(tag: str, period: str, taxonomy: str = "us-gaap", unit: str = "USD", sort_order: str = "desc", limit: int = 100, offset: int = 0)

Parameters

  • tag: strrequired

    An XBRL concept name, case-sensitive, such as Revenues, NetIncomeLoss, Assets or EarningsPerShareBasic. list_company_concepts lists a company's concepts.

  • period: strrequired

    CY2024 (a year), CY2024Q4 (a quarter) or CY2024Q4I (the end of a quarter, for balance sheet items).

  • taxonomy: str = "us-gaap"

    The XBRL taxonomy: us-gaap (US companies), ifrs-full (foreign filers using IFRS), dei (cover page data such as shares outstanding) or srt.

  • unit: str = "USD"

    The unit, such as USD, USD/shares or shares.

  • sort_order: str = "desc"

    desc for the largest value first, asc for the smallest.

  • limit: int = 100

    Most results to return, from 1 through 1000.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "taxonomy": str, "tag": str, "label": str, "description": str, "unit": str, "period": str, "count": int, "offset": int, "next_offset": int | None, "values": list[dict]}

Notes

GET data.sec.gov/api/xbrl/frames/{taxonomy}/{tag}/{unit}/{period}.json. SEC picks, for each company, the value that best fits the calendar period, so a fiscal year ending in September counts toward the nearest calendar year. period is CY2024 for a year, CY2024Q4 for a quarter, or CY2024Q4I for a value at the end of the quarter, which balance sheet items such as Assets need. Each value has cik, entity_name, location (such as US-CA), start, end, val and accession_number. count is the number of companies. Pass next_offset back as offset until it is None.

qbash.integrations.sec_edgar.search_filings(...)

Search the full text of SEC EDGAR filings since 2001 for words or phrases, filtered by form type, company and filing date. Without a query, lists the latest filings, such as today's 8-Ks.

search_filings(query: str | None = None, form_types: list[str] | None = None, company: str | int | None = None, start_date: str | None = None, end_date: str | None = None, limit: int = 100, offset: int = 0)

Parameters

  • query: str | None = None

    Words to find, with a phrase in double quotes, such as "\"going concern\"". Omit to list filings by the other filters.

  • form_types: list[str] | None = None

    Form types to keep, such as ["10-K"] or ["8-K"]. Each also matches its amendments (10-K/A). A comma-separated string works too.

  • company: str | int | None = None

    Only this company's filings, as a ticker or CIK.

  • start_date: str | None = None

    First filing date, YYYY-MM-DD. Defaults to 2001-01-01 when end_date is set.

  • end_date: str | None = None

    Last filing date, YYYY-MM-DD. Defaults to today when start_date is set.

  • limit: int = 100

    Most results to return, from 1 through 100.

  • offset: int = 0

    How many results to skip. Pass next_offset from the previous page.

Returns

{"status": "success", "total": int, "total_is_lower_bound": bool, "offset": int, "next_offset": int | None, "results": list[dict]}

Notes

GET efts.sec.gov/LATEST/search-index, the API behind EDGAR full-text search. Put a phrase in double quotes, such as "\"supply chain\"". A match is one document, so a filing can match more than once, through its main document and an exhibit. Each result has accession_number, form, file_date, period_ending, companies (SEC's display names with ticker and CIK), ciks, document, document_type (such as 10-K or EX-99.1), document_description, items (8-K item numbers) and url, which read_filing_document reads. With a query, matches are ranked by relevance. With no query, the latest filed come first. form_types matches amendments too, so 10-K also finds 10-K/A, and each result's form tells them apart. SEC returns 100 results a page and counts up to 10,000, after which total_is_lower_bound is True. Pass next_offset back as offset until it is None.

Task SDK reference

Connect SEC EDGAR to qbash

Sign up, connect your SEC EDGAR account, and use its tools across qbash.

Sign up free