profitelligence
SEC filings, insider trading and market signals in Python.
pip install profitelligence
import profitelligence as prof
prof.api_key("pk_live_...") # or set PROFITELLIGENCE_API_KEY
prices = prof.company.ohlc("AAPL", days=90) # 90 rows, typed
prices[0].close # 305.69, a float
prices.df # a DataFrame, with [pandas]
That is the whole idea. The Profitelligence API answers in pipe-delimited CSV. This package parses it, types it, and hands you rows you can work with.
What you get
Nine namespaces cover 68 endpoints. Every method is generated from the same API reference the documentation site renders, so the package cannot describe an endpoint the API does not have.
| Namespace | Data |
|---|---|
prof.company |
Profiles, daily prices, technical signals, corporate actions |
prof.filings |
8-K summaries and filing patterns |
prof.form4 |
Insider transactions, clusters, insider profiles |
prof.institutional |
13F holdings, managers, crowded trades |
prof.financials |
Income statement, balance sheet, cash flow |
prof.fred |
Economic series from the Federal Reserve |
prof.discovery |
Search, spotlights, interesting companies |
prof.graph |
The knowledge graph |
prof.analytics |
Correlations, opportunity scores, strategies |
Every method carries the endpoint's own documentation. In a notebook,
prof.form4.clusters? shows the arguments, the tier it needs, and the columns
it returns.
Authentication
Get a key at profitelligence.com/account/api-keys.
prof.api_key("pk_live_...") # for a notebook
export PROFITELLIGENCE_API_KEY=pk_live_...
You can also call with no key at all. Guests reach the free endpoints on the top 500 symbols, which is enough to try the package before you sign up.
In a service, build a client and hold it. One client is one connection pool.
from profitelligence import Client
with Client(api_key="pk_live_...", timeout=60) as prof:
holdings = prof.institutional.manager_top_holdings("0001067983")
Tables
CSV endpoints return a Table: named columns, typed values, one row object per
record. It is a normal Python sequence, so index it, slice it, and iterate it.
prices = prof.company.ohlc("AAPL,MSFT", days=180)
prices.columns # ['symbol', 'time', 'open', 'high', 'low', 'close']
len(prices) # 360
prices[0].close # 305.69 a float
prices[0].time # date(2026, 8, 17) a date
prices.column("close") # the whole column
prices.to_dicts() # plain dictionaries
Types come from the API reference where it declares them, and from the data
where it does not. A column is typed as a whole: if one value will not parse,
the column stays text rather than becoming a mix you cannot do arithmetic on.
An empty cell is None, never 0 and never "".
For pandas, install the extra:
pip install 'profitelligence[pandas]'
frame = prices.df # or prices.to_pandas()
frame.set_index("time").close.resample("W").last()
Date columns arrive as datetime64, so resampling and plotting work with no
further conversion.
JSON endpoints — the page routes, FRED, search, and the knowledge graph — return the decoded body as it stands.
When a call does not work
Errors say what happened, in the API's own words.
try:
scores = prof.analytics.opportunities()
except prof.UpgradeRequired as error:
print(error.message) # the plan this endpoint needs
except prof.RateLimited as error:
print(error.retry_after) # seconds until the window resets
| Error | Means |
|---|---|
AuthenticationError |
The key is absent, wrong, or revoked |
UpgradeRequired |
Your plan does not include this endpoint or this symbol |
RateLimited |
The window is spent. retry_after, limit, remaining, reset |
BadRequest |
An argument is missing or out of range |
NoData |
The API looked and found nothing to return |
ServerError |
The API failed. The client already retried twice |
Timeout |
No answer inside the timeout |
All of them inherit ProfitelligenceError.
A rate limit is never retried behind your back. A notebook that sleeps for a minute without telling you is worse than an error you can see. Server errors and timeouts are retried twice, with backoff.
Two of these deserve a word. The API sometimes reports a problem in-band: HTTP
200, with a body of error,<message>. Read raw, that looks like success and
parses to nothing. This package raises instead — BadRequest when you caused
it, NoData when the API simply had nothing — so an empty result never passes
for a real one. A genuinely empty result, which the API returns as a header row
with no data rows, stays an empty Table.
What this package does not do
It reads. There is nothing here that writes to your account, and nothing that places a trade.
It reports what filings and prices show. It does not advise, predict, or recommend. What you do with the data is your decision, and a licensed advisor is the right person to help you make it.
Rate limits and tiers
Each key has a request window and a symbol list that follow your plan. Guests
and Free see the top 500 symbols, Pro the top 6,000, Elite all of them. A
symbol outside your tier raises UpgradeRequired with the plan it needs.
How this package is built
The client is generated. The nine modules under
src/profitelligence/resources/ are produced by codegen/generate.py from
codegen/spec.json, which is exported from the same API reference that renders
at profitelligence.com/api-reference.
That reference is the contract: an endpoint reaches this package by being
documented, not by someone hand-writing a signature.
Editing a generated file therefore has no lasting effect — the next generation
replaces it. The hand-written part is the core: client.py, _http.py,
table.py and errors.py.
uv sync --group dev
pytest # offline, every response mocked
pytest -m live # hits the public API; no key needed for the free endpoints
ruff check . && ruff format --check .
The source repository is private, so there is nowhere to send a pull request.
Bug reports are genuinely useful and are acted on: mail
support@profitelligence.com or use
profitelligence.com/support, and say
what you called, what came back, what you expected, and your Python and
profitelligence.__version__. A failing five-line script is worth more than a
paragraph.
License
MIT.
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 profitelligence-0.1.1.tar.gz.
File metadata
- Download URL: profitelligence-0.1.1.tar.gz
- Upload date:
- Size: 64.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48a4e23c323b275c3e09f47d85ffd5b935ed120a2fdc60174f6c0dbea4f0fa9b
|
|
| MD5 |
c62b4c55885c426d75e86c2b82ffe474
|
|
| BLAKE2b-256 |
15a08d5904a7b51a3624f2d88c51c440138d8a88bd81797baa89d7658f40a59f
|
Provenance
The following attestation bundles were made for profitelligence-0.1.1.tar.gz:
Publisher:
publish.yaml on profitelligence/profitelligence-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
profitelligence-0.1.1.tar.gz -
Subject digest:
48a4e23c323b275c3e09f47d85ffd5b935ed120a2fdc60174f6c0dbea4f0fa9b - Sigstore transparency entry: 2704405007
- Sigstore integration time:
-
Permalink:
profitelligence/profitelligence-py@291aeeec061a53f548e17ec7648f211a9a37bf04 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/profitelligence
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@291aeeec061a53f548e17ec7648f211a9a37bf04 -
Trigger Event:
push
-
Statement type:
File details
Details for the file profitelligence-0.1.1-py3-none-any.whl.
File metadata
- Download URL: profitelligence-0.1.1-py3-none-any.whl
- Upload date:
- Size: 46.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3a2cbed99f9c6fd0c31b8d566cca3d8a4d7ba9077a6693613ec3d488b0671a2
|
|
| MD5 |
0d648512f5dd4767e90f4e8d9b11c004
|
|
| BLAKE2b-256 |
40cbeae92c9c5be497c549031f75df195b88cb3752170ccce206aca7c0b767db
|
Provenance
The following attestation bundles were made for profitelligence-0.1.1-py3-none-any.whl:
Publisher:
publish.yaml on profitelligence/profitelligence-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
profitelligence-0.1.1-py3-none-any.whl -
Subject digest:
d3a2cbed99f9c6fd0c31b8d566cca3d8a4d7ba9077a6693613ec3d488b0671a2 - Sigstore transparency entry: 2704405042
- Sigstore integration time:
-
Permalink:
profitelligence/profitelligence-py@291aeeec061a53f548e17ec7648f211a9a37bf04 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/profitelligence
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@291aeeec061a53f548e17ec7648f211a9a37bf04 -
Trigger Event:
push
-
Statement type: