Form4API REST API Reference — SEC Form 4, 144 & 13F-HR Data
Get a free API key
500 requests/day, no credit card — your key shows instantly in the dashboard.
GET /v1/transactions?ticker=AAPL&per_page=10Reproduce with curl
curl "https://api.form4api.com/v1/transactions?ticker=AAPL&per_page=10" \ -H "X-Api-Key: YOUR_API_KEY"
Get your own free API key → 500 requests/day, no credit card.
// introduction
Introduction
Form4API provides real-time SEC Form 4 insider trading data via a simple REST API. Every time a corporate insider — director, officer, or 10% owner — buys or sells shares, they must file Form 4 with the SEC within two business days. Form4API parses those filings continuously and surfaces the data through clean, developer-friendly endpoints. See the insider trading API overview for a high-level walkthrough of the endpoints and pricing.
Base URL
https://api.form4api.comA machine-readable OpenAPI 3.x specification is published at api.form4api.com/openapi/v1.json. Use it with Postman, openapi-generator-cli, or any OpenAPI-aware tool to scaffold a client in your language of choice. The spec stays in sync with the live API automatically.
// quickstart
Quickstart
Get your first API response in under two minutes.
Get your API key
Sign up for a free account — no credit card required. Your API key is shown immediately in the dashboard.
Install an SDK (optional)
Official SDKs for JavaScript/TypeScript and Python handle auth, retries, pagination, and type safety for you. Skip this step if you prefer raw HTTP.
npm install form4apiMake your first request
Fetch the five most recent insider transactions across all companies. Replace YOUR_API_KEY with your actual key.
curl "https://api.form4api.com/v1/transactions?per_page=5" \
-H "X-Api-Key: YOUR_API_KEY"Don't want to set up a key first? Run a live request in the playground above ↑ — real data, no key needed.
Filter by ticker and transaction type
Narrow results to purchases (P) at Apple.
curl "https://api.form4api.com/v1/transactions?ticker=AAPL&code=P&per_page=10" \
-H "X-Api-Key: YOUR_API_KEY"Paginate through large result sets
Responses are arrays. When a page returns fewer records than per_page, you've reached the end. The maximum page size is 100 for /v1/transactions and 500 for other endpoints. Both SDKs expose a paginate() method that handles this loop automatically.
# Page 1
curl "https://api.form4api.com/v1/transactions?ticker=NVDA&per_page=100&page=1" \
-H "X-Api-Key: YOUR_API_KEY"
# Page 2 (repeat until response array is shorter than per_page)
curl "https://api.form4api.com/v1/transactions?ticker=NVDA&per_page=100&page=2" \
-H "X-Api-Key: YOUR_API_KEY"Use the async client (Python)
AsyncForm4ApiClient mirrors every method of the sync client — just await each call. Use it with FastAPI, Django Async, or any asyncio-based framework.
import asyncio
from form4api import AsyncForm4ApiClient
async def main():
async with AsyncForm4ApiClient("YOUR_API_KEY") as client:
txns = await client.transactions.list(ticker="AAPL", per_page=5)
for t in txns:
print(t.insider_name, t.shares_amount, "@", t.price_per_share)
asyncio.run(main())// authentication
Authentication
All API requests must include your API key in the X-Api-Key request header. You can find your key in the dashboard.
Keep your API key secret — do not expose it in client-side JavaScript or commit it to source control. Use environment variables or a secrets manager. Form4API is built by Theodor Nielsen on 100% public SEC EDGAR data.
curl "https://api.form4api.com/v1/transactions" \
-H "X-Api-Key: YOUR_API_KEY"401 response — invalid or missing key
{
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid X-Api-Key header.",
"requestId": "req_abc123"
}
}Which SDKs are available?
Official client libraries wrap authentication and request handling for you.
pip install form4apinpm install form4api// rate-limits
Rate Limits
Each API key has two independent limits: a per-minute burst and a daily cap. Both return 429 Too Many Requests with a Retry-After header (seconds) when exceeded.
Every response also carries the per-minute window state so you can throttle proactively instead of waiting for a 429: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp, seconds, when the minute window resets).
| Plan | Requests / day | Requests / minute |
|---|---|---|
| Free | 500 | 20 |
| Pro | 50,000 | 200 |
| Business | 250,000 | 500 |
| Enterprise | Unlimited | 2,000 |
Per-minute limit exceeded (resets in seconds)
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Resets in 47 seconds.",
"requestId": "0HN9K2P4QR8S1:00000001"
}
}Daily cap exceeded (resets at midnight UTC)
{
"error": {
"code": "DAILY_LIMIT_EXCEEDED",
"message": "Daily request limit reached. Resets at midnight UTC.",
"requestId": "0HN9K2P4QR8S1:00000002"
}
}POST /v1/keys) is additionally limited to 5 requests per 10 minutes per IP address to prevent abuse. This limit does not count against your API key quota.// pagination & conventions
Pagination & conventions
Every list endpoint follows the same pagination contract — predictable across /v1/transactions, /v1/filings, /v1/insiders, /v1/companies, /v1/signals, /v1/form144, /v1/holdings, and /v1/managers. Each endpoint page references this section instead of re-stating the rules.
Query parameters
| Param | Type | Default | Notes |
|---|---|---|---|
| page | integer | 1 | 1-based page number. |
| per_page | integer | 50 | Max 100 for /v1/transactions; max 500 for other list endpoints. |
How do I know when I've reached the end?
Every list endpoint returns a JSON array. When a page returns fewer records than per_page, you've reached the end. There's no total-count header, no next cursor token, and no has_more field — the short-page signal is the contract. This keeps responses cacheable at the CDN edge (every query is just a deterministic URL) and avoids the consistency problems of cursor pagination over an actively-updated dataset.
Built-in paginate helper
Both SDKs expose a paginate() method that handles the loop for you — yields one page (an array) at a time, retries on 429, stops on the first short page. Prefer it over hand-written loops.
# Page through all NVDA insider transactions, 100 per page
curl "https://api.form4api.com/v1/transactions?ticker=NVDA&per_page=100&page=1" \
-H "X-Api-Key: YOUR_API_KEY"
curl "https://api.form4api.com/v1/transactions?ticker=NVDA&per_page=100&page=2" \
-H "X-Api-Key: YOUR_API_KEY"Other conventions
Date formatISO 8601. Date-only values (2026-01-01) are interpreted as 2026-01-01T00:00:00Z. Date filters (from / to) are inclusive.OrderingResults are returned in a deterministic descending order — typically by transactionDate, filedAt, or reportPeriod depending on the endpoint. See each endpoint's reference for specifics.Null fieldsOptional fields are null (not missing) when the underlying SEC filing did not include them.Empty resultsAn empty array ([]) with HTTP 200 — never 404 — when a query matches no rows.EncodingAll responses are UTF-8 JSON. Numbers are JSON numbers (not strings); monetary values are decimal numbers in USD.// errors
Errors
All errors use a consistent JSON envelope. The code field is a machine-readable string you can match on; the requestId can be sent to support to help diagnose issues.
Error envelope
{
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is invalid.",
"requestId": "req_7f3a9c"
}
}| HTTP | Code | Description |
|---|---|---|
| 401 | MISSING_API_KEY | No X-Api-Key header was sent. |
| 401 | INVALID_API_KEY | The API key exists but is invalid or revoked. |
| 402 | PLAN_REQUIRED | The endpoint requires a higher plan (e.g. Signals + Sentiment require Business). |
| 403 | PRO_TIER_REQUIRED | A Pro-gated filter parameter (e.g. a post-trade return filter) was used on a lower plan. |
| 404 | NOT_FOUND | The requested resource (ticker, CIK, accession number, subscription ID) does not exist. |
| 429 | RATE_LIMIT_EXCEEDED | Per-minute burst limit reached. Check the Retry-After header for seconds to wait. |
| 429 | DAILY_LIMIT_EXCEEDED | Daily request cap reached. Resets at midnight UTC. |
| 400 | INVALID_REQUEST | Request body is missing required fields (e.g. webhook url or eventTypes). |
| 400 | INVALID_EVENT_TYPE | An unrecognised event type was supplied. Valid: TransactionFiled, ClusterBuy, ClusterSell. |
| 400 | QUERY_TOO_SHORT | Name search requires at least 2 characters. |
| 400 | SUBSCRIPTION_LIMIT_EXCEEDED | Webhook subscription cap for your plan reached (Free 1, Pro 5, Business 25). See the Webhooks section for per-plan limits. |
| 400 | EXPORT_UNBOUNDED | The CSV export was called without a bounding filter (e.g. ticker or date range). Add a bound to constrain the result set. |
| 400 | INSECURE_URL | Webhook URL must use HTTPS. |
| 400 | PRIVATE_ADDRESS | Webhook URL resolves to a private or loopback address. |
| 400 | UNRESOLVABLE_HOST | Webhook URL hostname could not be resolved via DNS. |
| 400 | INVALID_RANGE | The since parameter for webhook events is more than 30 days in the past. |
// transactions
Transactions
Returns individual insider transactions parsed from Form 4 filings. Each record represents a single row in a Form 4 table — one trade by one insider at one price.
/v1/transactions| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by stock ticker symbol (e.g. AAPL, MSFT). |
| cik | string | optional | Filter by company CIK (alternative to ticker). |
| insider_cik | string | optional | Filter to transactions by a specific insider CIK. |
| code | string | optional | Filter by SEC transaction code. Common values: P (open-market purchase), S (open-market sale), A (grant/award), M (option exercise), F (tax withholding on vest/exercise), D (disposition to issuer), C (conversion), J (other acquisition or disposition), G (gift). Full list of 22 codes documented in the Glossary. |
| codes | string | optional | CSV list of transaction codes to include (e.g. P,M,A). Mutually exclusive with exclude_codes. |
| exclude_codes | string | optional | CSV list of transaction codes to exclude (e.g. F,D). Mutually exclusive with codes. |
| category | string | optional | High-level trade category preset. Values: open_market (P + S codes only), grants (A + M), derivatives (derivative-flagged rows), gifts (G), other. Composable with other filters. |
| exclude_category | string | optional | Exclude a category. Same values as category. E.g. exclude_category=derivatives removes all derivative transactions. |
| exclude_derivative | boolean | optional | If true, omit derivative-security transactions (options, warrants, convertibles). Equivalent to exclude_category=derivatives. |
| significant | boolean | optional | Preset filter for high-conviction trades: open-market only (P code), no 10b5-1 plan, no derivatives. Equivalent to category=open_market&exclude_10b5=true&exclude_derivative=true. |
| exclude_10b5 | boolean | optional | If true, omit transactions filed under a Rule 10b5-1 pre-scheduled trading plan. Useful for filtering to discretionary conviction trades only. |
| from | string | optional | Start date filter (ISO 8601, e.g. 2026-01-01). Filters by transactionDate. |
| to | string | optional | End date filter (ISO 8601). |
| min_value | number | optional | Pro only. Minimum transaction value in USD (sharesAmount × pricePerShare). Rows where totalValue is null are excluded. |
| max_value | number | optional | Pro only. Maximum transaction value in USD. |
| min_shares | number | optional | Pro only. Minimum number of shares transacted. |
| max_shares | number | optional | Pro only. Maximum number of shares transacted. |
| min_return_1d | number | optional | Pro+ only. Minimum 1-trading-day post-filing return as a decimal (e.g. 0.05 = 5%). Excludes transactions without a computed 1d return. |
| max_return_1d | number | optional | Pro+ only. Maximum 1-trading-day post-filing return. |
| min_return_1w | number | optional | Pro+ only. Minimum 1-week (5 trading days) post-filing return. |
| max_return_1w | number | optional | Pro+ only. Maximum 1-week post-filing return. |
| min_return_1m | number | optional | Pro+ only. Minimum 1-month (21 trading days) post-filing return. |
| max_return_1m | number | optional | Pro+ only. Maximum 1-month post-filing return. |
| min_return_3m | number | optional | Pro+ only. Minimum 3-month (63 trading days) post-filing return. |
| max_return_3m | number | optional | Pro+ only. Maximum 3-month post-filing return. |
| min_return_6m | number | optional | Pro+ only. Minimum 6-month (126 trading days) post-filing return. |
| max_return_6m | number | optional | Pro+ only. Maximum 6-month post-filing return. |
| has_returns | boolean | optional | Pro+ only. true = only transactions with all 5 horizons populated. false = only transactions where one or more horizons are still null. |
| per_page | number | optional | Number of results to return. Default: 50, max: 100. |
| page | number | optional | Page number for pagination. Default: 1. |
Date filters (from / to) are both inclusive, treated as UTC, and filter on transactionDate. A date-only value (e.g. 2026-01-01) is interpreted as 2026-01-01T00:00:00Z. Results are ordered by transactionDate descending.
curl "https://api.form4api.com/v1/transactions?ticker=AAPL&per_page=5" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"ticker": "AAPL",
"companyName": "Apple Inc.",
"insiderName": "Cook Timothy D",
"insiderCik": "0001214156",
"insiderTitle": "Chief Executive Officer",
"isDirector": false,
"isOfficer": true,
"is10PctOwner": false,
"accessionNumber": "0001140361-26-013190",
"securityTitle": "Common Stock",
"transactionCode": "S",
"isOpenMarket": true,
"is10b5Plan": false,
"sharesAmount": 5087,
"pricePerShare": 251.25,
"totalValue": 1278153.75,
"sharesOwnedAfter": 3340280,
"directIndirect": "D",
"isDerivative": false,
"transactionDate": "2026-04-02T00:00:00Z",
"periodOfReport": "2026-04-01T00:00:00Z",
"return1d": 0.0124,
"return1w": 0.0237,
"return1m": 0.0418,
"return3m": 0.1156,
"return6m": 0.1842
}
]isOpenMarkettrue only when transactionCode is P (purchase) or S (sale). All other codes — option exercises, awards, tax withholding — return false.is10b5Plantrue when the trade was filed under a Rule 10b5-1 pre-scheduled trading plan. These trades are automatic and carry no conviction signal. Use ?exclude_10b5=true to omit them from results.insiderTitleOfficer title as reported on the Form 4 (e.g. "Chief Executive Officer"). null when not disclosed.isDirector / isOfficer / is10PctOwnerRelationship flags from the Form 4 header. An insider may have more than one role (e.g. a founder who is both CEO and 10% owner).totalValuesharesAmount × pricePerShare in USD. null when pricePerShare is null (common for grants and option exercises).directIndirect"D" = directly owned. "I" = indirectly owned (via trust, spouse, or other entity).isDerivativetrue when the security is a derivative (option, warrant, convertible). Derivative transactions report shares underlying the instrument, not shares directly transferred.periodOfReportThe date the Form 4 covers — typically the same as transactionDate, but may differ for deferred or reportable transactions.return1d / 1w / 1m / 3m / 6mStock return at 1 / 5 / 21 / 63 / 126 trading days after the filing date, as a decimal (0.05 = +5%). Anchored on the first market close at or after filedAt, split-adjusted via Yahoo Finance daily bars. null when the horizon hasn't been reached yet (e.g. a 4-month-old filing has no return6m) or the ticker has no price data on file. All horizons populated within ~6 months of any filing.How are Form 4/A amendments handled?
When an insider files an amendment to a previously-filed Form 4 (designated Form 4/A), they're correcting an error in the original — typically a wrong share count, a wrong transaction code, or a missing transaction. Naive ingestion pipelines treat the amendment as a new filing, which silently double-counts the transaction in downstream analytics. Form4API's parser detects the amendment relationship via the EDGAR accession-number link, retires the original transaction, applies the corrected values in place, and exposes a single canonical record at /v1/transactions with an isAmended flag and a reference to the original accession number.
Cluster signals, sentiment, post-trade returns, and any aggregations you build on top automatically use the corrected data. No reconciliation logic is required in your code — the API guarantees exactly one transaction record per real-world event regardless of how many amendments the insider files.
isAmendedtrue when this record was rewritten from a Form 4/A. false when the original Form 4 was the final version.amendedFromAccessionNumberOriginal Form 4 accession the amendment supersedes. null when isAmended is false.// quality filters (free)
Use significant=true to get only high-conviction open-market buys — no 10b5-1 plans, no derivatives. Equivalent to combining category=open_market&exclude_10b5=true&exclude_derivative=true.
/v1/transactions?significant=true&from=2026-01-01// pro tier
Size filtering (min_value, max_value, min_shares, max_shares) and return screening (min_return_*, max_return_*, has_returns) require the Pro plan or higher.
Response fields are visible on every tier — only the filter parameters are gated. Free-tier requests with any gated filter return 403 PRO_TIER_REQUIRED.
Example — significant open-market buys over $1M where the stock was up >20% three months later:
/v1/transactions?significant=true&min_value=1000000&min_return_3m=0.20// filings
Filings
Returns Form 4 filing headers. Use these endpoints when you need filing-level metadata such as the accession number, filed timestamp, and period of report. To get the underlying transactions, use /v1/transactions.
/v1/filings/recentReturns the most recent Form 4 filings across all companies.
| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by company ticker (e.g. AAPL). |
| per_page | number | optional | Number of results to return. Default: 20, max: 100. |
curl "https://api.form4api.com/v1/filings/recent?per_page=10" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"accessionNumber": "0001140361-26-019658",
"companyTicker": "GYRE",
"companyName": "GYRE THERAPEUTICS, INC.",
"periodOfReport": "2026-05-05T00:00:00Z",
"filedAt": "2026-05-08T02:02:09Z",
"amendmentType": "Original",
"transactionCount": 2
}
]/v1/filings/{accession}Returns a single filing by its SEC accession number, including a count of its transactions. To retrieve the transactions themselves use /v1/transactions.
curl "https://api.form4api.com/v1/filings/0001209191-26-034821" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"accessionNumber": "0001140361-26-017175",
"companyTicker": "AAPL",
"companyName": "Apple Inc.",
"periodOfReport": "2026-04-23T00:00:00Z",
"filedAt": "2026-05-04T07:01:02Z",
"amendmentType": "Original",
"transactionCount": 1
}// insiders
Insiders
Search for individual insiders (directors, officers, 10%+ owners) by name, fetch a single insider profile by CIK, or retrieve their complete trade history.
/v1/insidersSearch insiders by name. Returns a paginated list.
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | optional | Partial name match (case-insensitive, minimum 2 characters). E.g. "cook" matches "Cook Timothy D". Returns 400 QUERY_TOO_SHORT if fewer than 2 characters are supplied. |
| per_page | number | optional | Number of results per page. Default: 20, max: 100. |
| page | number | optional | Page number for pagination. Default: 1. |
curl "https://api.form4api.com/v1/insiders?name=cook" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"cik": "0001214128",
"name": "Cook Timothy D",
"isDirector": true,
"isOfficer": true,
"isTenPercentOwner": false,
"officerTitle": "Chief Executive Officer",
"totalFilings": 48
}
]/v1/insiders/{cik}Fetch a single insider profile by their SEC CIK number. The CIK is returned by the list endpoint and by any transaction record.
curl "https://api.form4api.com/v1/insiders/0001214128" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"cik": "0001214128",
"name": "Cook Timothy D",
"isDirector": true,
"isOfficer": true,
"isTenPercentOwner": false,
"officerTitle": "Chief Executive Officer",
"totalFilings": 48
}/v1/insiders/{cik}/transactionsReturns all Form 4 transactions filed by this insider, newest first. Supports date range filtering and pagination.
| Name | Type | Required | Description |
|---|---|---|---|
| from | string | optional | Start date (ISO 8601, e.g. 2026-01-01). Filters by transactionDate. |
| to | string | optional | End date (ISO 8601). |
| page | number | optional | Page number. Default: 1. |
| per_page | number | optional | Results per page. Default: 50, max: 100. |
curl "https://api.form4api.com/v1/insiders/0001214128/transactions?per_page=10" \
-H "X-Api-Key: YOUR_API_KEY"/v1/insiders/{cik}/summaryPro+One-call aggregate of this insider's entire career: total bought / sold USD, net flow, top companies by transaction count, transaction-code breakdown (P/S/F/M/A/G), 10b5-1 vs discretionary split, and post-trade return averages (discretionary open-market trades only — 10b5-1 plan trades and grants/exercises excluded for cleaner signal). Saves you a loop over /transactions when you need career-level analytics rather than the trade ledger.
curl "https://api.form4api.com/v1/insiders/0001214128/summary" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"cik": "0001214128",
"name": "Cook Timothy D",
"officerTitle": "Chief Executive Officer",
"isDirector": true,
"isOfficer": true,
"isTenPercentOwner": false,
"career": {
"firstTransaction": "2011-09-09T00:00:00Z",
"lastTransaction": "2026-04-30T00:00:00Z",
"totalTransactions": 142,
"totalBoughtUsd": 0,
"totalSoldUsd": 821345670.00,
"netUsd": -821345670.00,
"companies": [
{ "ticker": "AAPL", "companyName": "Apple Inc.", "transactionCount": 142, "firstAtCompany": "2011-09-09T00:00:00Z" }
],
"transactionTypeBreakdown": {
"P": 0, "S": 78, "F": 12, "M": 36, "A": 14, "G": 0, "Other": 2
},
"tenB5Plan": {
"totalUnderPlan": 64,
"totalDiscretionary": 14,
"pctUnder10b5Plan": 45.07
},
"returns": {
"openMarketTransactionsWithReturns": 78,
"avgReturn1d": 0.0021,
"avgReturn1w": 0.0114,
"avgReturn1m": 0.0327,
"avgReturn3m": 0.0865,
"avgReturn6m": 0.1542
}
}
}/v1/insiders/{cik}/scorecardProPredictive track record for a single insider: hit rate (fraction of open-market buys with a positive absolute return after 3 months), average and median 3-month and 6-month returns, best and worst single buy, and a scored-buy count. Useful for ranking insiders by historical signal quality before acting on a new filing. Requires at least 5 matured discretionary open-market buys — returns sampleSufficient: false otherwise (field values are null; do not infer signal from insufficient data).
curl "https://api.form4api.com/v1/insiders/0001214128/scorecard" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"insiderCik": "0001214128",
"insiderName": "Cook Timothy D",
"scoredBuyCount": 12,
"sampleSufficient": true,
"hitRate3m": 0.75,
"avgReturn3m": 0.112,
"medianReturn3m": 0.084,
"scoredBuyCount6m": 10,
"sampleSufficient6m": true,
"hitRate6m": 0.70,
"avgReturn6m": 0.198,
"medianReturn6m": 0.153,
"bestBuy": {
"ticker": "AAPL",
"filedAt": "2019-08-14T00:00:00Z",
"return3m": 0.412
},
"worstBuy": {
"ticker": "AAPL",
"filedAt": "2022-02-01T00:00:00Z",
"return3m": -0.218
},
"lastTradeAt": "2024-11-01T00:00:00Z",
"methodology": "absolute-return-v1"
}/v1/insiders/leaderboardBusinessRanked list of insiders sorted by 3-month hit rate descending, limited to those with sampleSufficient: true. Useful for building a watchlist of historically accurate insiders, or weighting a cluster-buy signal by participant quality. Accepts per_page (default 20, max 100) and page. Each row is the same shape as the scorecard response.
/scorecard above: absolute return, not market-adjusted. Rankings are a historical signal, not a forward guarantee.curl "https://api.form4api.com/v1/insiders/leaderboard?per_page=10" \
-H "X-Api-Key: YOUR_API_KEY"// companies
Companies
Look up a company by ticker to get its SEC profile and the list of registered insiders who have filed Form 4 for that company.
/v1/companiesReturns a list of companies, optionally sorted and limited.
| Name | Type | Required | Description |
|---|---|---|---|
| sort | string | optional | Sort order. Accepted values: name (alphabetical, default) or totalFilings (most-filed first). |
| limit | integer | optional | Maximum number of results to return. Default 100. |
curl "https://api.form4api.com/v1/companies?sort=totalFilings&limit=10" \
-H "X-Api-Key: YOUR_API_KEY"/v1/companies/{ticker}Returns the SEC profile for a company.
| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | required | The company ticker symbol (path parameter). |
curl "https://api.form4api.com/v1/companies/AAPL" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"cik": "0000320193",
"name": "Apple Inc.",
"ticker": "AAPL",
"exchange": "Nasdaq",
"totalFilings": 119,
"activeInsiders": 19,
"sicDescription": "Electronic Computers",
"stateOfIncorporation": "CA",
"website": null
}sicDescriptionSEC SIC industry description (e.g. "Electronic Computers"). null when not available.stateOfIncorporationTwo-letter US state code where the company is incorporated (e.g. "CA", "DE"). null for foreign issuers.websiteCompany website URL as filed with the SEC. null when not disclosed.activeInsidersNumber of distinct insiders who have filed at least one Form 4 for this company./v1/companies/{ticker}/insidersReturns all insiders who have filed Form 4 for this company, with their CIK and most recent transaction date.
| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | required | The company ticker symbol (path parameter). |
curl "https://api.form4api.com/v1/companies/AAPL/insiders" \
-H "X-Api-Key: YOUR_API_KEY"// signals
Signals
Signals surface statistically notable insider activity. A cluster buy is triggered when 3 or more distinct insiders at the same company file open-market purchases (code P) within a rolling 5-day window ending on the filing date. A cluster sell follows the same rule for sales (code S). Option exercises, grants, and tax withholdings do not count toward the cluster threshold. Pre-scheduled trades filed under a Rule 10b5-1 plan are also excluded — these carry no conviction signal.
One signal record is stored per company per day and is updated each time a new filing for that company is processed. Signals are ordered by signalDate descending.
402 PLAN_REQUIRED error./v1/signals| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by company ticker (e.g. NVDA). |
| cluster_buy | boolean | optional | If true, return only signals where a cluster buy is active. |
| cluster_sell | boolean | optional | If true, return only signals where a cluster sell is active. |
| page | number | optional | Page number. Default: 1. |
| per_page | number | optional | Results per page. Default: 100, max: 500. |
curl "https://api.form4api.com/v1/signals?cluster_buy=true&per_page=5" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"ticker": "OPCH",
"companyName": "Option Care Health, Inc.",
"signalDate": "2026-05-07T00:00:00Z",
"buySellRatio": 2.47,
"isClusterBuy": true,
"isClusterSell": false,
"insiderCount": 11
}
]buySellRatioTotal shares purchased ÷ total shares sold by all insiders over the past 90 days. Capped at 99 when there are buys but no sells.insiderCountNumber of distinct insiders who filed any transaction for this company in the past 90 days — not just those who contributed to the cluster trigger.signalDateThe date the triggering Form 4 was filed with the SEC, not the transaction date.402 response — plan too low
{
"error": {
"code": "PLAN_REQUIRED",
"message": "This endpoint requires the Business plan or higher. Your current plan is Free.",
"requestId": "req_7f3a9c"
}
}How is the insider sentiment score calculated?
Monthly insider sentiment score for a ticker, computed MSPR-style: (buyValue − sellValue) / (buyValue + sellValue) × 100, clamped to ±100. Positive = net buying conviction; negative = net selling.
Our score uses only open-market transactions (codes P and S), excluding 10b5-1 plan trades, option exercises, grants, and tax withholdings. Pre-scheduled 10b5-1 sales carry no conviction signal, so leaving them in pollutes the score — this is the key differentiator vs other vendors' MSPR. Months with no qualifying transactions are omitted from the array; clients that want a dense time series can zero-fill on their side.
/v1/signals/sentiment/{ticker}| Name | Type | Required | Description |
|---|---|---|---|
| months | number | optional | Months of history to return. Default: 24, min: 1, max: 60. |
curl "https://api.form4api.com/v1/signals/sentiment/NVDA?months=6" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"ticker": "NVDA",
"companyName": "NVIDIA Corporation",
"monthly": [
{
"period": "2026-05",
"score": -82.5,
"buyValue": 250000.00,
"sellValue": 2580000.00,
"buyCount": 1,
"sellCount": 4
},
{
"period": "2026-04",
"score": 12.7,
"buyValue": 1100000.00,
"sellValue": 850000.00,
"buyCount": 3,
"sellCount": 2
}
]
}// form-144
Form 144
Form 144 is the SEC notice of proposed sale — insiders must file it before selling restricted or control securities above the 5,000-share or $50,000 / 3-month threshold. The actual sale shows up later in Form 4, typically within a few days.
This makes Form 144 a leading indicator: you see the intent to sell before the trade prints. The isUnder10b5Plan flag separates pre-scheduled disposition (low signal) from discretionary intent (higher signal) — derived from the planAdoptionDates element in the filing.
Unlike Form 4, Form 144 carries the insider as plain text only — there is no CIK on the insider field. Use insider_name as a forgiving ILIKE substring (matches cook against Timothy D Cook or COOK, TIM).
402 PLAN_REQUIRED error./v1/form144| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by company ticker (e.g. NVDA). |
| insider_name | string | optional | Case-insensitive substring match on the insider's name as filed. |
| from | date | optional | Only return notices filed on or after this date (UTC). |
| to | date | optional | Only return notices filed on or before this date (UTC). |
| exclude_10b5 | boolean | optional | If true, omit notices filed under a 10b5-1 plan. |
| page | number | optional | Page number. Default: 1. |
| per_page | number | optional | Results per page. Default: 50, max: 100. |
curl "https://api.form4api.com/v1/form144?ticker=NVDA&exclude_10b5=true&per_page=5" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"accessionNumber": "0001950047-26-003316",
"ticker": "NVDA",
"companyName": "NVIDIA Corporation",
"insiderName": "Huang Jen Hsun",
"relationship": "Director / Officer",
"broker": "Charles Schwab",
"sharesProposed": 120000,
"aggregateMarketValue": 24500000.00,
"approxSaleDate": "2026-06-03",
"exchange": "NASDAQ",
"acquiredDate": "2019-12-12",
"natureOfAcquisition": "Founders Shares",
"isUnder10b5Plan": false,
"filedAt": "2026-05-21T00:00:00Z",
"noticeDate": "2026-05-21"
}
]sharesProposedFrom the filing's noOfUnitsSold field (despite the name, this is the proposed quantity, not the executed one).isUnder10b5PlanTrue when the notice references a 10b5-1 plan adoption. Lets you separate discretionary intent from pre-scheduled sales.approxSaleDateInsider's stated expected sale date. Filings dated MM/DD/YYYY are normalised to UTC midnight.acquiredDateWhen the insider originally acquired the shares — often years before this notice.402 response — plan too low
{
"error": {
"code": "PLAN_REQUIRED",
"message": "This endpoint requires the Business plan or higher. Your current plan is Free.",
"requestId": "req_7f3a9c"
}
}// transactions-export
Transactions Export
Streams a bulk RFC 4180 CSV of Form 4 insider transactions. Accepts the same filter grammar as GET /v1/transactions but returns a CSV file rather than paginated JSON. Use this endpoint when you need a full dataset for backtesting, spreadsheet analysis, or bulk ingestion.
402 PLAN_REQUIRED error.Bounded request required. At least one of ticker, cik, insider_cik, or from must be provided. Requests without any bounding parameter return 400 EXPORT_UNBOUNDED.
Hard cap: 100,000 rows per request. For full history, chunk by date range (e.g. one calendar year at a time). Rows stream in ascending filedAt order.
Use filedAt, not transactionDate, for backtesting. A Form 4 must be filed within 2 business days of the trade. Filtering on transactionDate leaks lookahead bias because you would not have known about the trade until it was filed. The from / to parameters on this endpoint filter on filedAt, not transactionDate. See the backtesting guide for a worked example.
/v1/transactions/export| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by stock ticker symbol (e.g. AAPL). One of ticker, cik, insider_cik, or from is required. |
| cik | string | optional | Filter by company CIK. One of ticker, cik, insider_cik, or from is required. |
| insider_cik | string | optional | Filter to transactions by a specific insider CIK. One of ticker, cik, insider_cik, or from is required. |
| code | string | optional | Filter by SEC transaction code (e.g. P, S, A, M). |
| codes | string | optional | CSV list of transaction codes to include (e.g. P,M,A). Mutually exclusive with exclude_codes. |
| exclude_codes | string | optional | CSV list of transaction codes to exclude (e.g. F,D). Mutually exclusive with codes. |
| category | string | optional | High-level trade category preset: open_market, grants, derivatives, gifts, other. |
| exclude_category | string | optional | Exclude a category. Same values as category. |
| exclude_derivative | boolean | optional | If true, omit derivative-security transactions (options, warrants, convertibles). |
| significant | boolean | optional | Preset: open-market only, no 10b5-1 plan, no derivatives. Equivalent to category=open_market&exclude_10b5=true&exclude_derivative=true. |
| exclude_10b5 | boolean | optional | If true, omit transactions filed under a Rule 10b5-1 pre-scheduled trading plan. |
| from | date | optional | Start date filter (ISO 8601, e.g. 2020-01-01). Filters by filedAt. One of ticker, cik, insider_cik, or from is required. |
| to | date | optional | End date filter (ISO 8601). Filters by filedAt. Inclusive, UTC. |
| min_value | number | optional | Pro only. Minimum transaction value in USD. |
| max_value | number | optional | Pro only. Maximum transaction value in USD. |
| min_shares | number | optional | Pro only. Minimum number of shares transacted. |
| max_shares | number | optional | Pro only. Maximum number of shares transacted. |
| min_return_1d | number | optional | Pro+ only. Minimum 1-trading-day post-filing return as a decimal (e.g. 0.05 = 5%). |
| max_return_1d | number | optional | Pro+ only. Maximum 1-trading-day post-filing return. |
| min_return_1w | number | optional | Pro+ only. Minimum 1-week post-filing return. |
| max_return_1w | number | optional | Pro+ only. Maximum 1-week post-filing return. |
| min_return_1m | number | optional | Pro+ only. Minimum 1-month post-filing return. |
| max_return_1m | number | optional | Pro+ only. Maximum 1-month post-filing return. |
| min_return_3m | number | optional | Pro+ only. Minimum 3-month post-filing return. |
| max_return_3m | number | optional | Pro+ only. Maximum 3-month post-filing return. |
| min_return_6m | number | optional | Pro+ only. Minimum 6-month post-filing return. |
| max_return_6m | number | optional | Pro+ only. Maximum 6-month post-filing return. |
| has_returns | boolean | optional | Pro+ only. true = only transactions with all 5 return horizons populated. |
| inst_ownership_trend | string | optional | Filter by institutional ownership trend. Values: rising, falling, stable. |
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://api.form4api.com/v1/transactions/export?ticker=AAPL&from=2020-01-01&to=2024-12-31" \
-o aapl-insider.csvCSV columns (27)
filedAt,transactionDate,ticker,companyName,insiderName,insiderCik,insiderTitle,isDirector,isOfficer,isTenPercentOwner,transactionCode,isBuyOrSell,isDerivative,is10b5Plan,securityTitle,sharesAmount,pricePerShare,value,sharesOwnedAfter,directOrIndirect,accessionNumber,periodOfReport,return1d,return1w,return1m,return3m,return6mfiledAtISO 8601 UTC timestamp of when the Form 4 was filed with the SEC. Use this column as your event timestamp for backtesting - not transactionDate.isBuyOrSelltrue when transactionCode is P (purchase) or S (sale) - i.e. an open-market trade.directOrIndirectD = directly owned. I = indirectly owned (via trust, spouse, or other entity).valuesharesAmount × pricePerShare in USD. Empty when pricePerShare is null (common for grants and option exercises).return1d ... return6mPost-filing stock return at 1 / 5 / 21 / 63 / 126 trading days as a decimal (e.g. 0.05 = +5%). Empty when the horizon has not been reached yet or the ticker has no price data.400 response - missing bound
{
"error": {
"code": "EXPORT_UNBOUNDED",
"message": "At least one of ticker, cik, insider_cik, or from is required for export requests.",
"requestId": "req_8c2b1d"
}
}// form-144-export
Form 144 Export
Streams a bulk RFC 4180 CSV of Form 144 notice-of-proposed-sale filings. Accepts the same filter grammar as GET /v1/form144 but returns a CSV file rather than paginated JSON. Use this endpoint to build offline datasets, backtest leading-indicator strategies, or track proposed-sale history across a watchlist.
402 PLAN_REQUIRED error.Bounded request required. At least one of ticker, insider_name, or from must be provided. Requests without any bounding parameter return 400 EXPORT_UNBOUNDED.
Hard cap: 100,000 rows per request. For full history, chunk by date range (e.g. one calendar year at a time). Rows stream in ascending filedAt order.
/v1/form144/export| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter by company ticker (e.g. NVDA). One of ticker, insider_name, or from is required. |
| insider_name | string | optional | Case-insensitive substring match on the insider's name as filed. One of ticker, insider_name, or from is required. |
| from | date | optional | Start date filter (ISO 8601). Filters by filedAt. One of ticker, insider_name, or from is required. |
| to | date | optional | End date filter (ISO 8601). Filters by filedAt. Inclusive, UTC. |
| exclude_10b5 | boolean | optional | If true, omit notices filed under a 10b5-1 plan. |
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://api.form4api.com/v1/form144/export?ticker=NVDA&from=2020-01-01&to=2024-12-31" \
-o nvda-form144.csvCSV columns (15)
filedAt,noticeDate,ticker,companyName,insiderName,relationship,brokerName,sharesProposed,aggregateMarketValue,approxSaleDate,exchange,acquiredDate,natureOfAcquisition,isUnder10b5Plan,accessionNumberfiledAtISO 8601 UTC timestamp of when the Form 144 was filed with the SEC. Use this as the event timestamp for leading-indicator strategies.noticeDateThe date of the notice as stated on the filing, normalised to YYYY-MM-DD.sharesProposedThe number of shares the insider proposes to sell. This is an intent figure, not a confirmed execution.aggregateMarketValueEstimated market value of the proposed sale at the time of filing, in USD.approxSaleDateThe insider's stated expected sale date. Filings with MM/DD/YYYY format are normalised to YYYY-MM-DD.isUnder10b5Plantrue when the notice references a 10b5-1 plan. Use exclude_10b5=true to omit these and focus on discretionary intent.acquiredDateWhen the insider originally acquired the shares proposed for sale.400 response - missing bound
{
"error": {
"code": "EXPORT_UNBOUNDED",
"message": "At least one of ticker, insider_name, or from is required for export requests.",
"requestId": "req_9a3e4f"
}
}// holdings
Institutional Holdings (13F-HR)
Quarterly Form 13F-HR holdings filed by institutional investment managers with discretion over more than $100M in 13F-eligible equity securities. Filed within 45 days of quarter end (so Q1 holdings land mid-May, Q2 mid-August, etc.).
Each row is one position. A single security can appear multiple times in one filing when the manager attributes shares across sub-managers — Berkshire, for instance, lists each security up to 14 times, once per subsidiary insurance company.
Use cusip when you need exact security matching across all filers (the only stable cross-filing identifier). Use ticker for issuer-side queries — this resolves via the issuer CIK and only covers issuers we already track from Form 4, so coverage is high for US large-caps but partial for ETFs and bonds.
/v1/holdings and /v1/managers require the Business or Enterprise plan. Free and Pro keys receive a 402 PLAN_REQUIRED error./v1/holdings| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | optional | Filter to a specific issuer ticker (e.g. NVDA). Resolves via the issuer CIK — only matches holdings where the underlying company is in our database. |
| cusip | string | optional | Exact 9-character CUSIP match. Use this when you need 100% coverage (some issuers don't have a Form-4-mapped ticker). |
| manager_cik | string | optional | Filter by filing manager CIK (e.g. 1067983 for Berkshire). Leading zeros optional. |
| quarter | date | optional | Filter to a specific report period (always a quarter-end date, e.g. 2026-03-31). |
| min_value | number | optional | Minimum USD value of the position. Filters out small holdings. |
| page | number | optional | Page number. Default: 1. |
| per_page | number | optional | Results per page. Default: 50, max: 100. |
curl "https://api.form4api.com/v1/holdings?manager_cik=1067983&per_page=3" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"manager": "Berkshire Hathaway Inc",
"managerCik": "1067983",
"reportPeriod": "2026-03-31T00:00:00Z",
"issuerName": "APPLE INC",
"ticker": "AAPL",
"cusip": "037833100",
"titleOfClass": "COM",
"value": 91234567890,
"shares": 300000000,
"shareType": "SH",
"investmentDiscretion": "SOLE",
"votingSole": 300000000,
"votingShared": 0,
"votingNone": 0,
"accessionNumber": "0001193125-26-226661",
"filedAt": "2026-05-15T00:00:00Z"
}
]valuePosition value in USD. Per the SEC's 2020 amendment, this is dollars (not thousands). Older historical filings used thousands; we backfill only post-amendment data.shareTypeSH = share count. PRN = principal amount (for bonds / convertibles).investmentDiscretionSOLE = manager has sole discretion. DFND = defined / shared with another party. OTR = other.tickerMay be null when we couldn't resolve the issuer's CUSIP to an issuer in our database (ETFs, foreign ADRs, less-followed issuers). The cusip field is always populated.Which 13F managers does the index cover?
Summary view of every 13F-HR filer, returning the latest filing per manager with aggregate AUM and position count. Useful for discovery ("who are the biggest institutional filers?") and ranking ("rank holders of AAPL by AUM").
/v1/managers| Name | Type | Required | Description |
|---|---|---|---|
| name | string | optional | Case-insensitive substring match on the manager name as filed (e.g. "berkshire" matches "Berkshire Hathaway Inc"). |
| min_aum | number | optional | Minimum total reported AUM in USD. Filters out smaller funds. |
| page | number | optional | Page number. Default: 1. |
| per_page | number | optional | Results per page. Default: 50, max: 100. |
curl "https://api.form4api.com/v1/managers?min_aum=100000000000&per_page=5" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"name": "Berkshire Hathaway Inc",
"cik": "1067983",
"latestReportPeriod": "2026-03-31T00:00:00Z",
"latestAum": 263095703570,
"latestPositionCount": 90,
"latestFiledAt": "2026-05-15T00:00:00Z",
"latestAccessionNumber": "0001193125-26-226661"
}
]402 response — plan too low
{
"error": {
"code": "PLAN_REQUIRED",
"message": "This endpoint requires the Business plan or higher. Your current plan is Free.",
"requestId": "req_7f3a9c"
}
}// webhooks
Webhooks
Subscribe to real-time events instead of polling. When a matching event fires, Form4API POSTs a JSON payload to your endpoint within seconds of the SEC publishing the filing. Each delivery is signed with X-Insider-Signature so you can verify it came from us.
/v1/webhooksCreate a new webhook subscription. The signing secret is returned once — store it immediately. Subscription caps are tier-dependent; Free-tier subscriptions are flagged isReadOnly: true and cannot be modified after creation.
| Plan | Active subscriptions |
|---|---|
| Free | 1 (read-only) |
| Pro | 5 |
| Business | 25 |
| Enterprise | Unlimited |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | required | HTTPS endpoint that will receive webhook payloads. Must be publicly reachable. |
| eventTypes | string[] | required | Array of event types to subscribe to. Valid values: TransactionFiled, ClusterBuy, ClusterSell. |
Response
| Name | Type | Required | Description |
|---|---|---|---|
| subscriptionId | number | optional | Unique subscription ID. Use this to delete the webhook. |
| secret | string | optional | Signing secret — shown once only. Store it securely to verify X-Insider-Signature. |
| url | string | optional | The endpoint URL. |
| eventTypes | string[] | optional | Subscribed event types. |
| isReadOnly | boolean | optional | True for Free-tier subscriptions — they receive events but cannot be modified after creation. |
| warning | string | optional | Reminder that the secret will not be returned again. |
curl -X POST "https://api.form4api.com/v1/webhooks" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/form4",
"eventTypes": ["TransactionFiled", "ClusterBuy"]
}'/v1/webhooksList all webhook subscriptions for your API key. Secrets are never returned in this response.
curl "https://api.form4api.com/v1/webhooks" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"subscriptionId": 42,
"url": "https://yourapp.com/webhooks/form4",
"eventTypes": ["TransactionFiled", "ClusterBuy"],
"createdAt": "2026-05-01T10:00:00Z",
"isActive": true
}
]/v1/webhooks/{id}Delete a webhook subscription by its numeric ID. Returns 204 No Content on success, or 404 NOT_FOUND if the ID doesn't exist or belongs to a different key.
curl -X DELETE "https://api.form4api.com/v1/webhooks/42" \
-H "X-Api-Key: YOUR_API_KEY"
# Returns 204 No Content on success/v1/webhooks/eventsReturns up to 500 delivery records from the last 24 hours by default. Use the optional since parameter (ISO 8601) to replay from a specific timestamp — up to 30 days back. Useful for catching missed deliveries after a planned outage.
curl "https://api.form4api.com/v1/webhooks/events" \
-H "X-Api-Key: YOUR_API_KEY"
# Replay from a specific point in time (up to 30 days back)
curl "https://api.form4api.com/v1/webhooks/events?since=2026-05-01T00:00:00Z" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"deliveryId": 1042,
"subscriptionId": 7,
"eventType": "TransactionFiled",
"attemptCount": 1,
"deliveredAt": "2026-05-04T14:23:11Z",
"nextRetryAt": null,
"lastStatusCode": 200,
"isDead": false,
"payload": { "filingId": 123, "accessionNumber": "0001140361-26-017175" }
}
]How do webhook event payloads look?
Every webhook POST has a top-level type field and a data object whose shape depends on the event type.
{
"type": "TransactionFiled",
"data": {
"ticker": "AAPL",
"companyName": "Apple Inc.",
"insiderName": "Cook Timothy D",
"insiderTitle": "Chief Executive Officer",
"isDirector": false,
"isOfficer": true,
"is10PctOwner": false,
"transactionCode": "S",
"isOpenMarket": true,
"is10b5Plan": false,
"sharesAmount": 10000,
"pricePerShare": 212.45,
"totalValue": 2124500.00,
"transactionDate": "2026-04-30T00:00:00Z"
}
}How do I verify webhook signatures?
Each request includes an X-Insider-Signature header with the value sha256=<hex> — HMAC-SHA256 of the raw request body signed with your subscription secret. Always verify before processing.
import crypto from 'crypto'
export async function POST(req: Request) {
const body = await req.text()
const sig = req.headers.get('X-Insider-Signature') ?? ''
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET!)
.update(body)
.digest('hex')
if (sig !== expected) {
return new Response('Invalid signature', { status: 401 })
}
const event = JSON.parse(body)
// handle event.type: 'TransactionFiled' | 'ClusterBuy' | 'ClusterSell'
return new Response('ok', { status: 200 })
}// usage
Usage
Check your current quota, view daily request history, and inspect recent API calls — all from your own API key without needing to log into the dashboard.
/v1/keys/usageReturns your current plan, how many requests you have made today, your daily limit, and when the counter resets (midnight UTC).
curl "https://api.form4api.com/v1/keys/usage" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"plan": "Free",
"requestsToday": 42,
"dailyLimit": 500,
"requestsThisMonth": 842,
"resetAt": "2026-05-16T00:00:00Z"
}/v1/keys/usage/historyReturns a daily breakdown of request counts. Useful for tracking usage trends or building your own monitoring dashboard. Dates are UTC; days with zero requests are omitted.
| Name | Type | Required | Description |
|---|---|---|---|
| days | number | optional | Number of days to include. Default: 30, max: 90. |
curl "https://api.form4api.com/v1/keys/usage/history?days=7" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{ "date": "2026-05-15", "count": 42 },
{ "date": "2026-05-14", "count": 318 },
{ "date": "2026-05-13", "count": 204 }
]/v1/keys/usage/activityReturns your most recent API requests with endpoint, HTTP status, and duration. Useful for debugging integration issues or auditing unexpected usage. Logs are retained for 90 days.
| Name | Type | Required | Description |
|---|---|---|---|
| limit | number | optional | Number of recent requests to return. Default: 100, max: 200. |
curl "https://api.form4api.com/v1/keys/usage/activity?limit=5" \
-H "X-Api-Key: YOUR_API_KEY"Response
[
{
"endpoint": "/v1/transactions",
"statusCode": 200,
"durationMs": 4,
"createdAt": "2026-05-15T07:31:22Z"
},
{
"endpoint": "/v1/companies/AAPL",
"statusCode": 200,
"durationMs": 3,
"createdAt": "2026-05-15T07:31:18Z"
}
]// billing
Billing
Programmatically generate a Stripe checkout URL to upgrade your plan. The endpoint requires a valid API key and returns a one-time checkout session URL. Redirect the user to this URL to complete payment. See pricing for plan limits and prices.
/v1/billing/checkout| Param | In | Values |
|---|---|---|
| plan | query | Pro | Business | Enterprise |
curl -X POST "https://api.form4api.com/v1/billing/checkout?plan=Pro" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_..."
}/v1/billing/portalCreates a Stripe Customer Portal session for managing an existing subscription — cancel, change plan, update payment method. Requires an active paid subscription. Returns a one-time portal URL; redirect the user to it.
curl -X POST "https://api.form4api.com/v1/billing/portal" \
-H "X-Api-Key: YOUR_API_KEY"Response
{
"portalUrl": "https://billing.stripe.com/session/..."
}// mcp
MCP / AI Assistants
The form4api-mcp package wraps the Form4API REST API as an MCP (Model Context Protocol) server. Once configured, any MCP-compatible AI assistant — Claude Desktop, Claude Code, Cursor, Windsurf, Zed — can call Form4API directly without you writing any code.
How do I install and configure the MCP server?
The server runs via npx — no global install needed. Add it to your client's config file and restart the client.
# Claude Desktop — claude_desktop_config.json
# macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
# Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"form4api": {
"command": "npx",
"args": ["-y", "form4api-mcp"],
"env": {
"FORM4API_KEY": "fapi_live_your_key_here"
}
}
}
}Get your FORM4API_KEY from the dashboard (free, no credit card).
Which MCP tools are available? (23)
| Tool | Description |
|---|---|
| Form 4 insider trading | |
| get_transactions | Search insider transactions — filter by ticker, insider, date range, transaction codes or whole categories (exclude_category=derivatives), 10b5-1 plan trades, or use significant=true for real discretionary buys/sells only. Pro adds trade-size screening (min_value, min_shares). |
| get_recent_filings | Most recent Form 4 filings, optionally filtered by ticker. |
| get_filing | Single filing by SEC accession number. |
| get_insider_profile | Insider profile — name, title, director/officer/10% owner flags. |
| get_insider_transactions | All transactions for a specific insider by CIK. |
| get_company_overview | Company profile — name, CIK, SIC sector, state, website, filing counts. |
| get_company_insiders | All insiders who have filed Form 4s for a company. |
| list_companies | List companies sorted by name or filing count. |
| get_insider_career_summary | Aggregate career rollup: total bought/sold, top companies, 10b5-1 split, return averages. (Pro plan+) |
| get_insider_scorecard | Buy track-record scorecard for an insider (CIK) — hit rate and avg/median 3m/6m return on discretionary open-market buys; null when fewer than 5 matured samples. (Pro plan+) |
| get_insider_leaderboard | Top insiders ranked by hit rate or avg return; filter by horizon (3m/6m), min_trades, and limit. (Business plan+) |
| Signals + sentiment | |
| get_signals | Cluster buy/sell signals — multiple insiders at the same company in the same direction; 10b5-1 trades excluded. (Business plan+) |
| get_sentiment | MSPR-style monthly sentiment score per ticker (−100 to +100), 10b5-1 excluded. (Business plan+) |
| Form 144 + institutional | |
| get_form144 | Notice-of-proposed-sale filings — early signal ~2 days before the Form 4 sale lands. (Business plan+) |
| get_holdings | Institutional positions from Form 13F-HR; filter by ticker, CUSIP, manager, quarter, or min value. (Business plan+) |
| get_managers | Institutional manager index with latest AUM. (Business plan+) |
| Utility | |
| check_usage | Your API key usage stats — plan, requests today, daily limit. |
| get_key_activity | Recent API requests for this key. |
| get_usage_history | Daily request counts for the last N days. |
| search_insiders | Substring search on insider names. |
| list_webhooks | List your webhook subscriptions. |
| get_webhook_events | Replay webhook delivery events since a timestamp. |
| get_public_stats | Corpus coverage stats — filings, transactions, history span, 13F holdings/AUM. No key required. |
What example prompts work with MCP?
Once configured, ask your AI assistant natural-language questions:
- >“What insider trades happened at NVDA this week, excluding 10b5-1 plan trades?”
- >“Show me significant insider buys at NVDA — real open-market purchases only, no plans or option exercises”
- >“Show me cluster buy signals from the last 7 days”
- >“What is Tim Cook's career insider-trading summary — total bought/sold and return averages?”
- >“Are there any Form 144 filings at TSLA suggesting upcoming sales?”
- >“Pull all open-market purchases over $500k at Tesla in 2026”
- >“What has the CFO of Microsoft been doing with their shares this year?”
- >“Check my Form4API usage and plan”
get_transactions, get_recent_filings, company, insider, and utility tools) work on the Free plan. get_insider_career_summary and get_insider_scorecard require Pro. Signals, sentiment, Form 144, holdings, institutional managers, and insider leaderboard (get_signals, get_sentiment, get_form144, get_holdings, get_managers, get_insider_leaderboard) require the Business plan. When a tool requires a higher plan, the AI surfaces a clear upgrade message with a link to pricing — no cryptic errors.// faq
Frequently asked questions
Developer-focused answers covering amendments, 10b5-1 plan filtering, date semantics, post-trade returns, rate-limit behaviour, and sandbox availability. The same content emits an identical FAQPage JSON-LD block on this page.
// glossary
Glossary
Key terms from SEC filings and insider trading data used throughout this API. Mirrored as a DefinedTermSet JSON-LD block on this page so AI crawlers can quote each definition cleanly.
- Accession Number
- The SEC's unique identifier for a single filing, formatted as XXXXXXXXXX-YY-ZZZZZZ (e.g. 0001140361-26-013190). The first segment is the filer's CIK, YY is the year, and ZZZZZZ is a sequence number. Use this to fetch a specific filing from the /v1/filings/{accession} endpoint.
- Beneficial Ownership
- Shares that an insider has an economic interest in, even if they are not registered in the insider's name. An insider is considered a beneficial owner of shares held by a spouse, a trust they control, or a company they own more than 50% of.
- CIK
- Central Index Key — the SEC's permanent numeric identifier for every entity that files with the SEC, including individuals and companies. CIKs are always 10 digits, zero-padded (e.g. 0001214156). Use a CIK to look up an insider's full filing history via /v1/insiders/{cik}.
- Open Market Transaction
- A discretionary purchase or sale executed on a public exchange at the prevailing market price. In Form 4 data, open-market transactions are identified by transaction codes P (purchase) and S (sale). These are the trades most relevant for signal analysis — they represent the insider choosing to put their own money in, or taking it out. Non-market events such as option exercises (M), tax withholding (F), grants (A), and gifts (G) are also reported on Form 4 but are not discretionary and should not be treated as conviction signals. The isOpenMarket field makes this distinction explicit.
- Rule 10b5-1 Plan
- A pre-scheduled trading arrangement that allows corporate insiders to buy or sell company stock at predetermined times, prices, or quantities, set up in advance when the insider held no material non-public information (MNPI). Trades executed under a 10b5-1 plan are automatic — the insider does not make a real-time decision to trade. Because they are pre-committed and not driven by current information, they carry no conviction signal. Form4API marks these trades with is10b5Plan: true and excludes them from cluster buy/sell signal computation. Use ?exclude_10b5=true on the transactions endpoint to filter them out.
- Cluster Signal
- A ClusterBuy or ClusterSell signal is triggered when three or more insiders at the same company independently file Form 4 transactions in the same direction (all buys or all sells) within a 5-day window. Clusters are considered a stronger signal than a single insider trade because they suggest shared conviction among multiple informed parties.
- Derivative Security
- A security whose value is derived from an underlying asset — typically company stock. Common derivatives reported on Form 4 include stock options, warrants, and convertible notes. When isDerivative is true in a transaction, sharesAmount refers to the number of shares underlying the derivative, not shares directly transferred.
- Direct vs Indirect Ownership
- The directIndirect field indicates how an insider holds shares. "D" (direct) means shares are registered in the insider's own name. "I" (indirect) means shares are held through an intermediary such as a trust, LLC, partnership, or a family member's account.
- Form 4
- The SEC filing required under Section 16 of the Securities Exchange Act of 1934. Corporate insiders — directors, officers, and shareholders owning more than 10% of a company — must file Form 4 within two business days of any change in their beneficial ownership of company securities. Form4API parses every Form 4 filed with the SEC and exposes the data via this API.
- Insider
- For SEC reporting purposes, an insider is any director, officer, or 10%-or-greater shareholder of a public company. These individuals have a heightened duty to disclose their trades because they may have access to material non-public information. Insider trading data is public — only the trades of these registered insiders are reported on Form 4.
- Period of Report
- The date field on a Form 4 indicating when the reported transaction occurred. This is usually identical to transactionDate but can differ for transactions that are grouped or reported after a delay. When the two dates differ, periodOfReport reflects the filing's stated coverage date.
- Section 16
- Section 16 of the Securities Exchange Act requires insiders to report their ownership and any changes to it. Section 16(a) mandates the Form 4 filings this API is built on. Section 16(b) requires insiders to disgorge any "short-swing profits" — gains from buying and selling the same stock within a six-month window.
- Transaction Code
- A single letter on Form 4 indicating the nature of the transaction. The most common codes are: P (open-market purchase), S (open-market sale), A (grant or award), M (exercise or conversion of derivative), F (shares withheld to cover tax on vest/exercise), D (disposition to the issuer). Less common but valid codes include: C (conversion of derivative), J (other acquisition or disposition), G (gift), X (in-the-money derivative exercise), O (out-of-the-money derivative exercise), E (expiration of long derivative), H (expiration of short derivative), I (discretionary transaction), L (small acquisition), U (tender offer disposition), W (acquisition by will or descent), Z (voting trust deposit/withdrawal), V (voluntary exempted disposition), K (equity swap), B (automatic sell to cover taxes), T (Rule 10b5-1 plan transaction).
// background reading
- What is SEC Form 4? Filing requirements, transaction codes, programmatic access →
- SEC Form 144 explained — notice of proposed sale →
- 13F-HR filings — institutional holdings explained →
- Cluster buy signals — why multiple insiders buying together matters →
- Rule 10b5-1 plans — pre-scheduled insider trades and why they carry less signal →