DEV Community

Jared Ablon
Jared Ablon

Posted on

I parsed 4,251 SEC 8-K filings — 7.3% have buried material events nobody surfaces

The wedge

US public companies file Form 8-K to disclose material events between quarterly reports. Each 8-K has one or more item codes indicating what the event is — Item 1.05 for a material cybersecurity incident, Item 5.02 for a director or officer departure, Item 1.01 for a definitive material agreement, and so on.

There's also a catch-all: Item 8.01 ("Other Events"). The SEC's instructions explicitly say that if a more specific item applies, you should use that instead. In practice, filers chronically use Item 8.01 to disclose events that fit a more specific item — sometimes innocently, sometimes to bury the disclosure.

Most SEC data APIs trust the filer-reported item codes. We re-classify from the body text and surface the discrepancies.

I built FilingFirehose (a productized SEC EDGAR JSON API) and ran the body-text classifier over 4,251 8-K filings filed in a 21-business-day window. Findings:

  • 7.3% of Item 8.01 filings contain body language strongly suggesting a more specific item code
  • Top suspected misclassifications: Item 1.01 (material agreement, 27 cases), Item 3.01 (notice of delisting, 17), Item 1.05 (cyber, 5), Item 5.02 (officer departure, 3), Item 2.01 (acquisition, 3), Item 1.03 (bankruptcy, 3)
  • Item 7.01 (Reg FD) shows a similar pattern: 4.0% of those have body language suggesting another item should have been used

Why this matters

For three audiences specifically:

Compliance teams. The SEC's 2023 cybersecurity disclosure rule explicitly flags Item 1.05 misclassification as a violation. Recent enforcement actions cite this exact pattern (a company filing a cyber breach under 8.01 when 1.05 was required). If you're monitoring competitor or watchlist filings, knowing which 8.01 filings actually contain cyber language gives you a real-time risk signal.

Quant analysts running event-driven strategies. Classification noise on filer-reported items is a known problem. The body-text classification is itself a free signal — companies that bury events under 8.01 may be doing so to delay market reaction, which means the price-impact lag is longer than naive item-code monitoring would suggest. Strategies that key off the discrepancy between filer-reported items and body-detected items have an alpha source most consumers miss entirely.

Fintech journalists. Item 8.01 filings are where the buried news lives. Manually reading every 8-K's body for cyber, officer, or material-agreement language is a Sunday-afternoon job. We do it automatically.

The pipeline

The whole thing is ~2k LOC of Python. Stack:

  • EDGAR poller: standard SEC getcurrent atom feed at 2-second cadence
  • Filing fetch: per-filing HTML body via requests (cached aggressively — EDGAR rate-limits at 10 req/s)
  • Body extraction: BeautifulSoup with custom rules for the SEC's idiosyncratic HTML
  • Classification: deterministic regex + keyword + co-occurrence rules. No transformer. Domain phrases are specific enough that rule-based beats LLM accuracy on this task, with no per-filing inference cost.
  • Storage: Polars LazyFrames over a partitioned Parquet store (form_type / date). The classifier output stored as a JSON column alongside the parsed metadata.
  • Re-runs nightly: full body-text re-parse with current rules; results overwrite the JSON column.

Sample classifier rule for Item 1.05 (cyber):

def detect_item_105(body: str) -> bool:
    """Detect material cybersecurity incident language."""
    body_lower = body.lower()
    has_breach_lang = any(p in body_lower for p in [
        "material cybersecurity incident",
        "unauthorized access",
        "data exfiltration",
        "ransomware",
        "cyber attack",
        "cybersecurity event",
    ])
    has_temporal = any(p in body_lower for p in [
        "on [date]",
        "we became aware",
        "discovered on",
        "identified on",
    ])
    has_materiality = any(p in body_lower for p in [
        "material",
        "significant impact",
        "operations were affected",
    ])
    return has_breach_lang and (has_temporal or has_materiality)
Enter fullscreen mode Exit fullscreen mode

(Real implementation has more rules + scoring. False positive rate on a 50-filing manual audit: ~12%. False negative rate on 100 unflagged filings: 1%.)

The output

Every 8-K record in our API includes:

{
  "accession_number": "0001234567-26-001234",
  "company_name": "Example Corp",
  "filed_at": "2026-05-10T16:00:00-04:00",
  "filer_reported_items": ["8.01"],
  "detected_items": ["8.01", "1.05"],
  "discrepancy_items": ["1.05"],
  "suspected_buried_events": ["reported as Item 8.01 but body suggests Item 1.05"]
}
Enter fullscreen mode Exit fullscreen mode

The discrepancy_items field is the difference between detected and reported. The suspected_buried_events field is a human-readable string explaining the flag.

How to query it

The free public tier covers the past 72 hours, no API key required:

# All 8-Ks with suspected buried events from the last 72h
curl "https://filingfirehose.com/v1/public/8k?suspected_buried_only=true"

# Filter by item code
curl "https://filingfirehose.com/v1/public/8k?items=1.05"

# Recent activist 13D filings (separate endpoint)
curl "https://filingfirehose.com/v1/public/13d?activist=Saba"

# Recent ATM offerings on S-3/424B5
curl "https://filingfirehose.com/v1/public/atm?min_shelf_million_usd=100"
Enter fullscreen mode Exit fullscreen mode

For the full archive (10+ years) + webhook delivery + 10× rate limit, there's a free 14-day Pro trial, no card required.

Live data

What I'd love feedback on

  1. Other body-text patterns worth testing. Going-concern language buried under generic 8-K items is on my list. What else?
  2. The classifier's false-positive rate. 12% feels acceptable for a screening tool but may be too noisy for a trading signal. Curious if anyone here has experience tuning rule-based classifiers in this regime.
  3. Other forms worth body-text-parsing. S-1 amendments, proxy statements, going-concern 10-Q sections — what would compound the most?

If you're building anything in this space, happy to chat. The source on the parsing rules isn't fully open (it's the moat) but I'll share the methodology in detail with anyone serious.

— Jared

Top comments (0)