A public company that cannot file its 10-K or 10-Q on time is required to say so. The instrument is Form 12b-25 — everyone calls it an NT, for "notification of late filing" — and it is a short, dull document that says the report will be late and gestures at why. In exchange the issuer gets an automatic extension: fifteen calendar days for an annual report, five for a quarterly.
It is the cheapest distress flag in existence. Not because an NT is rare or dramatic, but because it is an admission made under a deadline, by a company that would obviously rather not make it. Nobody files one because things are going well. The auditor is asking questions, or the controller quit, or a number from last year has stopped being true.
The catch is that most NTs are boring, and the ones that matter look identical to the ones that don't on the day they land. So we went and measured the follow-through: 30,754 late-filing notices from January 2015 through mid-September 2026, tracked forward to see whether the overdue report ever actually arrived.
The signal is not the notice. It is the lapse.
Here is the distribution that matters. Every NT 10-K filed through the end of 2025, bucketed by how long the overdue annual report took to show up:
- 51.7% — filed inside the fifteen-day window. The system working as designed.
- 21.1% — 16 to 45 days. Late past the extension, but resolved within the quarter.
- 10.2% — 46 to 180 days.
- 4.1% — more than 180 days.
- 12.9% — never filed at all.
Roughly half of all NT 10-K filers use the extension for exactly what it is for: the audit ran long, the report lands a week later, nothing happened. Reading that half as distress is how you end up with a signal that is 90% noise.
The other half is where the information is, and the cleanest cut through it is a date, not a judgment call. The extension window closes on a known day. Either the report was filed by then or it was not. An issuer still delinquent after the window has, in the plainest possible terms, missed a deadline it already asked for extra time on.
The NT tells you the numbers are late. The silence after the extension expires tells you the numbers are wrong.
That is why the feed carries `cured_date`, `days_to_cure` and a computed `is_delinquent` rather than just the notice. A row that has been sitting uncured for sixty days past its window is a different object from the same row on the day it was filed, and the useful query is almost always the former.
Listed issuers cure; the rest of the tape does not
Only 11,997 of those 30,754 notices — 39% — come from issuers that map to a symbol in our universe. The remainder are shells, deregistering micro-caps, and companies whose listing ended before the paperwork did. That split turns out to be the single strongest conditioner on the whole dataset:
- Listed issuers cure 94.0% of their late filings. Unmapped issuers cure 85.2%.
- On NT 10-Ks specifically, the never-filed rate is 6.3% for listed issuers versus 12.9% across everyone.
- Median time to cure is about a week either way — the difference is entirely in the tail, not the middle.
So a delinquent NT from a name you can actually trade is roughly twice as unusual as the raw base rate suggests. If you are scanning for distress in a tradable universe, filter to mapped symbols first or your hit list will fill up with companies that no longer exist.
The repeat-offender intuition is wrong
The obvious next move is to treat a chronic late filer as the risky one and a first-time NT as the alarming anomaly. We checked, and it does not hold. Among listed issuers filing an NT 10-K between 2018 and 2025:
- First NT in three years: 92.3% eventually cured.
- Repeat filer: 95.0% eventually cured.
If anything the chronic filer is the safer bet. It makes sense once you say it out loud — a company on its ninth NT has a small accounting department and a standing habit, and it has filed the report every previous time. The first-timer is the one where something changed. Neither effect is large enough to trade on its own, but it is large enough to kill the feature everyone builds first.
One artifact to watch for while you replicate this: never-cured rates by filing year look like they are climbing steeply (10.1% in 2015, 21.8% for 2026 to date). That is censoring, not deterioration. A notice filed last month has not had time to cure. Drop the most recent six to twelve months before computing anything that looks like a trend.
The clock the filing runs on
NTs are deadline artifacts, and they cluster hard. Measured from the end of the period the late report covers, the median NT 10-K is filed on day 90 (10th percentile 76, 90th 93) and the median NT 10-Q on day 45 (p10 43, p90 48). They pile up against the statutory deadlines because that is the last possible moment to admit you will miss them.
Two practical consequences. First, NT volume is violently seasonal — there is no point comparing March to July without normalizing by fiscal-period census. Second, `period_of_report` and `filed_date` answer different questions: the first tells you which set of numbers is in trouble, the second tells you when the market learned. Backtest on the second.
Querying it
The cross-issuer endpoint is the scanning surface. `delinquent=true` applies the window arithmetic server-side — fifteen days for an annual report, five for a quarterly — and returns only notices whose extension lapsed with nothing filed:
curl -H "Authorization: Bearer $HEDGEFRIEND_KEY" \ "https://api.hedgefriend.dev/v1/sec/late-filings?delinquent=true&filing_type=NT%2010-K&from=2026-01-01" # Everything one issuer has ever filed, matched on CIK so every # share class resolves to the same notice. curl -H "Authorization: Bearer $HEDGEFRIEND_KEY" \ "https://api.hedgefriend.dev/v1/sec/late-filings/TICKER"
A weekly delinquency scan is about as small as a real screen gets — one paginated request, filtered to rows that carry a ticker:
import os, requests
HEADERS = {"Authorization": f"Bearer {os.environ['HEDGEFRIEND_KEY']}"}
URL = "https://api.hedgefriend.dev/v1/sec/late-filings"
rows, cursor = [], None
while True:
r = requests.get(
URL,
params={
"delinquent": "true",
"from": "2026-01-01",
"limit": 200,
"cursor": cursor,
},
headers=HEADERS,
timeout=30,
)
r.raise_for_status()
page = r.json()
rows += page["data"]
cursor = page["meta"]["next"]
if not cursor:
break
# Tradable names only: unmapped issuers cure far less often and are
# mostly shells, which will otherwise dominate the list.
listed = [x for x in rows if x["ticker"]]
listed.sort(key=lambda x: x["filed_date"])
for x in listed:
print(x["filed_date"], x["ticker"].ljust(6), x["filing_type"].ljust(8), x["subject_name"])Rows that have since cured carry `cured_date` and `days_to_cure`, so the same endpoint serves the historical study and the live screen. There is no separate research extract to reconcile against production.
What this is and is not
It is not a strategy. Delinquency is a low-frequency event — around 760 distinct listed tickers file any NT in a given year, out of roughly 11,400 active symbols, and only a fraction of those go delinquent — and the names it surfaces are disproportionately small, illiquid, and hard to borrow. Anyone promising you a Sharpe ratio from this is selling something.
What it is: a very high-precision flag for a state of the world that is otherwise invisible until a restatement or a delisting notice makes it obvious. It costs one request a week. It is a good input to a risk screen, a good reason to read an issuer's 8-Ks carefully, and a good exclusion rule — many funds simply will not hold a delinquent filer, and knowing which names qualify before the deadline passes is worth more than knowing after.
Mostly it is a reminder that a lot of the useful information in public markets is not signal in the statistical sense at all. It is a company being made to say something it would rather not say, on a schedule it does not control, in a filing nobody reads.
The free tier covers 500 requests a day — enough to reproduce anything in this post.
Get a free key