Watch a list of tickers

Watch a list of tickers for insider buying clusters, planned insider sales, activist stakes and institutional positions. One endpoint, one key, a cursor that guarantees no duplicates and no gaps.

Eleven SEC forms, four rhythms, one endpoint.

You have a watchlist. You want to know when something happens on it: insiders buying together, an insider filing to sell, an activist taking a stake, a fund moving in or out.

All of that is public. It is also spread across four SEC forms with four different shapes, published at four different rhythms, none of which was designed to be read by a program.

One shape for all of it

Every event in this feed has the same envelope, whatever form it came from:

{
  "event_id": "insider_cluster:CAMP:2026-08-03",
  "event_type": "insider_cluster",
  "occurred_at": "2026-08-03",
  "company": { "name": "Camp4 Therapeutics Corp", "ticker": "CAMP" },
  "score": 67.2,
  "score_inputs": {
    "num_insiders": 4,
    "num_buys": 4,
    "total_value_usd": 59451.15,
    "formula": "insider_cluster/v1",
    "inputs_complete": false
  },
  "data": { "conviction": "NON-CONVICTION" },
  "source": { "url": "https://www.sec.gov/...", "form": "4" }
}

Code you write for insider clusters reads activist stakes without changes. That is the whole design.

Note conviction: NON-CONVICTION on that record. Four insiders bought, but the pattern says mechanical - a grant or a scheduled plan rather than someone deciding. A feed that only gave you "four insiders bought" would have you reading that as something it is not.

Watching your list

Pass your tickers, comma separated:

curl -H "Authorization: Bearer ds_live_your_key_here" \
  "https://datasignalslab.com/v1/events?ticker=AAPL,MSFT,NVDA&limit=100"

Narrow to what you care about:

curl -H "Authorization: Bearer ds_live_your_key_here" \
  "https://datasignalslab.com/v1/events?ticker=NVDA\
&event_type=insider_cluster,activist_stake&min_score=70"

Every response carries a cursor. Store it, pass it back as since, and an hourly job sees each event exactly once - never twice, never skipping one. That holds whether you call every hour or once a week.

Prefer to be pushed to? Register a webhook and we deliver as events land, signed so you can prove the payload came from us.

The part that matters when someone questions you

Every score carries the terms it was built from. You can recompute it. And where a term of the formula is missing from the published source, the record says inputs_complete: false instead of quietly inventing a number to fill the gap - as it does on the record above.

The full published set is hashed daily into an append-only chain, anchored in Bitcoin. A signal from three months ago cannot be edited after the fact to look better than it was. And a separate endpoint reports where a source has since revised something we already sent you: what we published, and what the source says today.

That is the difference between a track record and a claim about one.

Being straight about it

Not real time. Sources refresh once a night, congressional trades weekly, institutional holdings quarterly - because that is how often they are published. The freshest an event can be is this morning's round.

Published filings only. The archive holds what was published, not everything a source ever had.

Not investment advice. This is data for research and monitoring.

What it costs

Plans start at $29 a month, with a free tier that carries one stream so you can check the shape of the data and the honesty of the scores before you pay. Two endpoints need no key at all: one lists the fields each stream carries, the other reports how many hours old every source is right now.

FAQ

How many streams cover a ticker?

Twelve, of which the SEC ones apply to any registered company: insider clusters, planned insider sales, activist stakes, institutional holdings and material corporate events.

Can I watch by CIK instead of ticker?

Yes, pass `cik=` instead. Both work, and there is a per-company endpoint that accepts either.

What happens if I go over my monthly events?

The feed returns an empty page with your cursor unchanged and a plain notice. Nothing is skipped: resume from that cursor when your period resets or you upgrade.

How do I know a score is right?

Recompute it from `score_inputs`. If that is not possible for a record, the record already told you so.

Can I watch by CIK instead of ticker? Yes, pass cik= instead. Both work, and there is a per-company endpoint that accepts either.

What happens if I go over my monthly events? The feed returns an empty page with your cursor unchanged and a plain notice. Nothing is skipped: resume from that cursor when your period resets or you upgrade.

How do I know a score is right? Recompute it from score_inputs. If that is not possible for a record, the record already told you so.