Python Beginner

Corporate Event Monitor

Build a command-line tool to monitor 8-K corporate events -- earnings, M&A deals, cybersecurity incidents, and officer changes -- in real time.

Note: The code examples in this tutorial have not yet been verified against the live API. If you encounter issues, please let us know.

What You'll Build

A command-line Python script that monitors 8-K corporate events filed with the SEC. An 8-K is a "current report" that companies must file when a significant event occurs -- things like earnings releases, acquisitions, cybersecurity breaches, or executive departures. Unlike quarterly or annual reports, 8-K filings arrive as events happen, making them the fastest official signal from public companies.

The script will:

  • Fetch recent 8-K events from the stockdata.dev API
  • Display them as a formatted table with date, ticker, company name, and event type labels
  • Support filtering by 8-K item code (e.g., --item 2.02 for earnings only)
  • Support filtering by ticker to watch a single company
  • Support a --days flag to control the time range

The 8-K is the most time-sensitive SEC filing. Companies are required to file within 4 business days of the triggering event. This makes 8-K filings one of the fastest ways to learn about major corporate developments through official channels.

Prerequisites

  • Python 3.7 or newer
  • The requests library (pip install requests)
  • A stockdata.dev API key (get one free)

The Code

Create a file called event_monitor.py and paste the following:

Python
import argparse
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.stockdata.dev/v1"

# Human-readable labels for common 8-K item codes
ITEM_LABELS = {
    "1.01": "M&A / Material Agreement",
    "1.05": "Cybersecurity Incident",
    "2.01": "Acquisition/Disposition",
    "2.02": "Earnings",
    "5.02": "Officer Change",
    "7.01": "Reg FD Disclosure",
    "8.01": "Other Events",
}


def fetch_events(ticker=None, item=None, days=7):
    """Fetch 8-K events from the API."""
    headers = {"X-API-Key": API_KEY}

    if ticker:
        url = f"{BASE_URL}/company/{ticker}/filings"
        params = {"form_type": "8-K", "limit": 50}
        if item:
            params["item"] = item
    else:
        url = f"{BASE_URL}/events"
        params = {"days": days, "limit": 50}
        if item:
            params["item"] = item

    resp = requests.get(url, headers=headers, params=params)
    resp.raise_for_status()
    return resp.json()["events"]


def summarize_items(event):
    """Build a short label from the event's item codes."""
    labels = []
    for entry in event.get("item_labels", []):
        code = entry["item"]
        labels.append(ITEM_LABELS.get(code, code))
    return ", ".join(labels) if labels else event.get("items", "")


def print_events(events, title):
    """Print events as a formatted table."""
    if not events:
        print("No events found.")
        return

    print(f"\n{title}")
    print("=" * 95)
    print(f"{'Date':12}{'Ticker':8}{'Company':28}{'Event Type':47}")
    print("─" * 95)

    for e in events:
        date = e["filing_date"]
        ticker = e["ticker"]
        company = e.get("company_name", "")[:27]
        event_type = summarize_items(e)[:46]
        print(f"{date:12}{ticker:8}{company:28}{event_type:47}")

    print(f"\nTotal: {len(events)} events")


def main():
    parser = argparse.ArgumentParser(description="Monitor 8-K corporate events")
    parser.add_argument("--ticker", help="Filter to a specific company")
    parser.add_argument("--item", help="Filter by 8-K item code (e.g., 2.02)")
    parser.add_argument("--days", type=int, default=7,
                        help="Look back N days (default: 7, max: 90)")
    args = parser.parse_args()

    events = fetch_events(ticker=args.ticker, item=args.item, days=args.days)

    # Build a descriptive title
    parts = ["8-K Events"]
    if args.ticker:
        parts = [f"8-K Events for {args.ticker.upper()}"]
    if args.item:
        label = ITEM_LABELS.get(args.item, args.item)
        parts.append(f"[{label}]")
    parts.append(f"(last {args.days} days)")
    title = " ".join(parts)

    print_events(events, title)


if __name__ == "__main__":
    main()

Replace "your_api_key_here" with your actual API key. For production scripts, consider using an environment variable instead of hardcoding the key.

How It Works

When a significant event happens at a public company, the SEC requires an 8-K filing. Each 8-K contains one or more "item" codes that categorize the event. Here are the most important ones:

  • Item 1.01 -- Entry into a Material Definitive Agreement. This covers M&A deals, major contracts, and other binding agreements. When you see a 1.01 filing, a company has just signed something big.
  • Item 1.05 -- Material Cybersecurity Incidents. Added in 2023, this requires companies to disclose significant cybersecurity breaches within 4 business days. A rare but high-impact signal.
  • Item 2.01 -- Completion of Acquisition or Disposition of Assets. The deal is done. While 1.01 announces the agreement, 2.01 confirms the acquisition or asset sale has closed.
  • Item 2.02 -- Results of Operations and Financial Condition. This is the earnings release. Companies file a 2.02 when they announce quarterly or annual results. By far the most common and most watched 8-K item.
  • Item 5.02 -- Departure/Appointment of Directors or Officers. Executive changes -- a CEO stepping down, a new CFO being appointed, or board members joining or leaving. Leadership transitions often move stock prices.
  • Item 7.01 -- Regulation FD Disclosure. Material information shared with select parties that must be disclosed publicly under Reg FD. Often contains forward-looking guidance or investor presentations.
  • Item 8.01 -- Other Events. A catch-all for events the company considers important enough to disclose but that don't fit neatly into other categories.

