EDGAR Insider Transactions
Insider transactions from SEC Forms 3, 4 and 5: buys, sells, grants and gifts by officers, directors and 10% owners.
edgar_insider_transactions — the dataset name to pass to the Obscura API.
What one row means
One reported securities transaction line (non-derivative or derivative) parsed from a single SEC Form 3/4/5 insider-ownership XML document. A filing can carry many transactions; each becomes one row. Non-derivative rows are emitted first, then derivative rows.
One row per (filename, seq).
Point-in-time availability
Every Obscura dataset carries available_date: the calendar day the publisher made the row
available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the
same thing on every dataset in the catalog.
For edgar_insider_transactions: filing_join: available_date = edgar_filings.event_date (the filing's EDGAR dissemination date), recovered by joining filename -> edgar_filings.
Known limitation
Backfilling Form 3/4/5 deep history. Dense from 2012; 2003-2011 is a partial sample of filings, not of the market.
Refresh cadence
Obscura refreshes edgar_insider_transactions every 6 hours — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.
Schema — 38 columns
The full public column list for edgar_insider_transactions, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/edgar_insider_transactions.
| Column | Type | Description |
|---|---|---|
| filename | text · not null | EDGAR ownership-document path (sec.gov/Archives/{filename}); primary-key part 1 and the join key back to `edgar_filings.filename`, which carries the true filing/public date. |
| seq | integer · not null | Zero-based position of this transaction within the document; non-derivative rows first, then derivative. Primary-key part 2. |
| cik | bigint · not null | SEC Central Index Key of the issuer (the company whose stock was traded). NOT NULL. |
| issuer_name | text | Name of the issuer company, from the XML `<issuerName>`. |
| symbol | text | Issuer trading symbol from `<issuerTradingSymbol>`, blank-filtered to null. |
| owner_cik | bigint | SEC CIK of the reporting insider (the person/entity who transacted); parsed from `<rptOwnerCik>`. |
| owner_name | text | Name of the reporting insider, from `<rptOwnerName>`. |
| is_director | boolean · not null | True if the insider is a director of the issuer; from the `<isDirector>` relationship flag. NOT NULL default false. |
| is_officer | boolean · not null | True if the insider is an officer; from `<isOfficer>`. NOT NULL default false. |
| is_ten_percent_owner | boolean · not null | True if the insider is a >=10% beneficial owner; from `<isTenPercentOwner>`. NOT NULL default false. |
| officer_title | text | Free-text officer title (e.g. 'CFO') when `is_officer`; from `<officerTitle>`. |
| form_type | text | Ownership form type: '3', '4', or '5' (from `<documentType>`), determining the filing deadline rule. |
| period_of_report | date | The filing's period-of-report date from `<periodOfReport>`; the as-of reporting date of the ownership document. |
| security_title | text | Title/class of the security transacted (e.g. 'Common Stock', 'Stock Option'); from the transaction's `<securityTitle>`. |
| available_date | date | The Form 3/4/5's SEC filing/dissemination date — when the public could first see it. Recovered from `edgar_filings` via `filename`; the point-in-time anchor for this dataset. |
| occurred_on | date | The transaction date — when the insider actually traded (the real-world event); Form 4 is due within 2 business days, so filed shortly after. |
| transaction_code | text | SEC transaction code: P=open-market buy, S=sale, A=grant/award, M=option exercise, F=tax withholding, G=gift, ...; from `<transactionCode>`. |
| acquired_disposed | text | Direction flag: 'A'=acquired, 'D'=disposed; from `<transactionAcquiredDisposedCode>`. |
| shares | double precision | Number of shares (or derivative units) in the transaction; from `<transactionShares>`. |
| price_per_share | double precision | Per-share transaction price; from `<transactionPricePerShare>`. |
| shares_owned_after | double precision | Beneficial share count owned by the insider following the transaction; from `<sharesOwnedFollowingTransaction>`. |
| direct_or_indirect | text | Ownership nature: 'D'=direct, 'I'=indirect; from `<directOrIndirectOwnership>`. |
| nature_of_ownership | text | Free-text nature of an indirect holding (e.g. 'By Trust', 'By 401(k)', 'By Spouse') from `<ownershipNature><natureOfOwnership>`; qualifies the 'I' `direct_or_indirect` code. |
| aff10b5_one | boolean | Rule 10b5-1 pre-arranged trading-plan flag (document-level `<aff10b5One>`): true when the trade was made under a scheduled, non-discretionary plan vs an opportunistic discretionary trade. |
| equity_swap_involved | boolean | Equity-swap flag from the transaction's `<transactionCoding><equitySwapInvolved>`. |
| conversion_exercise_price | double precision | Strike/exercise price of the derivative (option/warrant), from the derivative transaction's `<conversionOrExercisePrice>`; null for non-derivative rows. |
| underlying_security_title | text | Title/class of the security the derivative converts into, from `<underlyingSecurity><underlyingSecurityTitle>`; the true underlying exposure of an option/RSU row. |
| underlying_security_shares | double precision | Count of underlying shares the derivative converts into, from `<underlyingSecurity><underlyingSecurityShares>` (our `shares` is the derivative-unit count, not this). |
| exercise_date | date | Date the derivative first becomes exercisable, from the derivative transaction's `<exerciseDate>`. |
| expiration_date | date | Expiration date of the derivative, from `<expirationDate>`. |
| is_other | boolean | Fourth insider-relationship flag (`<isOther>`) — a relationship not covered by director/officer/ten-percent-owner. |
| other_text | text | Free-text description of the `is_other` relationship, from `<otherText>`. |
| owner_city | text | Reporting insider's city, from `<reportingOwnerAddress><rptOwnerCity>`. |
| owner_state | text | Reporting insider's state/country code, from `<rptOwnerState>`. |
| owner_zip_code | text | Reporting insider's ZIP/postal code, from `<rptOwnerZipCode>`. |
| owner_non_us_address | boolean | Foreign-address flag, from `<rptOwnerNonUSAddressFlag>`: true when the insider's address is outside the US. |
| derivative | boolean · not null | True when the row came from the derivative table (options, RSUs, warrants); false for non-derivative (common stock) transactions. NOT NULL default false. |
| scraped_at | timestamp with time zone · not null | Ingestion timestamp set to `Utc::now()` at upsert; internal provenance, excluded from exports. |
Access edgar_insider_transactions
Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.
import obscura
client = obscura.Client("obs_live_…")
df = client.query(
dataset="edgar_insider_transactions",
symbols=["NVDA", "AAPL"],
start="2024-01-01",
)
Create a free account Browse all 95 datasets
Frequently asked questions
What is in the edgar_insider_transactions dataset?
Insider transactions from SEC Forms 3, 4 and 5: buys, sells, grants and gifts by officers, directors and 10% owners. One reported securities transaction line (non-derivative or derivative) parsed from a single SEC Form 3/4/5 insider-ownership XML document. A filing can carry many transactions; each becomes one row. Non-derivative rows are emitted first, then derivative rows.
How do I avoid look-ahead bias with edgar_insider_transactions?
Filter on edgar_insider_transactions.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — filing_join: available_date = edgar_filings.event_date (the filing's EDGAR dissemination date), recovered by joining filename -> edgar_filings. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get edgar_insider_transactions?
As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="edgar_insider_transactions". The column schema is public at https://api.obscura.trade/v1/catalog/edgar_insider_transactions.
Can I filter edgar_insider_transactions by company or symbol?
Yes. edgar_insider_transactions carries symbol, the column the API's symbols filter resolves against.
Is edgar_insider_transactions complete?
Not yet, and the limitation is declared rather than hidden: Backfilling Form 3/4/5 deep history. Dense from 2012; 2003-2011 is a partial sample of filings, not of the market.
How often is edgar_insider_transactions updated?
Obscura refreshes edgar_insider_transactions on a every 6 hours schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.