How to Monitor SEC Cybersecurity Disclosures via API
You set up monitoring for cybersecurity disclosures in the 10-K and think you are covered — until you realize you are missing every incident filing and every foreign issuer.
In this article, you will learn:
- Where SEC cybersecurity disclosure actually lives — 3 forms, 3 item keys, 3 naming conventions
- How to extract Item 1C governance disclosures from annual reports
- How to catch Item 1.05 material incident filings as they land, on a 4-business-day clock
- Why foreign issuers use Item 16K and what happens when your monitor misses them
- What to actually measure in governance and incident disclosures
- And lastly, how to build a unified SEC cybersecurity disclosure monitor — with a free API
You build a pipeline to monitor cybersecurity disclosures in 10-K filings and it runs cleanly for months. Then a material breach hits an 8-K on a Friday evening, a foreign issuer discloses a governance overhaul in a 20-F, and your monitor catches neither — because it was only looking in one of the 3 places where the data actually lives.
Cyber disclosure under the SEC’s 2023 rules spans 3 forms with 3 different item keys, and each uses a different naming convention. This article builds one pipeline that covers all of them.
The 3 places cyber disclosure lives
And the single most common mistake I see is monitoring only one of them. You end up with governance and no incidents, or incidents and no context to judge them against.
| Form | Item key | What it contains | Cadence |
|---|---|---|---|
| 10-K | item1c | Cybersecurity risk management, strategy and governance. Board oversight, management’s role, processes, third-party risk. | Annual |
| 8-K | Item1_05 | Material cybersecurity incident. The breach itself, filed within 4 business days of a materiality determination. | Event-driven |
| 20-F | Item16K | Cybersecurity — the foreign private issuer equivalent of Item 1C. | Annual |
3 different forms. 3 different item keys. 3 different naming conventions, which is exactly why home-grown pipelines cover one and silently miss the others:
item1c— lowercase, 10-K conventionItem1_05— capital I, underscore separator, 8-K conventionItem16K— capital I, no separator, 20-F convention
Normalize the case and you match nothing. Pass back verbatim what the API returns and you match everything.
Note also that item1a (Risk Factors) is not a substitute for item1c. Companies discussed cyber risk in risk factors long before 2023, but that is a statement of exposure. Item 1C is a description of governance and process — a different question, answered under a different mandate.
Why this data is hard to assemble today
Knowing where the data lives is the easy part. Getting it out at scale is where the cost hides.
EDGAR gives you the filings, and then stops. Every 10-K is free to download — subject to the SEC’s 10-requests-per-second, per-IP ceiling, enforced with a 403 Forbidden and a roughly 10-minute IP block, and a mandatory User-Agent header naming a real contact. Pulling the current 10-K for the S&P 500 is manageable. Pulling every 10-K, every 20-F and every 8-K for a 3,000-name universe across 3 filing years is tens of thousands of requests, hours of wall clock, and a real risk of a mid-run block that leaves gaps you will not notice.
Then you have to find Item 1C inside the document. Which means a parser. Which means anchoring on a heading that, in modern inline-XBRL filings, is split across nested styled elements — so the string Item 1C. Cybersecurity frequently does not exist contiguously in the HTML at all. The table of contents matches your anchor before the real section does. Item 1B, the natural end-anchor, is often a single line reading “None,” or omitted entirely, at which point your extracted section runs to the end of the filing.
And Item 1C is new, which means the heuristics that people spent a decade tuning for Item 1A and Item 7 have not been tuned for it. The failure is silent: you get a string, it is simply the wrong string.
Most datasets skip it entirely. Structured cyber-disclosure products barely exist yet. Which is the opportunity — and the reason this is worth building rather than buying.
Extracting Item 1C from annual reports
That is the cost of building your own parser. The alternative is to skip the parsing entirely. Business Quant’s Section Extraction API pre-extracts sections at ingestion time across 10-K, 10-Q, 8-K, 20-F, S-1 and F-1 — including Item 1C, from the moment the rule took effect. Sub-second lookups, clean HTML, inline XBRL already stripped.
def section(accession, key):
r = requests.get(
f"https://data.businessquant.com/secfilings/{accession}/content",
params={"item_key": key, "api_key": API_KEY},
)
return BeautifulSoup(r.text, "html.parser").get_text("\n", strip=True)
# Latest 10-K
filing = requests.get("https://data.businessquant.com/secfilings", params={
"ticker": "AAPL", "formtype": "10-K", "page_size": 1, "api_key": API_KEY,
}).json()["data"][0]
if "item1c" in filing["items"]: # confirm before requesting
cyber = section(filing["accession"], "item1c")
Check items[] first. The array on every filing record tells you which sections were extracted from that specific filing. A 10-K from fiscal 2022 will not have item1c — the rule did not exist. That is not a failure, and your pipeline should record it as “not applicable” rather than as an error.
Catching Item 1.05 incident filings as they land
Governance is the slow half. Here is the fast half. An actual breach disclosure arrives as an 8-K carrying Item1_05 — on a 4-business-day clock, and, as you would expect, usually after hours on a Friday.
The SEC Filings API returns the item codes in the search response, so you know an 8-K is a cyber incident before downloading it — no fetch-then-classify round trip. Poll on an interval, check the items[] array for Item1_05, and extract only the filings that carry it:
from datetime import datetime, timedelta
since = (datetime.utcnow() - timedelta(days=1)).strftime("%d-%m-%Y")
for ticker in watchlist:
r = requests.get("https://data.businessquant.com/secfilings", params={
"ticker": ticker, "formtype": "8-K", "from_date": since, "api_key": API_KEY,
})
for filing in r.json()["data"]:
if "Item1_05" not in filing["items"]:
continue
incident = section(filing["accession"], "Item1_05")
alert(ticker, filing["publishdatetime"], incident, filing["url_sec"]["url_html"])
Filings are indexed within seconds of EDGAR acceptance, and publishdatetime carries minute-level precision. To be precise about a word the market overuses: this is polling, not streaming — you set the interval, nothing is pushed to you. A 30-second poll is comfortably inside the useful window for a disclosure on a 4-day clock.
Watch for the amendment. Initial Item 1.05 filings are frequently thin — an incident was detected, an investigation is underway, materiality is being assessed. The substance arrives in the 8-K/A, sometimes weeks later, with scope, data affected, and financial impact. An 8-K/A carries a new accession, so treat it as a distinct event linked to the original.
Covering foreign issuers with Item 16K
Now the part that will quietly ruin your panel if you miss it. Foreign private issuers file 20-F, not 10-K, and their cybersecurity disclosure sits under Item 16K. So if your monitor only looks for item1c, every ADR in your universe is silently absent — not flagged, not errored, just gone. Your coverage looks complete and is not.
CYBER_KEY = {"10-K": "item1c", "20-F": "Item16K", "8-K": "Item1_05"}
key = CYBER_KEY[filing["formtype"]]
if key in filing["items"]:
disclosure = section(filing["accession"], key)
This matters more than it sounds. 20-F filers include some of the largest technology, semiconductor, banking and telecom companies listed in the US — precisely the sectors where cyber governance disclosure carries the most information. Section extraction for 20-F is thin across the market generally, which is why most cyber monitors have an ADR-shaped hole in them.
Building the unified cyber disclosure monitor
You have governance from 10-K, incidents from 8-K, and the foreign issuer equivalent from 20-F. The last step is to bring all 3 into one pipeline with one canonical output, so the downstream handling is the same regardless of which form the disclosure arrived in:
CYBER_KEY = {"10-K": "item1c", "20-F": "Item16K", "8-K": "Item1_05"}
def cyber_disclosures(ticker, from_date="01-01-2024"):
r = requests.get("https://data.businessquant.com/secfilings", params={
"ticker": ticker,
"formtype": "10-K,20-F,8-K",
"from_date": from_date,
"api_key": API_KEY,
})
rows = []
for f in r.json()["data"]:
key = CYBER_KEY.get(f["formtype"])
if not key or key not in f["items"]:
continue
rows.append({
"ticker": ticker,
"form": f["formtype"],
"kind": "incident" if key == "Item1_05" else "governance",
"period": f["reportperiod"],
"published": f["publishdatetime"],
"accession": f["accession"],
"text": section(f["accession"], key),
"sec_url": f["url_sec"]["url_html"],
})
return rows
2 record types fall out naturally. Governance disclosures (item1c / Item16K) are annual, comparable, and diffable year over year. Incident disclosures (Item1_05) are event-driven and time-critical. Same pipeline, different downstream handling.
Cite sec_url on everything. For a compliance or underwriting workflow, the authoritative source is sec.gov, whatever you retrieved from.
What to actually measure
Text on its own is not a dataset, and a folder of Item 1C sections is not an analysis. So here is what I actually pull out of them.
For governance disclosures (Item 1C / Item 16K):
- Board oversight structure. Which committee owns cyber — audit, risk, or a dedicated committee? Does the full board receive briefings, and how often?
- Management accountability. Is there a named CISO? Who do they report to? Reporting line into the CEO versus into a divisional CIO is a meaningful distinction.
- Named frameworks. NIST CSF, ISO 27001, SOC 2. Explicit framework adoption is a comparable, extractable field.
- Third-party risk. Whether vendor and supply-chain cyber risk is addressed at all.
- Incident response process. Whether the company describes a tested process or merely asserts one exists.
- Length and specificity. Disclosure that runs 3 paragraphs of generalities is a different signal from disclosure that runs 2 pages with named processes. In a mandated disclosure regime, vagueness is itself information.
For incident disclosures (Item 1.05):
Time from detection to filing. Data affected. Systems affected. Whether financial impact is quantified or deferred. Whether an amendment followed, and what it added.
Year over year, the diff is the signal. A company that materially expands its Item 1C — adding a committee, naming a CISO, adopting a framework — changed something. A company whose Item 1C is byte-identical to last year’s did not.
Edge cases in cyber disclosure
The pipeline above covers the golden path. Before you trust it in production, handle the cases where the data does not behave the way the rule says it should.
Item 1C did not exist before fiscal 2023. So older 10-K filings will not have it, and when your pipeline finds nothing there, it is right. Check the items[] array rather than treating that absence as a failure — otherwise your error log fills with 20 years of correct behaviour.
Item 1.05 versus Item 8.01. Some companies disclose a cyber incident under Item 8.01 (Other Events) rather than Item 1.05 — typically when they have not yet concluded the incident is material. A monitor watching only Item1_05 will miss these. Watch Item8_01 too and filter on content.
Item 1A is not Item 1C. Cyber risk factors have existed for years. They describe exposure, not governance. Do not conflate them, and do not fall back to item1a when item1c is absent.
The initial 8-K is often thin. The substance lands in the 8-K/A. Link amendments to originals and treat the pair as one event.
Foreign issuers use Item 16K. Hardcode item1c and every ADR disappears from your panel without an error.
Materiality is a judgment call the filer makes. A company that never files an Item 1.05 has not necessarily never had an incident. It has never determined an incident was material. That distinction matters in any analysis you publish.
The short version
Step back for a second and look at what this actually is. SEC cybersecurity disclosure is a mandated, structured, market-wide dataset that is barely 2 years old. Those do not come along often. And it is largely missing from commercial data products, not because anyone decided against it, but because those products were built around item taxonomies that predate the rule and nobody has gone back to widen them.
It lives in 3 places under 3 different item keys: item1c in the 10-K, Item1_05 in the 8-K, and Item16K in the 20-F. Business Quant’s Section Extraction API covers all 3 — pre-extracted, clean, sub-second, free — and the SEC Filings API tells you which filings contain them before you fetch a single document.
Which means a peer-benchmarked cyber governance panel, plus a 4-day incident monitor, is an afternoon’s work rather than a data-acquisition project. If you build it now, you are early.
Frequently asked questions
What is Item 1C of the 10-K?
Item 1C is the cybersecurity risk management, strategy and governance disclosure the SEC began requiring in annual reports starting in fiscal 2023. It covers board oversight, management accountability and third-party risk processes — governance, not incidents.
How quickly must a company disclose a material cybersecurity incident?
Within 4 business days of determining the incident is material, filed as Item 1.05 of an 8-K. Initial filings are often thin, with the fuller scope and financial impact arriving later in an 8-K/A amendment.
Where do foreign private issuers disclose cybersecurity governance?
In Item 16K of the 20-F, which is the foreign private issuer equivalent of Item 1C in a 10-K. A cyber disclosure monitor that only checks item1c will silently miss every ADR in its universe.
Is cyber risk factor language in Item 1A the same as Item 1C governance disclosure?
No. Item 1A describes exposure to cyber risk and has existed for years. Item 1C, mandated since fiscal 2023, describes the governance and process a company uses to manage that risk — a different question under a different mandate, and one should not be used as a fallback for the other.
Is the Business Quant Section Extraction API free for monitoring cyber disclosures?
Yes. Item 1C, Item 1.05 and Item 16K are all pre-extracted and served as clean HTML in sub-second lookups, with a free API key and no parser required.