The script uses two API endpoints depending on the filters:

  • GET /v1/events -- Fetches 8-K events across all companies. Supports item, days (default 7, max 90), ticker, and limit (default 50, max 200) parameters.
  • GET /v1/company/{ticker}/filings?item=2.02 -- Fetches filings for a specific company, filtered by 8-K item code. Used when the --ticker flag is provided.

The response from /v1/events looks like this:

JSON
{
  "events": [
    {
      "ticker": "AAPL",
      "company_name": "Apple Inc.",
      "form_type": "8-K",
      "filing_date": "2026-02-01",
      "items": "2.02,9.01",
      "item_labels": [
        {"item": "2.02", "label": "Results of Operations and Financial Condition"},
        {"item": "9.01", "label": "Financial Statements and Exhibits"}
      ],
      "accession_number": "0000320193-26-000001",
      "edgar_url": "https://www.sec.gov/Archives/edgar/data/..."
    }
  ],
  "count": 1
}

Each event may contain multiple item codes (for example, an earnings release often includes both 2.02 and 9.01). The summarize_items function maps these codes to short, readable labels so the table output is easy to scan.

Running It

Scan for all recent 8-K events across the market:

Shell
python event_monitor.py

Example output:

Output
8-K Events (last 7 days)
===============================================================================================
Date        Ticker  Company                     Event Type
───────────────────────────────────────────────────────────────────────────────────────────────
2026-02-18  AAPL    Apple Inc.                  Earnings, 8.01
2026-02-17  MSFT    Microsoft Corporation       Officer Change
2026-02-17  NVDA    NVIDIA Corporation          M&A / Material Agreement
2026-02-16  GOOGL   Alphabet Inc.               Reg FD Disclosure
2026-02-15  JPM     JPMorgan Chase & Co.        Earnings
2026-02-14  CRM     Salesforce Inc.             Acquisition/Disposition
2026-02-13  AMZN    Amazon.com Inc.             Cybersecurity Incident

Total: 7 events

Filter to earnings releases only:

Shell
python event_monitor.py --item 2.02

Example output:

Output
8-K Events [Earnings] (last 7 days)
===============================================================================================
Date        Ticker  Company                     Event Type
───────────────────────────────────────────────────────────────────────────────────────────────
2026-02-18  AAPL    Apple Inc.                  Earnings, 8.01
2026-02-15  JPM     JPMorgan Chase & Co.        Earnings
2026-02-14  WMT     Walmart Inc.                Earnings
2026-02-13  DIS     The Walt Disney Company     Earnings

Total: 4 events

Watch a specific company over a longer time range:

Shell
python event_monitor.py --ticker TSLA --days 30

Example output:

Output
8-K Events for TSLA (last 30 days)
===============================================================================================
Date        Ticker  Company                     Event Type
───────────────────────────────────────────────────────────────────────────────────────────────
2026-02-10  TSLA    Tesla Inc.                  Earnings
2026-01-28  TSLA    Tesla Inc.                  Officer Change
2026-01-22  TSLA    Tesla Inc.                  Reg FD Disclosure, 8.01

Total: 3 events

Monitor cybersecurity incidents over the last 90 days:

Shell
python event_monitor.py --item 1.05 --days 90

Use Cases

Earnings tracking

Use --item 2.02 to track which companies have just reported earnings. During earnings season, this gives you a real-time feed of who has reported and when. Combine with the Financial Statement Analyzer to immediately pull the reported numbers.

M&A monitoring

Filter on --item 1.01 (material agreements) and --item 2.01 (completed acquisitions) to track deal activity. Run this daily to catch new M&A announcements as they happen.

Cybersecurity alerts

Item 1.05 filings are rare but high-impact. A company disclosing a material cybersecurity incident can move the stock significantly. Run --item 1.05 --days 90 periodically to stay on top of breaches.

Officer departures and appointments

Filter on --item 5.02 to track executive changes. A sudden CEO departure or a new CFO appointment can signal a strategic shift. Combine with the Insider Trade Scanner to see if there's unusual insider trading around the leadership change.

Enhancements

Here are some ways to extend the event monitor:

  • Email alerts -- Run the script on a schedule with a cron job and send an email when new events match your filters. See the SEC Filing Alert Email tutorial for a notification pattern you can adapt.
  • Combine with insider trades -- Cross-reference 8-K events with insider trades from the same company and time period. Insider selling right before a cybersecurity disclosure (1.05) or executive departure (5.02) can indicate suspicious timing worth investigating.
  • Slack notifications -- Send a formatted Slack message via webhook when high-priority events appear. Item 1.05 (cybersecurity) and 5.02 (officer changes) are good candidates for immediate alerts.
  • Save to CSV -- Add a --csv output.csv flag to export events for further analysis. Use Python's built-in csv module to write the date, ticker, company, and event type columns.
  • Watchlist mode -- Maintain a list of tickers you care about and run the monitor against all of them. Loop over each ticker and aggregate the results into a single table.

8-K filings are just one piece of the puzzle. Combine event monitoring with insider trade scanning and institutional holdings analysis to build a comprehensive view of what's happening at a company.

Ready to build?

Get your free API key and start coding in minutes.

Get Free API Key