# Major Shareholder Change Monitor - SEC 13D & 13G (`maydit/major-shareholder-change-monitor`) Actor

Track structured SEC 13D and optional 13G stakes, purpose text and saved ownership changes. Evidence links, bounded company watchlists and honest amendment coverage.

- **URL**: https://apify.com/maydit/major-shareholder-change-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 major shareholder observations

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![Reported shareholder stakes, stated purpose and SEC filing evidence](https://api.apify.com/v2/key-value-stores/nemaYfVcrTgloz8Wn/records/major-shareholder-change-monitor-e70412646daa.png?signature=1kVeauUQf2E60AaGhWjnk)

### Track ownership as it was disclosed

Build a reviewable ownership timeline from structured SEC Schedule 13D filings and optional 13G filings. Compare a reporting person’s disclosed stake and stated purpose with your saved observation. Useful for issuer research, ownership monitoring and document review.

[Open this Actor in Console](https://console.apify.com/actors/oVHvi3lcUtmQ24Rx4/input) · [First run](#try-this-actor) · [Results](#result-preview) · [Saved comparisons](#build-a-repeatable-workflow) · [Full guide](#full-guide)

### Try this Actor

Inspect five reporting-person observations from a historical W. R. Berkley Schedule 13D/A filed in March 2026. The source contains eight reporting persons; this first example deliberately caps output at five. Use the comparison example below to retain all eight. No API key or additional paid source subscription is required.

**Inspect W. R. Berkley Schedule 13D ownership** — paste this input into the Console JSON editor.

```json
{
  "filingUrls": [
    "https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"
  ],
  "maxResults": 5
}
```

Open the dataset to inspect the person, reported stake and filing evidence. The fixed example demonstrates document extraction; it is not a notice that holdings changed today.

**Read each person separately:** Related reporting persons can disclose the same shares. Their holdings can overlap and **must not be summed**.

### Result preview

One row identifies a reporting person, issuer, security CUSIP and schedule family.

| Research question | Output fields |
| --- | --- |
| Which issuer and security? | `issuerName`, `issuerCik`, `cusip`, `securityTitle` |
| Who disclosed the position? | `reportingPersonName`, `reportingPersonCik` |
| What stake was reported? | `aggregateOwned`, `ownershipPercent`, raw source values |
| What purpose is present? | `purposeText`, `purposeStatus`, `purposeMentions` |
| What differs from the saved document? | `ownershipPercentagePointChange`, `aggregateOwnedChange`, `changedFields` |
| Where and when was it disclosed? | `sourceUrl`, `formType`, `eventDate`, `filingDate`, `acceptedAt` |

Values remain as filed. Document differences do not establish a purchase, sale or activist intent. Missing publication metadata stays null.

### Usage and pricing

Base result rate on the FREE tier: **$5 per 1,000 saved ownership observations**. The [Pricing tab](https://apify.com/maydit/major-shareholder-change-monitor/pricing) shows your plan’s result rate and the **Actor Start** charge. Set `maxResults` and a platform spending limit before running a larger watchlist. A result cap is an upper bound, not a promise of that many results.

Saved unchanged observations are billable. `onlyChanges` skips unchanged rows after a baseline; skipped rows, source errors and summary files are not dataset-item charges.

### Build a repeatable workflow

1. **Choose the issuer and evidence.** Start with a small ticker/CIK watchlist or exact XML documents. Include 13G only when its separate disclosure context fits your research.
2. **Save the first document.** Use the comparison example below. Keep the watchlist, limits, `snapshotName` and named history store consistent for later runs.
3. **Review each changed person.** Inspect `previous`, the reported stake deltas and the linked filing. Read Item 4 and its status before drawing conclusions from a changed purpose field.
4. **Maintain a research register.** Use `id` as the destination key, retain filing links and keep related reporting persons separate. Export JSON for nested previous values or CSV for a flat review sheet.

After the baseline, `onlyChanges: true` can suppress unchanged observations. Run each namespace sequentially and review SUMMARY before interpreting missing output.

### Full guide

#### Select company filings or exact documents

Choose `companies` (up to 10 tickers/CIKs) or `filingUrls` (up to 30 raw SEC XML URLs). Company queries use the SEC’s recent submissions index and never fall back to sample data. The index can include filings where the requested company is itself a reporting person; those documents are excluded if their issuer CIK does not match. A low filing cap can therefore miss issuer matches.

Company discovery uses `lookbackDays` and `maxFilingsPerCompany`; it does not traverse archived submissions indexes. Direct documents are inspected regardless of age. The empty-input default reads the historical W. R. Berkley document and returns its eight reporting-person observations, subject to the saved-result limit.

#### Field reference

| Field | What it tells you |
| --- | --- |
| `issuerCik`, `issuerName`, `cusip`, `securityTitle` | Identity of the issuer and disclosed class. No ticker is guessed from a company name. |
| `reportingPersonName`, `reportingPersonCik` | Disclosing person/entity. CIK is null where the filing does not supply it. |
| `aggregateOwned`, `ownershipPercent` | Numeric reported stake when parsable, alongside raw values. Zero is preserved as zero. |
| `soleVotingPower`, `sharedVotingPower`, `soleDispositivePower`, `sharedDispositivePower` | Reported voting and disposition powers. These can overlap. |
| `stakeComment`, `groupMembershipRaw` | Filing qualifications and group indication, without resolving legal ownership relationships. |
| `purposeText`, `purposeStatus` | Schedule 13D Item 4 text actually present in this document. |
| `purposeMentions` | Literal keyword excerpts for navigation. Negated mentions still appear; no activist-intent classification is inferred. |
| `ownershipPercentagePointChange`, `aggregateOwnedChange` | Differences from your saved document, when both values are numeric. They do not establish a purchase or sale. |
| `eventDate`, `filingDate`, `acceptedAt`, `observedAt` | Event date, SEC publication metadata when discovery supplies it, and this run’s observation time. |
| `sourceUrl`, `accessionNumber`, `formType` | The underlying structured SEC filing and form type. |

#### Read amendments correctly

An amendment can omit an unchanged item or refer to earlier filings. Missing Item 4 is labelled `absent_in_this_document_not_reconstructed`; it is not interpreted as withdrawal of earlier plans. This release does not reconstruct an amendment chain or resolve incorporated exhibits.

Only structured `SCHEDULE 13D`, `SCHEDULE 13D/A`, `SCHEDULE 13G` and `SCHEDULE 13G/A` XML is supported. Older unstructured `SC 13D`/`SC 13G` HTML and text are outside scope. For direct URLs, the SEC’s XSL viewer path is normalized to its raw XML document.

Schedule 13G uses a separate XML structure and disclosure context. Set `include13G` to include it. It has no 13D Item 4 narrative; the output says `not_applicable_13g`. These are disclosed positions with filing delays, not a live holdings feed.

#### Comparison identity and document order

Enable `comparePrevious` and retain the same watchlist, limits, `snapshotName` and named history store. First observations are `new`. Later runs include prior document fields, changed fields and the time of the prior saved observation. Set `onlyChanges` to save only new or changed observations; a fully unchanged run correctly returns zero rows.

Identity uses issuer CIK + CUSIP + schedule family + reporting-person CIK when supplied, otherwise the normalized disclosed name. Name or identity changes can create a new record. 13D and 13G are tracked separately. Changed holdings can reflect transactions, class changes, share-count denominators or filing corrections; a document difference alone is not a trade.

Company mode selects the first/latest encountered document for each person within the bounded recent-index scan. Direct URL mode uses the first document for that identity in the supplied input order; put the intended document first. A direct URL provides no verified publication timestamp, so `filingDate` and `acceptedAt` remain null. Event/signature dates are never substituted for publication time.

Only confirmed saved rows update comparison history. A discovered filing older than the saved filing date cannot roll the baseline backward. There is no removal inference. Use one writer per namespace; a detected concurrent state change is not overwritten.

#### Coverage, limits and failures

The dataset exports to JSON/CSV. **Run report** explains the outcome, and **SUMMARY** identifies successful, failed and unreached sources, filing caps, result limits and history updates. Source errors never become paid rows. Empty valid searches and unchanged comparisons are explicit outcomes.

SEC requests carry an identifying user agent, run sequentially at approximately one per second, and have bounded time and response size. Temporary server errors receive one retry. Access refusals are reported without bypass. Company discovery does not paginate archived submissions indexes or claim market-wide completeness.

#### Three example inputs

The first exact example is [Inspect W. R. Berkley Schedule 13D ownership](#try-this-actor) above. The other saved examples are:

##### Inspect a structured Schedule 13G amendment

Read the September 2026 Inflection Point amendment, including reported zero ownership. 13G has no 13D Item 4 purpose narrative.

```json
{
  "filingUrls": [
    "https://www.sec.gov/Archives/edgar/data/11544/000162828026060471/primary_doc.xml"
  ],
  "include13G": true,
  "maxResults": 5
}
```

##### Save a major-shareholder comparison baseline

Establish a saved reporting-person baseline from the documented 13D example. Later changes preserve prior document fields.

```json
{
  "filingUrls": [
    "https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"
  ],
  "comparePrevious": true,
  "snapshotName": "berkley-ownership-example",
  "maxResults": 20
}
```

#### Research use and sources

Combine ownership changes with earnings guidance, financing documents and insider disclosures to build a company evidence timeline. The Actor extracts and compares public disclosures; it does not label a stock as a buy or sell.

[SEC structured ownership release](https://www.sec.gov/submit-filings/edgar-news-announcements/edgar-release-23-4) · [SEC Schedule 13D/13G technical specification](https://www.sec.gov/file/schedule-13d-13g-tech-specs-20) · [SEC Developer Resources](https://www.sec.gov/about/developer-resources)

### Help with your run

Open **Run report** in the run’s Output tab for a readable outcome and **SUMMARY** for detailed coverage and source issues. Export CSV for flat spreadsheet columns or JSON to preserve nested evidence.

For help, open this Actor’s **Issues** tab with the run URL, relevant input and expected result. Remove credentials and private information before posting.

[Explore more Mayd-It Actors](https://apify.com/maydit)

# Actor input Schema

## `companies` (type: `array`):

Up to 10 US stock tickers or SEC CIKs. Searches each issuer’s recent submissions index within the lookback and filing cap. Does not traverse older index files. Choose this OR filing URLs. When both lists are empty, runs the documented historical SEC example.

## `filingUrls` (type: `array`):

Up to 30 raw SEC archive XML URLs; SEC XSL viewer prefixes are normalized to raw XML. Use either this list or companies. The first input document for an identity wins. Direct URLs have null filing-date and acceptance-time metadata.

## `include13G` (type: `boolean`):

Adds structured 13G/13G/A company filings and enables direct 13G documents. 13G has different reporting delays and no 13D Item 4 purpose narrative. Related persons’ holdings overlap and must not be summed.

## `lookbackDays` (type: `integer`):

Bounds company discovery by filing date. Direct URL documents are inspected regardless of age; event dates remain as filed.

## `maxFilingsPerCompany` (type: `integer`):

Bounds matching recent filings before XML inspection. Filings where this CIK is only a reporting owner are excluded after parsing, so a narrow cap can miss issuer matches. SUMMARY reports the cap and every inspected source.

## `maxResults` (type: `integer`):

Maximum confirmed saved rows. One row is one reporting person, issuer, security class and schedule-family observation. Source failures appear in SUMMARY, not in paid results.

## `comparePrevious` (type: `boolean`):

First saved observations establish history and are marked new. Later runs show prior values and changed fields. Only confirmed saved rows update history.

## `onlyChanges` (type: `boolean`):

Enables comparison and saves only new or changed observations. A fully unchanged repeat saves zero rows. Start with a baseline run before using this filter.

## `snapshotName` (type: `string`):

1-80 letters, numbers, underscores or hyphens. Use the same namespace AND input scope across runs. Use one writer at a time; no removal inference.

## `stateStoreName` (type: `string`):

3-63 letters, numbers or hyphens. Used only when comparisons are requested. Choose a dedicated store for each workflow.

## `maxRunSeconds` (type: `integer`):

Requests, rate waits and history work share this budget, also bounded by the platform deadline minus 25 seconds. SEC requests are serialized at about one per second, with one retry for 502/503/504.

## Actor input object example

```json
{
  "companies": [],
  "filingUrls": [
    "https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"
  ],
  "include13G": false,
  "lookbackDays": 365,
  "maxFilingsPerCompany": 4,
  "maxResults": 10,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "stateStoreName": "maydit-major-shareholder-history",
  "maxRunSeconds": 240
}
```

# Actor output Schema

## `results` (type: `string`):

Successful public metadata observations only. Failures are never synthetic paid rows.

## `runReport` (type: `string`):

Readable coverage, limits and history outcome from this run.

## `summary` (type: `string`):

Source coverage, actual counts, limits, failed sources and history outcome.

## `csvExport` (type: `string`):

Download the current run observations for spreadsheets.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "filingUrls": [
        "https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/major-shareholder-change-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "filingUrls": ["https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"] }

# Run the Actor and wait for it to finish
run = client.actor("maydit/major-shareholder-change-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "filingUrls": [
    "https://www.sec.gov/Archives/edgar/data/11544/000119312526092603/primary_doc.xml"
  ]
}' |
apify call maydit/major-shareholder-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/major-shareholder-change-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/oVHvi3lcUtmQ24Rx4/builds/VJhEACw44bnAT2ugm/openapi.json
