When a US company raises a private round, it files a Form D with the SEC within 15 days of the first sale. That covers seed rounds, Series A and later, SAFEs and convertible notes, which makes Form D a public, official record of who is raising and how much.
Getting it out of EDGAR is the awkward part. EDGAR publishes daily form indexes and one XML primary document per filing, so you have to read the index, fetch each filing politely within the SEC's fair-access limits, parse the XML and then filter out the pooled investment funds and real estate deals that file alongside operating startups.
This guide shows how to get a clean, filtered Form D dataset, how to tell new rounds from amendments, how to rank and deduplicate the results, and how to run it as a daily feed or a one-off historical backfill.
Step by step
Know what a Form D does and does not contain
Each filing gives the issuer's name, business address and phone, state, industry group, entity type, year of incorporation, the federal exemption claimed (for example Rule 506(b) or 506(c)), total offering amount, amount sold so far, number of investors and date of first sale. It does not name investors or give a valuation, and amounts are as reported by the issuer, in US dollars.
Choose the date window
daysBack (default 7) is the simplest option. For a precise range, set dateFrom and dateTo in YYYY-MM-DD; dateFrom overrides daysBack. Form D XML goes back to 2009, and one run covers at most 366 days, so split longer backfills into yearly runs.
{ "dateFrom": "2025-01-01", "dateTo": "2025-12-31", "industries": ["Biotechnology", "Pharmaceuticals"], "states": ["MA"], "maxResults": 5000 }Filter down to operating startups
The default industries, Technology (Computers, Telecommunications and Other Technology) and Health Care, already leave out pooled investment funds and real estate. Narrow further with states, exemptions (506(c) means general solicitation was allowed, with verified accredited investors only) and minAmountSold, for example 1000000 for rounds where at least $1M has been sold. Name, CIK and amendment filters run before any XML is downloaded, so they make runs faster than state, industry or amount filters.
Separate new rounds from amendments
A Form D/A is an amendment: an annual renewal or a correction of an earlier notice, which also updates the amount sold. Amendments are included by default. For a 'just raised' prospecting list, set includeAmendments to false so each row is a new notice; for tracking how a round fills, keep them and follow the issuer's CIK.
Rank and clean the results
Funds often report an indefinite offering size, which comes back as totalOfferingAmount null with offeringAmountIndefinite true. The pandas snippet below loads a run, drops indefinite offerings, ranks by amount sold and keeps the columns a sales team needs.
import os import pandas as pd from apify_client import ApifyClient client = ApifyClient(os.environ["APIFY_TOKEN"]) run = client.actor("actor-forge/startup-funding-rounds").call(run_input={ "daysBack": 7, "includeAmendments": False, "minAmountSold": 1000000, }) df = pd.DataFrame(list(client.dataset(run["defaultDatasetId"]).iterate_items())) if "offeringAmountIndefinite" in df.columns: df = df[df["offeringAmountIndefinite"] != True] cols = ["filingDate", "issuerName", "issuerCity", "issuerState", "industryGroup", "totalAmountSold", "totalOfferingAmount", "dateOfFirstSale", "filingUrl"] top = df.sort_values("totalAmountSold", ascending=False)[cols] top.to_csv("funded_this_week.csv", index=False) print(top.head(20).to_string(index=False))Run it as a daily feed without duplicates
EDGAR publishes each business day's index at about 10 pm US Eastern, so filings appear the next morning, and weekends and federal holidays have no index. Schedule the actor for the morning with a small overlap, such as daysBack 3, and deduplicate on filingUrl so Mondays and holidays are handled without gaps. The script keeps a local file of filing URLs it has already seen.
import json import os from pathlib import Path from apify_client import ApifyClient seen_path = Path("seen_filings.json") seen = set(json.loads(seen_path.read_text())) if seen_path.exists() else set() client = ApifyClient(os.environ["APIFY_TOKEN"]) run = client.actor("actor-forge/startup-funding-rounds").call(run_input={ "daysBack": 3, "includeAmendments": False, }) new_rows = [] for row in client.dataset(run["defaultDatasetId"]).iterate_items(): if row["filingUrl"] not in seen: seen.add(row["filingUrl"]) new_rows.append(row) seen_path.write_text(json.dumps(sorted(seen))) for r in new_rows: print(r["filingDate"], r["issuerName"], r.get("totalAmountSold"))Add people only when you have a lawful basis
includeRelatedPersons adds the executive officers, directors and promoters listed on each filing, plus the signer, with name, relationship, city and state only. These are public SEC records but they are personal data, so turn the option on only if you have a lawful basis such as GDPR or CCPA legitimate interest, and keep it off for company-level lists.
Sample input
{
"daysBack": 7,
"industries": [
"Technology",
"Health Care"
],
"exemptions": [
"506b",
"506c"
],
"includeAmendments": false,
"maxResults": 300
}Sample output
A week of technology and health care Form D notices looks like this:
| filingDate | formType | issuerName | issuerState | industryGroup | exemptions | totalOfferingAmount | totalAmountSold | investorCount | yearOfIncorporation |
|---|---|---|---|---|---|---|---|---|---|
| 2026-10-16 | D | 1921 Technologies Inc. | NY | Other Technology | Rule 506(b) | 10000000 | 3000000 | 3 | 2026 |
| 2026-10-16 | D | Estuary Biotherapeutics, Inc. | CA | Biotechnology | Rule 506(b) | 103654385 | 40654685 | 25 | 2022 |
| 2026-10-16 | D | Lamina Surgical, Inc. | CA | Other Health Care | Rule 506(c) | 5000000 | 490000 | 8 | 2024 |
| 2026-10-16 | D | Knowable Labs, Inc. | CA | Other Technology | Rule 506(b) | 310000 | 310000 | 5 | 2026 |
Run it from code
cURL
curl -X POST "https://api.apify.com/v2/acts/actor-forge~startup-funding-rounds/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"daysBack": 7, "industries": ["Technology", "Health Care"], "exemptions": ["506b", "506c"], "includeAmendments": false, "maxResults": 300}'JavaScript (Node.js)
// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
"daysBack": 7,
"industries": [
"Technology",
"Health Care"
],
"exemptions": [
"506b",
"506c"
],
"includeAmendments": false,
"maxResults": 300
};
const res = await fetch(
"https://api.apify.com/v2/acts/actor-forge~startup-funding-rounds/run-sync-get-dataset-items",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(input),
}
);
const items = await res.json();
console.log(items.length, items[0]);Python
# pip install apify-client (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"daysBack": 7,
"industries": [
"Technology",
"Health Care"
],
"exemptions": [
"506b",
"506c"
],
"includeAmendments": False,
"maxResults": 300
}
run = client.actor("actor-forge/startup-funding-rounds").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.
What it costs
A weekly list of 300 new tech and health care rounds costs 300 x $0.01 = $3.00. Even an unfiltered 1,000 filings, which the README puts at about four business days of every Form D filed, costs $10.00.
| Charged for | When | Price | Per 1,000 | Worked example |
|---|---|---|---|---|
| Filing result | Charged per Form D / D/A filing parsed and delivered (all fields included) | $0.01 | $10 | 1,000 filings = $10.00 (about 4 business days of every Form D filed) |
| Actor Start (platform start fee) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 | — | One run at up to 1 GB = $0.00005 (charged as one event) |
Ready to try it? Startup Funding Rounds Tracker — Recently Funded (SEC Form D) runs on Apify, pay per result.
Run on Apify → Read the full actor pageTips and pitfalls
- totalAmountSold is the amount sold so far, not the final close; later D/A amendments update it.
- Requests are paced to 5 per second, so a run takes roughly a minute per 250 filings parsed. Filtering by name or CIK keeps backfills fast.
- Results are sorted newest filing date first, so maxResults trims the oldest filings in your window.
- Use keywords such as 'Therapeutics' or 'AI' to match issuer names, but remember many startups have names that say nothing about what they do.
- If you clear the industries filter, expect many pooled funds with indefinite offering sizes; they always pass minOfferingAmount.
FAQ
How soon after a funding round does the Form D appear?
The company must file within 15 days of the first sale, and the filing shows up in the actor's results the morning after EDGAR's nightly index for that day.
Can I get Form D data from before 2009?
No. Form D XML filings start in 2009, and dateFrom is clamped to 2009-01-01.
Does every startup round have a Form D?
Not necessarily. The actor can only return Form D filings that were actually made on EDGAR, so a raise that was never filed as a Form D, for example by a company outside the US, will not appear.
What is the difference between Rule 506(b) and 506(c)?
Both are federal exemptions you can filter on. 506(c) allows general solicitation, with investors limited to verified accredited investors; 506(b) does not allow general solicitation.
Actors used in this guide
Startup Funding Rounds Tracker — Recently Funded (SEC Form D)
Track recently funded US startups from official SEC Form D filings: company, amount raised and offered, round date, industry, exemption, business…
$10 per 1,000 · filing resultRelated guides
How to Find a Company's Job Board and ATS (Workday, Greenhouse, Lever, Ashby)
Open any job on the company's careers page and look at the host: myworkdayjobs.com, greenhouse.io, lever.co, ashbyhq.com and similar tell you the…
How to Export UK Company Directors from Companies House in Bulk
Give Companies House Enrichment a list of company numbers or a SIC code, status and location filter, keep includeOfficers on, then flatten the…