This page covers the workflow: signing up, authenticating, rate limits, and reading a response. For the exhaustive, always-current shape of every field, use the API Reference (auto-generated from the running API).
caveats field saying this. Full detail in §05 below.Three steps: get a key, call an endpoint, read the response. No credit card, no email verification -- POST /v1/signup issues a free-tier key instantly.
0. Try it right now -- no signup required
/statements is one of the two public endpoints (see step 3 below), so this works before you've done anything else:
curl "https://api.clearyfi.com/v1/companies/AAPL/statements/income?year=2023&period=FY"
import requests resp = requests.get( "https://api.clearyfi.com/v1/companies/AAPL/statements/income", params={"year": 2023, "period": "FY"}, ) statement = resp.json() for line in statement["lines"]: print(line["canonical_concept"], line["value"], "from", line["source_tag"])
Response includes Apple's real FY2023 revenue, gross profit, operating income, net income, and diluted EPS -- each line carrying the exact source gaap_tag it was mapped from, for audit. interest_expense is deliberately absent: Apple nets it into other income/expense rather than tagging it discretely, so we surface that as a documented gap instead of guessing a value.
1. Sign up for a key
curl -X POST https://api.clearyfi.com/v1/signup \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com"}'
{ "api_key": "sfk_...redacted, shown once...", "tier": "free", "rate_limit_per_sec": 5, "daily_quota": 1000 }
The plaintext key is returned exactly once, in this response. Only its hash is stored -- if you lose it, sign up with a different email (there's no reissue flow yet).
2. Call a gated endpoint with X-API-Key
curl https://api.clearyfi.com/v1/companies/AAPL/insider-trades?limit=5 \
-H "X-API-Key: sfk_..."
3. Two endpoints need no key at all
/companies/{symbol}/statements/{statement} and /companies/{symbol}/periods are public -- they power the Data Explorer directly from browser JS. They're rate-limited per-IP instead of per-key.
Every endpoint except the two statement/period endpoints above requires an X-API-Key header. An invalid, missing, or revoked key gets a 401 before any rate limit is even checked.
Each key has two independent limits: a short-window burst rate (requests/sec, resets continuously) and a daily quota (resets at UTC midnight, tracked per calendar day). Either one being exceeded returns 429. Call GET /v1/usage with your key to see your own trailing daily counts.
| Tier | Rate limit | Daily quota | How to get it |
|---|---|---|---|
| free | 5 req/sec | 1,000 req/day | Default -- issued by POST /v1/signup |
| basic | 20 req/sec | 25,000 req/day | Manual upgrade (no self-serve billing yet) |
| pro | 100 req/sec | 250,000 req/day | Manual upgrade (no self-serve billing yet) |
Every signup is issued the free tier today -- there's no payment integration yet, so moving to a paid tier is a manual step on our end rather than something you can trigger yourself. All tiers are free during the beta; the planned prices when billing goes live are $19/mo (basic) and $79/mo (pro), and the free tier's limits won't be reduced (see the terms for the standing commitments).
| Status | Meaning | What to do next |
|---|---|---|
400 | Bad request parameter -- e.g. a quarter-end date that isn't a valid calendar quarter-end. | Check the parameter against the endpoint's schema in the API Reference; period params must be an actual calendar quarter-end date. |
401 | Missing, unknown, or revoked X-API-Key. | Confirm the X-API-Key header is present and spelled correctly. If you never signed up, POST /v1/signup (step 1 above) issues one instantly. |
404 | Unknown ticker/CIK, or no data found for the requested company/period/CUSIP. | Verify the ticker/CIK is a real SEC registrant and the period is inside our coverage floor (see §05) -- an empty/404 result never means "nothing was filed," it means outside our coverage window or a typo. |
429 | Per-key burst rate or daily quota exceeded (or, on the two public endpoints, the per-IP burst limit). | Back off and retry with backoff; call GET /v1/usage to see your current daily count against your quota. Sustained need for more room means a tier upgrade (see §02), not a workaround. |
502 / 503 | Upstream SEC request timed out, couldn't connect, or returned an error (or, for 503 alone, an internal admin operation was misconfigured). | Retry -- these mean the failure was upstream (SEC) or transient, not a bug in your request. If it persists across retries, treat it as a real outage and check /health. |
Grouped by domain. See the API Reference for full request/response schemas and live "Try it out".
| Endpoint | Description |
|---|---|
GET /v1/companies/{symbol}/statements/{statement} | One normalized income statement, balance sheet, or cash flow statement for a fiscal period. |
GET /v1/companies/{symbol}/periods | Fiscal periods with data available for a company. |
| Endpoint | Description |
|---|---|
GET /v1/companies/{symbol}/insider-trades | Form 3/4/5 insider transactions, most recent filings first. |
| Endpoint | Description |
|---|---|
GET /v1/companies/{symbol}/beneficial-ownership | Schedule 13D/13G (5%+ crossing) filings for a company. |
GET /v1/companies/{symbol}/institutional-holders | Managers holding a company as of a 13F quarter-end. |
GET /v1/companies/{symbol}/institutional-activity | DERIVED buy/sell activity for a company, aggregated across all managers. |
GET /v1/managers/{manager_cik}/holdings | One manager's full 13F holdings snapshot for a quarter. |
GET /v1/managers/{manager_cik}/activity | DERIVED buy/sell activity for one manager vs. the prior quarter. |
GET /v1/cusip-resolution-stats | Coverage snapshot for 13F CUSIP-to-company resolution. |
| Endpoint | Description |
|---|---|
POST /v1/signup | Issue a free-tier API key for an email address. |
GET /v1/usage | Your key's tier, limits, and recent daily request counts. |
13F is a quarter-end holdings snapshot, not a transaction feed. Every "activity" endpoint above computes buy/sell by diffing two consecutive quarters -- it is never SEC-reported trade data. Each of those responses carries an always-present caveats field repeating this.
institutional-holders/institutional-activity), an empty list can mean "no manager reported holding this issuer" or "this quarter hasn't been ingested for any manager yet" -- it does not confirm zero institutional ownership.