SEC-API.io Python Library

repository·master·Indexed 43 days ago

https://github.com/sec-api-io/sec-api-python

A comprehensive Python library for programmatic access to SEC EDGAR filings, exhibits, and financial datasets. It provides specialized APIs for querying filings (QueryApi), full-text search (FullTextSearchApi), downloading content (DownloadApi), converting XBRL to JSON (XbrlApi), extracting specific sections from 10-K/10-Q/8-K filings (ExtractorApi), generating PDFs (PdfGeneratorApi), and searching Form ADV data (FormAdvApi). It also supports real-time filing streams via WebSockets and bulk dataset synchronization.

Tokens
17.8K
Snippets
71
Records
75
Agent score
6%

What's inside SEC-API.io

  1. Configure Proxy Support for API Wrappers

    master

    If your corporate IT infrastructure requires a proxy or causes SSL certificate errors, you can pass a proxies dictionary to all API wrappers (such as QueryApi and DownloadApi) during initialization. The dictionary should contain keys for http and https protocols.

    from sec_api import QueryApi, DownloadApi, ...
    
    proxies = {
      "http": "http://your-proxy.com",
      "https": "https://your-proxy.com",
    }
    
    queryApi = QueryApi(api_key="YOUR_API_KEY", proxies=proxies)
    downloadApi = DownloadApi(api_key="YOUR_API_KEY", proxies=proxies)
  2. Download and sync Bulk Datasets

    master

    The Datasets class allows you to download complete SEC datasets for offline analysis. Downloads are atomic (using .tmp files) and resumable. The sync method is optimized to only download new or updated files by comparing sizes, making it ideal for scheduled updates.

    Available datasets include:

    • Form 10-K - Annual Reports (1993-present, ZIP: HTML, TXT)
    • Form 10-Q - Quarterly Reports (1993-present, ZIP: HTML, TXT)
    • Form 8-K Exhibit 99 - Press Releases (1994-present, ZIP: HTML, TXT, PDF)
    • Earnings Results (Item 2.02) (2004-present, ZIP: HTML, TXT, PDF)
    • Form 4 - Changes in Ownership (2009-present, JSONL)
    • Form 13F - Institutional Holdings (2013-present, JSONL)
    • Form N-PORT - Fund Holdings (2019-present, JSONL)
    • Form DEF 14A - Proxy Statements (1994-present, ZIP: HTML, TXT)
    from sec_api import Datasets
    
    datasets = Datasets(api_key="YOUR_API_KEY")
    
    # Download all containers for a dataset to the default directory
    datasets.download("form-10k-content")
    
    # Sync only new or updated containers (efficient for daily updates)
    datasets.sync("form-10k-content")
    
    # Download to a custom directory
    datasets.download("form-10k-content", path="./my-data/form-10k-content")
    
    # Download the entire dataset as a single ZIP file
    datasets.download("form-10k-content", strategy="zip")
  3. Stream real-time SEC filings via WebSockets

    master

    The Stream API provides a live feed of newly published SEC EDGAR filings via WebSockets.

    Setup:

    1. Install the websockets client: pip install websockets.
    2. Connect to wss://stream.sec-api.io using your API key as a query parameter.

    Connection URL Format: wss://stream.sec-api.io?apiKey=YOUR_API_KEY

    import asyncio
    import websockets
    import json
    
    API_KEY = "YOUR_API_KEY"
    SERVER_URL = "wss://stream.sec-api.io"
    WS_ENDPOINT = SERVER_URL + "?apiKey=" + API_KEY
    
    async def websocket_client():
        try:
            async with websockets.connect(WS_ENDPOINT) as websocket:
                print("✅ Connected to:", SERVER_URL)
                while True:
                    message = await websocket.recv()
                    filings = json.loads(message)
                    for f in filings:
                        print(f["accessionNo"], f["formType"], f["filedAt"], f["cik"])
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
    
    asyncio.run(websocket_client())
  4. Handle 'too many requests' errors with backoff strategy

    master
    The SEC-API.io Python library implements an internal backoff strategy to handle 429 Too Many Requests errors. If an API call returns a 429 status code, the library automatically waits for a period of 0.5 * (x + 1) seconds (where x is the current retry attempt) before retrying. The library typically attempts up to 3 retries before raising an error via handle_api_error.
  5. Query Form 3 - Initial Ownership Statements

    master

    To retrieve Form 3 filings, initialize InsiderTradingApi and query for documentType:3. You can filter by issuer.tradingSymbol to find specific companies.

    from sec_api import InsiderTradingApi
    
    insiderTradingApi = InsiderTradingApi("YOUR_API_KEY")
    
    data = insiderTradingApi.get_data({
        "query": "documentType:3 AND issuer.tradingSymbol:NTB",
        "from": "0",
        "size": "50",
        "sort": [{"filedAt": {"order": "desc"}}],
    })
    print(data["transactions"])
  6. Query Form 5 - Annual Ownership Statements

    master

    To retrieve Form 5 filings, initialize InsiderTradingApi and query for documentType:5.

    from sec_api import InsiderTradingApi
    
    insiderTradingApi = InsiderTradingApi("YOUR_API_KEY")
    
    data = insiderTradingApi.get_data({
        "query": "documentType:5 AND issuer.tradingSymbol:SPWR",
        "from": "0",
        "size": "50",
        "sort": [{"filedAt": {"order": "desc"}}],
    })
    print(data["transactions"])
  7. Query Form 4 - Changes in Ownership

    master

    To retrieve Form 4 filings, initialize InsiderTradingApi and query for documentType:4. This is used to track changes in ownership by company officers, directors, and beneficial owners.

    from sec_api import InsiderTradingApi
    
    insiderTradingApi = InsiderTradingApi("YOUR_API_KEY")
    
    data = insiderTradingApi.get_data({
        "query": "documentType:4 AND issuer.tradingSymbol:TSLA",
        "from": "0",
        "size": "50",
        "sort": [{"filedAt": {"order": "desc"}}],
    })
    print(data["transactions"])
  8. Search for specific 8-K items using QueryApi

    master

    You can use the items parameter in your query string to find specific sections within 8-K filings. For example, to find filings that include Item 9.01 ('Financial Statements and Exhibits'), use items:"9.01".

    from sec_api import QueryApi
    
    queryApi = QueryApi(api_key="YOUR_API_KEY")
    
    # Find the most recently reported Form 8-K filings that include Item 9.01
    query = {
      "query": "formType:\"8-K\" AND items:\"9.01\"",
      "from": "0",
      "size": "10",
      "sort": [{ "filedAt": { "order": "desc" } }]
    }
    
    filings = queryApi.get_filings(query)
  9. Search the AAER Database

    master

    Use AaerApi to access the Accounting and Auditing Enforcement Releases (AAER) database, which contains all AAERs filed from 1997 to the present. Use the .get_data(query) method to perform searches.

    from sec_api import AaerApi
    
    aaerApi = AaerApi("YOUR_API_KEY")
    
    query = {
        "query": "dateTime:[2012-01-01 TO 2020-12-31]",
        "from": "0",
        "size": "50",
        "sort": [{"dateTime": {"order": "desc"}}],
    }
    
    response = aaerApi.get_data(query)
    print(response["data"])
  10. Search Financial Restatements (Form 8-K Item 4.02)

    master

    Use Form_8K_Item_X_Api to search for filings related to financial restatements or non-reliance on prior financial results. The data includes identified issues, affected reporting periods, affected financial statement items, and auditor involvement.

    from sec_api import Form_8K_Item_X_Api
    
    item_X_api = Form_8K_Item_X_Api("YOUR_API_KEY")
    
    item_4_02_request = {
        "query": "item4_02:* AND filedAt:[2024-01-01 TO 2024-12-31]",
        "from": "0",
        "size": "50",
        "sort": [{"filedAt": {"order": "desc"}}],
    }
    item_4_02_response = item_X_api.get_data(item_4_02_request)
    print(item_4_02_response["data"])
  11. Search Form 1-K filings

    master

    Use the Form1KApi class to query Form 1-K (annual reports) filed under Regulation A. You can search using specific identifiers like fileNo.

    from sec_api import Form1KApi
    
    form1KApi = Form1KApi("YOUR_API_KEY")
    
    search_params = {
        "query": "fileNo:24R-00472",
        "from": "0",
        "size": "50",
        "sort": [{"filedAt": {"order": "desc"}}],
    }
    
    response = form1KApi.get_data(search_params)
    form1Ks = response["data"]
    
    print(form1Ks)