Skip to main content

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.

manager similarity heatmap

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.

price path from insider filings

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.

rate cycle from filings

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.

form d industry heatmap

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py3spread-0.1.1.tar.gz (21.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py3spread-0.1.1-py3-none-any.whl (23.1 kB view details)

Uploaded Python 3

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

Hashes for py3spread-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8d40a9246cb0998401ec4ee27bd70c9be6b71e39dd5d7a46f728a5c42d76bf1e
MD5 e14c7592d844d4f7019ac00f5a998f4a
BLAKE2b-256 7de6c3adab377c2f0bc2533eda316faef599642b70ff9b27642a4f2f7e5b2c5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for py3spread-0.1.1.tar.gz:

Publisher: publish.yml on 3spread/py3spread

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for py3spread-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6958fbe42917e21d058bf46d1c4511cf7366c2405d2f51db1e6d62a55ac1f88d
MD5 159892da04f90fe08dfdce4db3acd7bb
BLAKE2b-256 5ae0e7b3c9c29818a4500274b73c3069da866d39bcea900a43c1a1f45df60b1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for py3spread-0.1.1-py3-none-any.whl:

Publisher: publish.yml on 3spread/py3spread

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page