Python client for the 3spread API (machine-readable SEC filing data)
Project description
py3spread
Python client for the 3spread API: machine-readable SEC filing data (insider transactions, 13F holdings, fund portfolios, beneficial ownership, and more).
API keys are always free for individuals. Sign up at 3spread.com/auth/signup and you get full access to every dataset at 300 requests/minute.
Install
pip install py3spread
Requires Python 3.10+.
Public beta
3spread is in public beta: live, but still
rounding off the rough edges. History currently reaches back to filings
accepted in early 2021, with deeper coverage expanding per the roadmap.
Expect some coverage gaps across filing types,
fields, and history windows, the occasional filing that parses wrong, and
endpoints that may evolve with feedback. The
roadmap shows what's live now and what's
coming next, and it's driven by community requests. Rather than assuming a
gap, check what's actually populated via the coverage endpoints
(client.coverage, see below).
Quickstart
API keys are free, always, in beta and after. Grab one at 3spread.com/auth/signup, then:
from py3spread import Client
client = Client() # reads THREESPREAD_API_KEY from the environment
page = client.filings.list(ticker="AAPL", limit=5)
for filing in page["data"]:
print(filing["form_type"], filing["accepted_time"], filing["source_url"])
You can also pass the key directly with Client(api_key="...").
What the data can do
A few results straight out of the examples, every one of them built with a Community API key.
Which managers actually differ from the index
Ten managers' latest 13F portfolios, pairwise overlap, clustered. The custodian complex holds the market; Berkshire sits alone in its corner.
weights = portfolio.groupby("cusip")["value_usd"].sum() / total
common = a.index.intersection(b.index)
overlap = np.minimum(a[common], b[common]).sum()
From institutional_13f.ipynb.
The two-manager version lives in
fund_overlap.ipynb.
A price chart with no market data
Every insider transaction reports its execution price. Two years of Form 4 prices trace the stock, no exchange feed involved.
for txn in client.insiders.iter_transactions(
issuer_ticker="AAPL", transaction_kind="nonderiv",
transaction_start="2024-07-01", transaction_end="2026-07-01",
):
plot(txn["transaction_date"], txn["transaction_price_per_share"])
From form4_price_chart.ipynb.
The Fed cycle, out of money market filings
Median prime fund yield with a 10th-90th percentile band, built from the seven day gross yield every fund reports monthly on Form N-MFP.
for filing in client.money_market_funds.iter(cik=registrant, ...):
panel.append((filing["period_of_report"], filing["seven_day_gross_yield"]))
From rate_cycle.ipynb, which also
runs per-fund pass-through regressions.
The private capital map
Form D exempt offerings by industry and month. 319K+ filings almost nobody parses.
offerings = client.private_offerings.iter(
accepted_start="2026-01-01", accepted_end="2026-01-31")
From form_d_heatmap.ipynb.
More in examples/: an activist 13D radar, insider dossiers,
money market stress ranking, a live filing tape, and a dozen others.
Datasets
Each filing family is a resource on the client:
| Resource | Dataset |
|---|---|
client.filings |
Master filings index (all families) |
client.insiders |
Forms 3, 4, 5 insider filings and transactions |
client.institutional_holdings |
Form 13F filings and holdings |
client.private_offerings |
Form D offering notices |
client.fund_portfolios |
Form N-PORT portfolio holdings |
client.beneficial_ownership |
Schedule 13D / 13G reports |
client.proposed_sales |
Form 144 proposed sales |
client.fund_census |
Form N-CEN census reports |
client.money_market_funds |
Form N-MFP2/N-MFP3 reports and NAV series |
client.proxy_votes |
Form N-PX voting records |
client.reg_a_offerings |
Regulation A+ offerings |
client.registration_statements |
Registration statements and text sections (still being populated) |
client.entities |
Master CIK directory |
client.coverage |
Coverage and freshness endpoints |
client.changes |
Per-family changefeed |
list() returns one raw page as a dict. iter() (and iter_transactions(),
iter_holdings(), etc.) handles pagination for you and yields rows:
for txn in client.insiders.iter_transactions(issuer_ticker="AAPL",
transaction_start="2026-01-01",
transaction_end="2026-06-30"):
print(txn)
List endpoints require at least one identity filter (cik, ticker, or a
family id like issuer_cik) or a fully bounded date window; unfiltered calls
return a 400.
Keeping a downstream store in sync
Poll the changefeed per family:
for event in client.changes.iter("insiders", since="2026-07-01T00:00:00"):
print(event["filing_id"], event["action"])
Errors and retries
HTTP errors raise typed exceptions from py3spread, all subclasses of
ThreeSpreadError: AuthenticationError (401), RateLimitError (429),
WindowTooWideError / MissingParameterError / BadRequestError (400),
NotFoundError (404), ValidationError (422), ServerError (500/502), and
ServiceUnavailableError (503). Each carries status_code, code,
request_id, and details where available.
429, 502, and 503 are retried automatically with backoff (configurable via
Client(max_retries=...)).
Notes on values
Monetary and ratio fields come back as strings at full precision, for example
"360836000000.00". Parse them with decimal.Decimal, not float. Filing
datetimes such as accepted_time are timezone-naive ISO 8601 strings, as
filed with the SEC.
Tickers are uppercased for you before sending (the API rejects lowercase).
Development
uv venv && uv pip install -e ".[dev]"
pytest
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py3spread-0.1.1.tar.gz.
File metadata
- Download URL: py3spread-0.1.1.tar.gz
- Upload date:
- Size: 21.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d40a9246cb0998401ec4ee27bd70c9be6b71e39dd5d7a46f728a5c42d76bf1e
|
|
| MD5 |
e14c7592d844d4f7019ac00f5a998f4a
|
|
| BLAKE2b-256 |
7de6c3adab377c2f0bc2533eda316faef599642b70ff9b27642a4f2f7e5b2c5c
|
Provenance
The following attestation bundles were made for py3spread-0.1.1.tar.gz:
Publisher:
publish.yml on 3spread/py3spread
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py3spread-0.1.1.tar.gz -
Subject digest:
8d40a9246cb0998401ec4ee27bd70c9be6b71e39dd5d7a46f728a5c42d76bf1e - Sigstore transparency entry: 2061482545
- Sigstore integration time:
-
Permalink:
3spread/py3spread@a016ea6f9cb3d5474c298a5e5397d52d97c076be -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/3spread
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a016ea6f9cb3d5474c298a5e5397d52d97c076be -
Trigger Event:
release
-
Statement type:
File details
Details for the file py3spread-0.1.1-py3-none-any.whl.
File metadata
- Download URL: py3spread-0.1.1-py3-none-any.whl
- Upload date:
- Size: 23.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6958fbe42917e21d058bf46d1c4511cf7366c2405d2f51db1e6d62a55ac1f88d
|
|
| MD5 |
159892da04f90fe08dfdce4db3acd7bb
|
|
| BLAKE2b-256 |
5ae0e7b3c9c29818a4500274b73c3069da866d39bcea900a43c1a1f45df60b1f
|
Provenance
The following attestation bundles were made for py3spread-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on 3spread/py3spread
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py3spread-0.1.1-py3-none-any.whl -
Subject digest:
6958fbe42917e21d058bf46d1c4511cf7366c2405d2f51db1e6d62a55ac1f88d - Sigstore transparency entry: 2061482632
- Sigstore integration time:
-
Permalink:
3spread/py3spread@a016ea6f9cb3d5474c298a5e5397d52d97c076be -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/3spread
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a016ea6f9cb3d5474c298a5e5397d52d97c076be -
Trigger Event:
release
-
Statement type: