Home / Guides / Exhibits
Exhibits

Download 8-K Exhibit 99 press releases with Python

Find earnings 8-Ks (Item 2.02), list their Exhibit 99 documents and download the press releases, using the 8-K events feed and the download API.

When a company announces earnings, the 8-K itself is a one page cover. The actual press release, with the headline numbers and the financial tables, is attached as Exhibit 99.1. Investor presentations, CFO commentary and supplemental tables follow as 99.2, 99.3 and so on. The same pattern applies to Item 7.01 (Regulation FD) 8-Ks, which carry investor day slides and other announcements as Exhibit 99.

This tutorial finds today's earnings 8-Ks, lists their Exhibit 99 documents and downloads the press releases.

Steps

  1. /v1/form-8k?item=2.02 returns 8-Ks classified by item, newest first, each with its index URL.
  2. The filing index page lists every document with its exhibit type (EX-99.1, EX-10.1, GRAPHIC...). /v1/download fetches it, and a regex reads the table.
  3. /v1/download fetches each exhibit as filed.

The script

import html
import os
import re
import requests

BASE = "https://secfeedapi.com"
HEADERS = {"Authorization": f"Bearer {os.environ['SECFEED_KEY']}"}

def get(path, **params):
    r = requests.get(f"{BASE}{path}", params=params, headers=HEADERS, timeout=120)
    r.raise_for_status()
    return r

def exhibits(index_url):
    """[(type, description, url)] from the filing index page's document table."""
    page = get("/v1/download", url=index_url).text
    rows = re.findall(r'<td scope="row">([^<]*)</td>\s*<td scope="row"><a href="([^"]+)">[^<]*</a>.*?</td>\s*<td scope="row">([^<]*)</td>',
                      page, flags=re.S)
    return [(typ.strip(), desc.strip(), "https://www.sec.gov" + href.replace("/ix?doc=", "")) for desc, href, typ in rows]

def to_text(doc):
    doc = re.sub(r"(?is)<(head|script|style).*?</\1>", " ", doc)
    doc = re.sub(r"(?i)<br\s*/?>|</(p|div|tr|h\d)>", "\n", doc)
    return html.unescape(re.sub(r"<[^>]+>", " ", doc)).replace("\xa0", " ")

# 1. earnings releases filed today: 8-Ks with Item 2.02
events = get("/v1/form-8k", item="2.02", startDate="2026-10-13", size=4).json()["filings"]
os.makedirs("ex99", exist_ok=True)

for e in events:
    # 2. the Exhibit 99 documents attached to each 8-K
    ex99 = [x for x in exhibits(e["url"]) if x[0].startswith("EX-99")]
    print(f"{e['company']} ({e['filed']}): {len(ex99)} exhibit 99 document(s)")
    for typ, desc, url in ex99:
        print(f"   {typ:<8} {desc[:40]:<40} {url.rsplit('/', 1)[1]}")
    # 3. download EX-99.1, the press release, and show its first lines
    typ, desc, url = ex99[0]
    doc = get("/v1/download", url=url).text
    open(os.path.join("ex99", url.rsplit("/", 1)[1]), "w").write(doc)
    text = to_text(doc)
    lines = [" ".join(l.split()) for l in text.splitlines() if len(l.split()) >= 5]
    headline = next((l for l in lines if re.search(r"quarter|results", l, re.I)), lines[0])
    print(f"   {len(text.split()):,} words. First line about results: {headline[:120]}")
    print()

Output

EMERSON ELECTRIC CO (2026-10-13): 1 exhibit 99 document(s)
   EX-99.1  EX-99.1                                  apensionrestatementxex991.htm
   1,561 words. First line about results: Quarterly amounts may not sum to the annual amounts due to rounding. Earnings per share are computed independently each 

WELLS FARGO & COMPANY/MN (2026-10-13): 3 exhibit 99 document(s)
   EX-99.1  EXHIBIT 99.1                             wfc3qer10-13x26ex991xrelea.htm
   EX-99.2  EXHIBIT 99.2                             wfc3qer10-13x26ex992xsuppl.htm
   EX-99.3  EXHIBIT 99.3                             ex993-wellsfargo3q26pres.htm
   4,529 words. First line about results: Wells Fargo Reports Third Quarter 2026 Net Income of $6.0 billion, or $1.87 per Diluted Share

JOHNSON & JOHNSON (2026-10-13): 2 exhibit 99 document(s)
   EX-99.1  EX-99.1                                  a2026q3exhibit991.htm
   EX-99.2  EX-99.2                                  a2026q3exhibit992.htm
   2,364 words. First line about results: Johnson & Johnson reports Q3 2026 results, raises 2026 guidance

UNITEDHEALTH GROUP INC (2026-10-13): 2 exhibit 99 document(s)
   EX-99.1  EX-99.1                                  earningsrelease3q26unh.htm
   EX-99.2  EX-99.2                                  uhgearnings_q32026vfinal.htm
   5,250 words. First line about results: 1 UnitedHealth Group Reports Third Quarter 2026 Results • Third Quarter 2026 Revenues of $112.7 Billion; Earnings from O

Three of the four Exhibit 99.1 documents are classic quarterly earnings releases. The fourth shows why it pays to read the exhibit and not just the item code: Emerson's Item 2.02 8-K carries recast historical results after a pension accounting change, not a quarterly release.

Variations

  • Regulation FD announcements. Use item="7.01" for investor presentations and other voluntary disclosures. Many earnings 8-Ks have both 2.02 and 7.01.
  • One company over time. Search with formType:"8-K" AND items:"2.02" AND ticker:NVDA on /v1/filings to get every earnings 8-K for a ticker.
  • Text for NLP. The to_text helper is enough for headlines. For full documents, the extractor can also return 8-K item text, see Extract 8-K item text.
  • PDF copies. Pass the exhibit URL to /v1/pdf to archive a rendered copy.

Notes

  • Exhibit numbering follows Item 601 of Regulation S-K: 99 is "additional exhibits", used for press releases and presentations. Material contracts are Exhibit 10, see Download material contracts.
  • Results furnished under Item 2.02 are "furnished", not "filed", which matters for liability but not for the data.

Next steps

More exhibits guides

Run this guide with your own key

500 free API calls a month. Every example on this page works on the free plan.

Get free API key →