get_insider_transactions

shallow

com.keyvex/keyvex · Verify this server

Returns executive insider transactions filed on SEC Form 4 — open-market purchases and sales by officers, directors, and 10%-owners of public companies. Each record is one transaction line item from one filing. Use this when the user asks about: insider buying or selling at a specific company, all recent insider activity across the market, transactions by a specific officer, or large insider trades by value. Form 4 is the fastest insider-trade signal in the public record — must be filed within 2 business days of the trade. The reporting_lag_days field tells you how stale a particular disclosure is. Returns BOTH non-derivative rows (direct common-stock buys/sells, RSU vests, grants, gifts, tax-withholding sales) AND derivative rows (option exercises, warrant conversions, RSU/PSU activity). Filter to one or the other with is_derivative; filter to specific transaction codes with transaction_codes. Common transaction codes: P open-market purchase | S open-market sale A grant / award / RSU vest | M exercise of derivative X exercise of in/at-the-money derivative | C conversion of derivative F payment of exercise price or tax with shares | G bona fide gift D disposition to issuer (forced) | I 401(k)/ESPP | V voluntary ⚠ shares and price_per_share are NULLABLE, and null does not mean zero. SEC permits either to be omitted — the price can live in a footnote, and the share count is genuinely undetermined on instruments that convert at a future price (a convertible note settling on a later VWAP). Those filings state a dollar amount instead, so such rows carry total_value with a null shares. Before 2026-08-18 they were dropped from this dataset entirely. Do not do arithmetic on either field without a null check, and do not read a null share count as a trade of nothing — read total_value. Useful filter combos: ⚠ transaction_codes=['P'] IS NOT 'open-market buys'. SEC defines P as 'open market OR PRIVATE purchase', and the code alone says nothing about whether the security is common stock. Verified 2026-08-14: FLUT's code-P rows are $250M of Total Return Swaps (is_derivative=true) and ATTO's are an $8.5M private placement. Both are correctly labelled in transaction_nature and security_title — but a screen filtered on the code alone ranks them top by size. transaction_codes=['P'], is_derivative=false, include_non_open_market=false genuine open-market common-stock buys — the combination you almost always want transaction_codes=['M','X'] option exercises (cash-out trigger) transaction_codes=['A'] grants / RSU vests is_derivative=true all option/RSU/warrant activity is_derivative=false, transaction_type='sell', min_value=1000000 large open-market sells of common stock Optional include_baseline=true: also returns matching Form 3 initial- ownership records (the insider's *starting* position when they first became an insider) under a `baselines` field. Use this when you need to know how big a sale is relative to the insider's full position — Form 4 alone shows the delta, Form 3 anchors the baseline. Requires ticker or company_cik to be set. Baseline rows with is_nil_filing=true are 'no securities owned' Form 3s (~half of all filings) — the insider filed but started with ZERO holdings; shares_owned 0 is the position, not missing data. A ticker search also returns rows this issuer FILED UNDER SYMBOLS IT NO LONGER LISTS — renames, filer typos and ADR spellings all split a company's history across symbols. Each row keeps `ticker` exactly as SEC received it and gains `current_ticker` when the issuer trades under a different symbol today; the response carries `ticker_resolution` naming every symbol searched. Separately-listed share classes are NOT merged: GOOG does not return GOOGL. Asking for a RETIRED symbol returns only rows filed under it, because retired symbols get reissued to other companies. Rows found under a retired symbol are checked against the issuer's CIK, so a symbol another company files under today cannot leak its rows in. Coverage: full history on the bulk leg; the live-feed leg is scanned back 180 days, so a rename in the last few days may not be covered yet. data_source SELECTS WHICH BACKING COLLECTION: 'bulk_v2' (DEFAULT as of 2026-05-24) — `insider_transactions_v2` collection populated by SEC quarterly bulk Forms 3/4/5 TSV bundles. Deeper history (2006q1 → latest published quarter, ~9.9M rows). ⚠ RECENCY: the bulk dataset ends at the last PUBLISHED quarter (SEC releases it ~2 weeks after quarter end). On simple recency queries (descending sort, no v2-only filters) filings newer than that boundary are AUTO-MERGED from the live daily feed, so the default view stays current — coverage_warning says when this happened. For post-boundary browsing with v2-only filters, query data_source:'legacy' directly. INLINED FOOTNOTES (footnote_refs[] with resolved text on every row), aff10b5one 10b5-1 plan flag, full reporting_owners array, schema_era. Filters: ticker, company_cik, reporting_owner_cik, reporting_owner_name (substring), row_type ('nonderiv'|'deriv'), trans_codes (aka transaction_codes — either spelling works on either data_source), aff10b5one, schema_era ('pre_2023'|'2023_plus'), since/until, sort_by ('transaction_date'|'filing_date'). PLAUSIBILITY FIELDS — WHAT THEY CAN AND CANNOT CONCLUDE: Every row carries price_check and volume_check, and both are ALWAYS non-null: they say whether each check ran, and why not when it did not. Read those first. ⚠ THE RAW MARKET VALUES ARE PAID-PLAN ONLY. price_range_low and price_range_high (bulk rows), daily_range (legacy and live-feed rows) and shares_vs_daily_volume are Tiingo market data, which KeyVex's licence restricts to paid plans. On other plans those keys are OMITTED — not null — and the response carries licensed_fields_withheld naming them. The verdicts computed from them (price_check, price_outside_daily_range, price_fits_date, volume_check, volume_verdict) are served on every plan. ⚠ THE OTHER THREE ARE OFTEN ABSENT OR NULL, AND THIS TEXT USED TO SAY 'every row carries' ALL FOUR, WHICH WAS FALSE. Measured 2026-09-04 by the KeyVex auditor over a 500-row market-wide March sample: price_outside_daily_range key present 500/500, NON-NULL on 178 volume_verdict key present 500/500, NON-NULL on 178 shares_vs_daily_volume key ABSENT on 500/500 The 322 nulls are exactly the rows where volume_check is not 'checked' — so the reason is always available, on the field that says so. shares_vs_daily_volume is stamped only alongside a NON-NORMAL volume verdict, and the same sample contained no non-normal rows, so an ordinary response carries it nowhere. Do not build on its presence. A null here means NOT CHECKED. It never means fine. They were served without definition until 2026-09-01, which is how 'impossible' came to read as a stronger claim than the check supports. volume_verdict compares REPORTED SHARES against that day's recorded volume, and shares_vs_daily_volume is the raw ratio so you can judge for yourself: 'normal' ratio <= 0.25 'outsized' ratio > 0.25 — a large share of the day's tape 'impossible' ratio > 1 — MORE SHARES THAN THE DAY RECORDED. ⚠ 'impossible' means the two numbers cannot both be right, NOT that the trade did not happen. Our volume is one daily bar: it need not include off-exchange or block prints, and a Form 4 may report several days' activity on one date. Treat it as strong evidence of a reporting or data problem worth investigating, not as proof the transaction is fake. null = not judged. Computed only for market claims (codes P and S) — a grant never touched the tape, so a ratio on it would be noise. price_check says whether the price was tested against that day's bar: 'checked' tested; price_outside_daily_range holds the result 'misdated' tested; the price is OUTSIDE that day's bar (see daily_range) — price_outside_daily_range is TRUE — but fits the bar of price_fits_date, within 3 calendar days. Read as: a real fill whose filer wrote the wrong date. KeyVex's own screens treat it as real: its dollar total is kept, it is not vetoed as non-open-market, and co-report resolution never drops it silently. 'no_price_reported' the filer stated no price 'no_positive_price' the filer stated a price of zero or less, so there was nothing to compare. The bar may be present — see volume_check. 'no_verdict_recorded' the day's bar was found (volume_check ran off it) but its high/low were unusable, so the price half is unjudged 'no_daily_bar' no usable bar for that ticker and date ⚠ THE LAST THREE ARE DELIBERATELY DISTINCT. Until 2026-09-04 all three were served as 'no_daily_bar', which asserted a missing bar on rows whose shares_vs_daily_volume — a ratio computable only FROM that day's bar — was served three fields away. Found live by the trading simulation. If you match on 'no_daily_bar', match on all four. volume_check says whether the SHARES-vs-VOLUME check ran, and is now independent of the price half: 'checked' | 'not_a_market_trade' | 'no_daily_bar'. A row can be volume_check 'checked' while price_check is 'no_positive_price' — the bar was there, only the price was not. price_outside_daily_range is true|false|null, and NULL MEANS NOT CHECKED — never 'fine'. A row whose price_check is any value other than 'checked' or 'misdated' has not been vetted on price at all, so do not read its silence as a pass. CLUSTER BUY (every data_source): cluster_buy_insiders_30d = the number of DISTINCT reporting owners (by CIK) with an open-market purchase (code P) in the same ticker in the 30 days ending on this row's transaction_date, this row included; cluster_buy = a code-P row with that count >= 3. Both are NULL — never a guess — on a row that is not a purchase, or when the window cannot be counted; cluster_buy_basis always says which, e.g. 'owner CIK not recorded for trades before 2026-07-01' (live-feed rows before then carry no owner CIK; bulk rows always do). BACKWARD-COMPAT: every v2 row also carries the LEGACY field aliases (disclosure_date, transaction_code, shares, price_per_share, total_value, acquired_disposed, shares_owned_after, officer_name, is_derivative, reporting_lag_days, data_source, sec_filing_url) so callers reading the old field names keep working. The `transaction_type` field carries the legacy 'buy'|'sell' semantic (synthesized from trans_code + trans_acquired_disp_cd, identical algorithm to the legacy scraper); the v2 nonderiv|deriv discriminator lives at `row_type`. 'legacy' — `insider_trades` collection populated by KeyVex's daily EDGAR scraper. Shallower coverage (2022+), no footnotes, no aff10b5one, ~91% fewer filings in the same window than bulk_v2. Rows written since 2026-09-30 also carry reporting_owner_cik (the filing's FIRST reporting owner, 10-digit, the bulk's own rule) and reporting_owner_ciks (every owner on the filing); older legacy rows do not, so the field's absence means 'not recorded', not 'none'. Filters: ticker, company_cik, officer_name, transaction_type (buy|sell), is_derivative, transaction_codes (aka trans_codes), min_value, since/until, sort_by (disclosure_date|transaction_date|total_value). Use this only when you specifically need the legacy doc shape with NO v2-extension fields. SEC-SOURCE DATE CONVENTIONS — read raw values with these in mind: KeyVex preserves SEC's authoritative bytes exactly as published. Two recurring source-data patterns are worth recognizing so agents interpret raw date values correctly: (1) PERPETUAL-INSTRUMENT SENTINEL — exercise_date or expiration_date values of 2050-12-31 / 2050-08-31 ARE SEC's established convention for instruments with no calendar expiration (Deferred Stock Units, certain Non-Qualified Stock Options, Units of Limited Partnership Interest, similar perpetual or condition-vested derivatives). Read these as 'no expiration,' not as literal calendar dates in 2050. This is a fact about SEC's schema, not an inference. (2) ANOMALOUS-YEAR FILER-ENTRY PATTERN — date values with out-of-range year components — e.g., 0012-11-21 or 0025-07-25 (likely 2-digit years entered into a 4-digit field), or 2027-01-25 on a 2026 filing / 2028-03-19 on a 2024 filing (likely single-digit transpositions) — appear to be filer data-entry typos preserved verbatim from SEC's primary filings. KeyVex verified on a stratified spot-check that these values are byte-identical between SEC's primary XML and SEC's bulk extract (22 / 22 matches across all observed pattern faces); the SEC-to-KeyVex transit is faithful. The pattern is ongoing — observed across filings from 2014 through 2026, not legacy-only. Cross-reference filing_date to infer the likely intended year. (3) NUMERIC PRECISION — for data_source='bulk_v2', shares and price_per_share mirror SEC's BULK Form 345 extract, which rounds to 2 decimals (e.g. 474.6, where the primary XML shows 474.598). That rounding is SEC's, in the bulk feed — KeyVex stores the bulk value verbatim (no rounding in the loader). Audit v2 numerics against the bulk extract (the source of record), not the XML primary document, which carries fuller precision. Dates and transaction codes DO match the XML exactly. (4) A DISCLOSURE DATE IS NOT CLOSED WHEN THE DAY ENDS. Filings keep arriving bearing a disclosure_date that has already passed, because SEC accepts them late and there is no cut-off after which a date stops gaining rows. So the SAME disclosure_date window can return MORE rows tomorrow than it did today, and a result cached against that date goes quietly stale — the count does not change, so nothing looks wrong. Observed 2026-08-14: the newest disclosure_date on the tape was still 2026-08-13, yet a row bearing 08-13 was first ingested at 07:01 ET the NEXT morning. A caller working from the previous afternoon's view of 08-13 missed $1.26M of buying in a position it already held. (5) SANITY-CHECK A BIG DOLLAR FIGURE AGAINST VOLUME, IN THIS API. total_value is derived (shares x price) wherever SEC did not file a total, so a filer's unit or decimal slip lands in it. The cheapest test is whether that many shares could plausibly have traded: get_daily_prices(ticker, since, until, include_ohlc=true) -> volume Compare the reported share count to the session's volume. A purchase that is a large multiple of everything that traded is worth a second look before acting on it. Verified examples, 2026-08-14: COE reported 592,320 ordinary shares against 52,418 ADS traded — a 60:1 ADS ratio, not a real $11.8M buy. EVGN reported 460,000 against 326,793 traded (141%) and was FINE — Evogene is dual-listed on NASDAQ and Tel Aviv, so the US tape sees only part of the volume. The check flags what to examine; it does not decide. Both readings beat ranking by total_value and trusting the top. RE-QUERY rather than reusing a prior window. 'Same disclosure date' does not mean 'same rows'. If you need to detect what is NEW since your last look, compare against the row identity you saw before rather than assuming a closed date is settled — and note that a sync timestamp moving is a statement about the JOB, not about the DATA. Pure-publisher posture: KeyVex mirrors SEC's exact bytes, documents these conventions and filer quirks rather than altering them, and never silently 'corrects' a value to KeyVex's guess of what was meant. A customer auditing KeyVex against EDGAR's source of record for each row (the bulk Form 345 extract for v2 rows) will find a byte-for-byte match. MACHINE-READABLE FLAGS — responses include a `source_metadata` block on rows where the above SEC-source patterns are detected. The block is keyed by field name, with an array of flag strings per field: `sec_perpetual_sentinel` (assertive — exact-string match on a known SEC sentinel value); `anomalous_year_likely_filer_entry` (calibrated — year outside the plausible range on transaction_date, exercise_date, expiration_date, or period_of_report; covers filing-pipeline data quality issues across the upstream-actor stack including filer typos, filing-agent default-epoch substitutions, and other cause-classes where the year falls outside any plausible range). Presence is the signal: clean rows have NO `source_metadata` field at all (not an empty object — the field is omitted entirely). Absence means 'no SEC source quirks detected,' NOT 'certified clean by audit' — agents weigh the difference. The raw source date values are preserved unchanged; the flag block carries KeyVex's labeled interpretation alongside, never replacing.

100.0/100

1 trials · measured 2 days ago

get_insider_transactions scores 100.0/100 on Vouch's measured behaviour index, from 1 real invocation trials against com.keyvex/keyvex, measured 6 Oct 2026 under methodology v0.2.0. Every measured component scored 100.

Component breakdown

ComponentWeightValue
Reliability35%not applicable
Schema integrity25%100.0
Failure behaviour15%not applicable
Latency15%not applicable
Concurrency10%not applicable

Tool details

Transport
remote
Credential class
self-provisionable
Input schema
not declared
Output schema
not declared
Side-effect classification
unclassified

Score history

DayScoreTierMethodology
2026-10-06100.0shallowv0.2.0

Probe evidence

ProbeOutcomes
schema_integritypass: 1

Raw request/response logs are not archived yet — the outcome counts above are drawn directly from every recorded trial.

Embed this score

Available for every tool, scored or not — not a verification perk. Always links back to this page.

Vouch score: get_insider_transactions
[![Vouch score](https://vouch.tools/api/tools/a6e70649-6049-4c98-a30a-17318dfce6ae/badge.svg)](https://vouch.tools/tools/a6e70649-6049-4c98-a30a-17318dfce6ae)
get_insider_transactions — Vouch