Skip to main content
This tutorial builds a small, repeatable review of reported insider transactions. You will retrieve Form 4 rows for an issuer, filter records by transaction code, and retain the accession number and filing URL that let an analyst inspect the source. The result is a research queue, not a trading signal. A filing may omit the context that makes a transaction routine, and a code such as P should not be treated as a recommendation. For a product-level workflow, see the insider trading monitor. For filing mechanics, see the Form 4 glossary.

Prerequisites

  • An SEC API key in SECAPI_API_KEY
  • curl, or Python 3.8+ / Node.js 18+ for the examples below

1. Retrieve recent Form 4 rows

Start with a single issuer and Form 4. The response is a list envelope; the records are in data.
curl -sS -H "x-api-key: $SECAPI_API_KEY" \
  "https://api.secapi.ai/v1/insiders?ticker=AAPL&forms=4&limit=10"
Each row includes filing and transaction dates, transactionCode, transactionDirection, the reported owner, transaction shares and price when disclosed, the accession number, and provenance. Keep the source fields with any downstream note.

2. Filter a reported transaction code

Form 4 code P identifies a reported purchase transaction. Scope the query to Form 4 before using the code filter:
curl -sS -H "x-api-key: $SECAPI_API_KEY" \
  "https://api.secapi.ai/v1/insiders?ticker=JPM&forms=4&transaction_code=P&limit=10"
transactionDirection is a separate normalized field (acquired, disposed, or unknown). Preserve both values instead of inventing a single buy/sell label.

3. Build a compact review with Python

This example uses the REST contract directly, so each filter maps one-for-one to the documented endpoint.
import os
import requests

response = requests.get(
    "https://api.secapi.ai/v1/insiders",
    headers={"x-api-key": os.environ["SECAPI_API_KEY"]},
    params={
        "ticker": "JPM",
        "forms": "4",
        "transaction_code": "P",
        "limit": 20,
    },
    timeout=30,
)
response.raise_for_status()

for trade in response.json()["data"]:
    owner = trade.get("ownerName") or "Unknown owner"
    date = trade.get("transactionDate") or trade.get("filingDate")
    shares = trade.get("transactionShares")
    price = trade.get("transactionPrice")
    value = trade.get("transactionValue")
    filing_url = (trade.get("provenance") or {}).get("filingUrl")

    print(f"{date} | {owner} | code {trade.get('transactionCode')}")
    print(f"  shares={shares!r} price={price!r} value={value!r}")
    print(f"  accession={trade.get('accessionNumber')} source={filing_url}")
The code prints None for a field the filing does not provide. That is intentional: a review workflow should make missing evidence visible rather than silently estimating it.

4. Review one reporting owner

Use owner_name or owner_cik to focus on a specific reporting owner. This Node.js example calls the public REST endpoint directly.
const url = new URL("https://api.secapi.ai/v1/insiders");
url.search = new URLSearchParams({
  ticker: "JPM",
  forms: "4",
  owner_name: "Jamie Dimon",
  limit: "20",
}).toString();

const response = await fetch(url, {
  headers: { "x-api-key": process.env.SECAPI_API_KEY! },
});
if (!response.ok) throw new Error(`SEC API request failed: ${response.status}`);

const { data } = await response.json();

for (const trade of data) {
  console.log({
    owner: trade.ownerName,
    filed: trade.filingDate,
    transacted: trade.transactionDate,
    code: trade.transactionCode,
    direction: trade.transactionDirection,
    accession: trade.accessionNumber,
    filingUrl: trade.provenance?.filingUrl,
  });
}

5. Add the judgment the API cannot supply

Before escalating a transaction, read the linked filing and ask:
  • Is the row common stock, an option exercise, a derivative security, or another instrument?
  • Is the transaction code consistent with the conclusion you are drawing?
  • Are the transaction date, filing date, and any amendment material to the timing?
  • Does the filing footnote describe a plan, tax withholding, gift, or other context that changes the interpretation?
  • Are you comparing like-for-like records across issuers and reporting owners?
SEC API makes the disclosure easier to retrieve and organize. The filing is still the record, and investor judgment is still required.

Next steps