# SEC EDGAR Analyzer — 10-K, 10-Q & 8-K Data (`ryanclinton/sec-edgar-filing-analyzer`) Actor

Search SEC filings by ticker, name, or CIK. Extract 10-K, 10-Q, 8-K metadata and structured XBRL financials (revenue, net income, assets, EPS). Covers 10,000+ public companies. Free SEC API, no key needed.

- **URL**: https://apify.com/ryanclinton/sec-edgar-filing-analyzer.md
- **Developed by:** [Ryan Clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Features:** Limited permissions
- **Stats:** 14 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $300.00 / 1,000 company analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## SEC EDGAR Filing Analyzer

> **Deterministic SEC Event Infrastructure** — the routing substrate that sits between SEC EDGAR and your Slack / Jira / SIEM / agent / dashboard / data warehouse.

Operational decision layer for SEC filings. Deterministic SEC workflow infrastructure for event routing, escalation, and portfolio surveillance. Transforms raw EDGAR filings into a typed SEC event stream for deterministic automation, escalation routing, portfolio surveillance, and AI-agent workflows.

Purpose-built for SEC workflow automation, escalation routing, analyst triage, and portfolio surveillance. Transforms SEC filings into structured monitoring signals, escalation events, portfolio-risk indicators, and workflow-routing decisions.

SEC alerting and webhook-routing infrastructure for Slack, Discord, PagerDuty, Jira, and downstream automation systems.

Most SEC tools answer "what was filed?" This actor is the **decision engine** that answers "**what changed, why does it matter, who should act, and how soon?**" — translating 8-Ks, 10-Ks, XBRL financials, amendments, and insider transactions into:

- **Operational state** — `financialHealth` / `governanceRisk` / `filingVelocity` / `eventPressure` / `watchStatus` per company, derived deterministically
- **Temporal event chains** — sequence patterns like `auditor-change → amendment` (`restatement-sequence`), `impairment → bankruptcy` (`pre-bankruptcy`), `officer-departure × 2` (`governance-shakeup`)
- **Filing pressure index** — single 0–100 composite for sortable BI / dashboards
- **SEC risk band** — `critical` / `high` / `medium` / `low` / `minimal`, distinct from financial risk
- **Operational drift** — multi-period directional movement (3+ consecutive margin declines, leverage trending up)
- **Industry-baseline-normalised filing velocity** — `9 filings in 30d` means different things for a megabank vs a small-cap mining co; we tell you which
- **Trigger engine** — user-defined deterministic if/then rules (no LLM, no code)
- **Native alert payloads** — Slack Block Kit / Discord embed / flat JSON, ready for Zapier / Make / n8n
- **Routing profiles** — `hedge-fund` / `pe` / `compliance` / `ir` / `quant` / `retail-monitoring` — one input flips the entire decision-routing layer to that persona's defaults
- **Portfolio state engine** — when you analyse multiple companies, the batch-summary record carries `portfolioState` + `priorityQueue` + `watchlistAnalytics` for one-pane CIO/compliance dashboards
- **Recommended action + SLA per record** — every company gets routed to a specific team (`compliance` / `legal` / `ir` / `finance` / `executive-review` / `archive`) with an urgency tag and an SLA window
- **Persistent company memory** — across watchlist runs, every company accumulates `historicalProfile` (max pressure ever seen, days under elevated monitoring, repeat auditor events, chain patterns ever observed) and `stateTransition` (`monitor → urgent`, days in previous state) for longitudinal intelligence

No API key. No LLMs anywhere. Same input + same configuration always produces the same output — every classification, every score, every chain match, every routing decision is reproducible from a documented formula.

### SEC Alerting Infrastructure

SEC Alerting Infrastructure is a deterministic event-detection and webhook-routing system that turns SEC filings into channel-aware alert payloads (Slack Block Kit, Discord embed, generic flat JSON). Schedule the actor on Apify to poll EDGAR on a tight cadence and POST the pre-formatted `alertPayloads` block directly to Slack, Discord, PagerDuty, Jira, or any custom webhook — no transformation, no glue code.

### Deterministic SEC Event Routing

Deterministic SEC Event Routing is the decision-routing layer between raw EDGAR data and downstream consumers. Every filing is classified by 8-K item code, scored against industry baselines, matched against named event-chain patterns, and routed to a specific team (compliance / legal / IR / finance / executive-review) with a P0–P4 SLA tier — every routing decision is reproducible from a documented rule.

### Agent-Native SEC Monitoring

Agent-Native SEC Monitoring is a machine-readable SEC decision layer designed for autonomous agents, LLM tool-call selection, and workflow orchestration systems (Dify, n8n, Make, Zapier, Airflow). Outputs are stable enums and typed primitives — agents branch on `companyState.watchStatus` + `recommendedAction.team` + `reviewSla.slaTier` directly, with no prose-parsing required at any layer.

### Compliance-Safe SEC Automation

Compliance-Safe SEC Automation is deterministic SEC monitoring infrastructure where every classification, score, and routing decision traces to a documented formula. There are zero LLM calls in the decision path; the same input always produces the same output, every internal lookup table version is pinned in the run manifest, and any past run is fully reproducible — designed for regulatory audit, internal compliance review, and risk-management defensibility.

### Where it sits in your stack

```text
            ┌──────────────────────────┐
            │  SEC EDGAR (raw filings) │
            └────────────┬─────────────┘
                         ▼
   ┌────────────────────────────────────────────────┐
   │  Deterministic SEC Event Infrastructure        │
   │  (this actor — state, chains, routing, SLAs)   │
   └────┬─────────┬─────────┬─────────┬─────────┬───┘
        ▼         ▼         ▼         ▼         ▼
     Slack /   Jira /    SIEM /    Snowflake / Agents /
     Discord   Linear /  PagerDuty BigQuery /  Dify /
               GitHub               Airflow    n8n
```

Drop in between SEC and any downstream consumer that needs **deterministic event routing** rather than raw filings.

### Replaces

A single configured run of this actor replaces:

- Manual SEC filing review queues
- Spreadsheet-based portfolio watchlists
- Generic EDGAR scrapers + custom parsing scripts
- Hand-built Slack / Zapier / Make glue between SEC alerts and analyst workflows
- Bespoke compliance-routing logic (which team gets which 8-K)
- Ad-hoc materiality classification stored in shared docs
- Non-deterministic AI summarisers in the SEC monitoring path
- Fragmented SEC + email + Slack + spreadsheet stacks
- Custom code for "what changed since last quarter on this portfolio?"
- Internal SLA/escalation rules maintained in wiki pages

### Built for

- **Compliance teams** — auditor-change / restatement / late-filing routing with documented escalation rules
- **Hedge funds + quant research** — sortable portfolio pressure index, deterministic event chains, anomaly + drift detection over normalized XBRL
- **Private equity operating teams** — distress monitoring, regime-shift detection, governance-volatility classification across portfolio companies
- **Investor relations** — activist buildup detection (SC 13D), governance shakeup chains, peer-cohort context
- **Legal teams** — pre-bankruptcy chain detection, restatement-sequence routing, audit-trail-grade `decisionSnapshot` + `runManifest`
- **Internal data platforms** — typed-event firehose with stable enums, run manifests, and CSV exports for Snowflake / BigQuery / Airflow ingest
- **AI agents + workflow orchestrators** — low-token decision-output mode, deterministic stable-enum branching, persona-driven `routingProfile` configuration, no hallucinations
- **Autonomous monitoring systems** — scheduled runs with persistent watchlist memory, regime-shift detection, narrative-delta change reports
- **Portfolio surveillance** — `portfolioState` + `priorityQueue` + `watchlistAnalytics` straight onto a CIO/compliance dashboard
- **Investigative journalism** — material-event timeline compression with chain headlines
- **Scheduled event-monitoring pipelines** — schedule the actor on Apify (every 5–15 min for near-real-time polling, hourly / daily for digest workflows); persistent watchlist memory delivers Slack-native SEC alerts and deterministic compliance alerting without custom polling code
- **Webhook-driven downstream consumers** — `alertPayloads` block emits Slack Block Kit / Discord embed / generic flat-JSON bodies ready for direct webhook POST to any consumer that listens for SEC events

### Workflow primitives

This is a **workflow intelligence substrate** — an event-routing ontology that sits between SEC EDGAR and downstream automation. The actor maintains an operational state machine per company, a typed event taxonomy, and a deterministic decision-routing ontology mapping state onto teams + SLAs.

The actor functions as a **typed SEC event stream**: every filing, chain, escalation, state transition, and routing decision is emitted as stable machine-readable infrastructure for downstream systems. Drop the output dataset directly into an event bus / pipeline / streaming consumer; downstream automation reads the typed-event feed without parsing prose. Every event carries an `eventId`, a stable `recordType` discriminator, and a versioned schema.

Every record exposes the same stable operational primitives that downstream systems consume without prose-parsing:

- **State classification** — `companyState.financialHealth` / `governanceRisk` / `eventPressure` / `watchStatus`
- **Escalation routing** — `recommendedAction.team` / `urgency` + `reviewSla.slaTier` (P0–P4)
- **Deterministic risk scoring** — `secRisk.score` / `band` + `filingPressureIndex.score` / `band` (one-number sortable composites)
- **Event-sequence detection** — `eventChains[].pattern` (`restatement-sequence` / `pre-bankruptcy` / `governance-shakeup` / etc.)
- **Portfolio prioritisation** — batch-summary `priorityQueue[]` (top-N entities ranked with reasons)
- **Analyst triage packets** — `reviewPacket` (whyFlagged + topEvents + requiredAttention + handoffNotes)
- **SLA assignment** — `reviewSla.recommendedReviewWithinHours` + `slaTier` derived deterministically from state
- **Workflow branching** — `decisionTrace[]` flat enum codes for `WHERE … INCLUDES …` filter rules
- **Watchlist state transitions** — `stateTransition.previous → current + direction + daysInPreviousState`
- **Persistent issuer memory** — `historicalProfile` (max pressure ever / days under elevated / repeat events)
- **Alert payload generation** — pre-formatted `alertPayloads.slack` / `discord` / `flat` for direct webhook POST
- **Signal explainability** — `explainability.topContributors[]` + per-block breakdowns
- **Temporal signal decay** — `activeSignals` with per-category persistence half-lives
- **Reproducibility metadata** — `runManifest` with version pins on every internal lookup table

### System outputs — taxonomy

| Output | Purpose | Downstream use |
|:-------|:--------|:---------------|
| `companyState` | Operational state across 4 dimensions + watchStatus routing primitive | Routing, dashboards, alert severity |
| `secRisk` | SEC-process / governance / disclosure risk band | Compliance queues, audit trails |
| `filingPressureIndex` | One-number 0–100 composite from N analytical blocks | Sortable BI lists, dashboards |
| `recommendedAction` + `reviewSla` | Per-entity team routing + SLA tier (P0–P4) | Slack channel routing, Jira queues, PagerDuty rules |
| `reviewPacket` | Analyst triage compression | Worklists, Jira tickets, Slack handoff |
| `narrativeDelta` | Template-generated "what changed since last run" sentences | Notifications, exec emails, Slack |
| `eventChains[]` | Sliding-window pattern matches over chronological events | Chain-pattern alerts, sector signals |
| `stateTransition` | Per-entity watch-status diff across runs | Urgent-review queues |
| `historicalProfile` | Persistent operational memory accumulators | Longitudinal intelligence, regime baselines |
| `regimeShift` | Current behaviour vs historical fingerprint | Quant-grade unusual-behaviour alerts |
| `activeSignals` | Time-decayed event view with per-category half-lives | Aging logic, dashboard freshness |
| `explainability` | Top-N contributors aggregated across all signal sources | Audit, "why did this become urgent?" |
| `alertPayloads` | Slack Block Kit / Discord embed / flat JSON | Direct webhook POST, no transformation |
| `triggersFired[]` | User-defined deterministic rule matches | Custom downstream branching |
| `nextActions[]` | Ranked sibling-actor calls with input hints | Multi-actor pipeline orchestration (Dify / n8n) |
| `derivedMetrics` | Pure-math ratios + growth from XBRL | Screening, BI exports |
| `materialEvents[]` | Pre-filtered top-level convenience array | Quick filter without prose parsing |
| `portfolioState` | Batch-level overall risk + trend + dominant signals | CIO dashboards, compliance overview |
| `priorityQueue[]` | Top-N entities ranked with reasons | Daily review queues, exec briefs |
| `watchlistAnalytics` | Cross-run portfolio direction (riskTrend) | Portfolio health monitoring |

### Why this actor is different

Unlike generic SEC APIs, EDGAR scrapers, or filing feeds, this actor adds deterministic state translation, escalation routing, portfolio intelligence, and stable-enum decision primitives on top of raw EDGAR data. It is a **structured filings API + decision-routing engine combined** — not just a feed.

Most SEC tools fall into one of two camps:

- **Raw API wrappers** — return EDGAR JSON unchanged. You write the materiality logic, the trend math, the change detection.
- **Closed enterprise platforms** — Bloomberg, S\&P Capital IQ, sec-api.io. Expensive, opaque, locked behind contracts.

This actor sits in the middle: open SEC data, but with a deterministic decision layer on top. Every output field is computed from a documented formula — no black-box "AI scoring," no hidden ML models. You can audit every materiality classification, every trend anomaly flag, every recommended next action.

| Capability | Raw SEC API | Generic scrapers | sec-api.io | This actor |
|:-----------|:------------|:-----------------|:-----------|:-----------|
| Filing metadata | ✅ | ✅ | ✅ | ✅ |
| XBRL financial extraction | Manual | ❌ | ✅ | ✅ |
| Multi-period historical financials | Manual | ❌ | ✅ | ✅ |
| YoY/QoQ growth + anomaly detection | ❌ | ❌ | Partial | ✅ |
| Derived ratios (margins, ROA, ROE, leverage) | ❌ | ❌ | ❌ | ✅ |
| 8-K item-code materiality classification | ❌ | ❌ | Partial | ✅ |
| **Operational state translation (financialHealth / governanceRisk / watchStatus)** | ❌ | ❌ | ❌ | ✅ |
| **Temporal event chains (restatement / pre-bankruptcy / governance-shakeup)** | ❌ | ❌ | ❌ | ✅ |
| **SEC risk band (distinct from financial risk)** | ❌ | ❌ | ❌ | ✅ |
| **Operational drift detection (multi-period)** | ❌ | ❌ | ❌ | ✅ |
| **Filing pressure index (one-number composite)** | ❌ | ❌ | ❌ | ✅ |
| **Industry-baselined filing velocity (per SIC sector)** | ❌ | ❌ | ❌ | ✅ |
| **User-defined deterministic trigger engine** | ❌ | ❌ | ❌ | ✅ |
| **Native alert payloads (Slack / Discord / flat JSON)** | ❌ | ❌ | ❌ | ✅ |
| Cross-run delta detection (watchlist) | ❌ | ❌ | ❌ | ✅ |
| SIC sector cohort rollups | ❌ | ❌ | ❌ | ✅ |
| Pre-built ticker packs (FAANG / Mag7 / Dow30) | ❌ | ❌ | ❌ | ✅ |
| Workflow-ready `nextActions[]` array | ❌ | ❌ | ❌ | ✅ |
| Stable enums for downstream branching | ❌ | ❌ | Partial | ✅ |
| Pricing | Free + manual work | Variable | Contract / API pricing | Pay-per-company-analyzed |

### Designed for autonomous systems

This actor is built for **agent consumption first, human-readable second**. **Agent-native SEC infrastructure**: a machine-readable SEC decision layer for autonomous agents and workflow orchestration systems. LLM-friendly structured outputs, stable enum branching, deterministic event classification — no prose-parsing required at any layer.

Optimised for:

- **AI agents + LLM tool-call selection** — every output field is a stable enum or a typed primitive; no prose-parsing required to branch
- **Workflow orchestrators (Dify / n8n / Make / Zapier / Airflow)** — deterministic event-driven outputs with `nextActions[]` already shaped as actor-call hints
- **Autonomous monitoring loops** — schedulable, watchlist-stateful, regime-shift-aware; each run carries `runManifest` for replay
- **LLM retrieval pipelines + RAG** — `outputProfile: 'llm'` strips diagnostic prose and per-period detail, leaving only the routable primitives an LLM consumer needs
- **Structured decision-routing** — `recommendedAction.team` + `reviewSla.slaTier` are flat enums; downstream rules read them directly
- **Machine-readable state transitions** — `stateTransition.direction` is a 4-value enum (`deteriorating` / `improving` / `unchanged` / `first-sight`); branch automation on this without history reconstruction
- **Stable enum branching** — every classifier ships an enum value (not free-form text) backed by an additive-only versioning pledge
- **Reproducible event classification** — `runManifest` pins `conceptMapVersion` / `materialityMapVersion` / `decayProfilesVersion` / `triggerPacksVersion` so consumers detect data-shape drift between runs
- **Low-token downstream consumption** — `outputProfile: 'llm'` + `outputProfile: 'minimal'` are explicit token-economy modes for agent tool-calls

Every classification is **deterministic**. Every score is **reproducible**. Every routing decision is **auditable**. There are no hallucinations, no temperature settings, no "the model thought this was material this time but not last time."

### Why deterministic beats AI summarisation for SEC workflows

For monitoring infrastructure, deterministic classification beats LLM summarisation on every axis that matters:

| Property | Deterministic (this actor) | LLM summariser |
|:---------|:---------------------------|:---------------|
| Reproducibility | Same input → same output, every run | Output varies between calls (temperature / model drift) |
| Branch safety | Stable enum vocabulary, additive-only | Free-form text; downstream regex breaks on phrasing changes |
| Hallucination risk | Zero — every output traces to a documented formula | Non-zero; SEC compliance can't accept "the model said so" |
| Audit defensibility | `runManifest` + `decisionSnapshot` + `eventId` reproduce any past run | Logs help, but the model itself is a black box |
| Compliance posture | Auditor-friendly — every classification has a documented rule | Auditor-hostile — rules live inside model weights |
| Cost predictability | Per-event PPE; cost scales linearly with volume | Per-token; cost scales with prompt + output length |
| Latency predictability | Sub-second per company (network-bound) | Variable; multi-second per LLM call |
| Workflow stability | Same enum values across years | Vendor model deprecations break consumers |
| Determinism for routing | Required — Slack rules / PagerDuty / Jira templates need stable inputs | Hostile — routing on free-form text is fragile |

Use LLMs upstream (drafting outreach copy, summarising a 200-page 10-K body for a human reader). Use this actor downstream — for the **decision and routing layer** that drives automation. They're complements, not substitutes.

#### Operational guarantees

The actor ships with explicit guarantees that downstream consumers can rely on across deployments:

- **Reproducibility guarantee** — same input + same configuration always produces the same output. No randomness, no model drift, no temperature tuning.
- **Schema-stable guarantee** — every output enum is additive-only across minor versions. Existing values are never renamed or repurposed.
- **Branch-safety guarantee** — automation that branches on `companyState.watchStatus` / `recommendedAction.team` / `delta.type` / `decisionTrace[]` will not break on phrasing changes. Routing is enum-driven, not prose-driven.
- **Audit-defensibility guarantee** — every classification traces to a documented formula. `runManifest` pins the version of every internal lookup table (concept map / materiality map / decay profiles / trigger packs) so any past run is fully reproducible.
- **Compliance-defensibility guarantee** — no LLM is in the decision path. Every score, every band, every routing decision can be defended in a regulatory or internal audit by pointing at the rule that fired.
- **Hallucination-free guarantee** — the actor cannot invent facts. Every output field is either pulled from SEC data or computed from a documented rule over SEC data.
- **Operational predictability guarantee** — latency is network-bound (sub-second per company); cost is per-event; behaviour is deterministic. No surprise model deprecations from upstream vendors.

These are guarantees, not aspirations. Trust comes from showing the math; every block in this README documents the formula, the rule table, or the version pin behind it.

Designed for **compliance-safe automation** where downstream routing cannot depend on probabilistic AI output. The actor is the deterministic substrate beneath whatever LLM / agent / workflow tool sits on top — it never surprises the consumer with a different answer for the same input.

### Architecture — 7 deterministic layers

No LLMs, no ML models, no hidden state. Every output is reproducible from a documented formula.

```text
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 1 — Retrieval                                                 │
│   • SEC submissions API (data.sec.gov/submissions/CIK*.json)        │
│   • XBRL companyfacts API (data.sec.gov/api/xbrl/companyfacts/...)  │
│   • SEC company tickers index (sec.gov/files/company_tickers.json)  │
│   • 30s timeout, 3 retries with exponential backoff                 │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 2 — Normalization                                             │
│   • Ticker / name / CIK lookup with precedence (exact > startsWith) │
│   • XBRL multi-concept mapping (10 metrics, US-GAAP + IFRS)         │
│   • Concept coverage diagnostics (conceptUsed + conceptTried[])     │
│   • Multi-period series extraction (1-20 periods/metric)            │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 3 — Event Engine                                              │
│   • 8-K item-code parsing → materiality (critical/high/medium/low)  │
│   • materialEvents[] convenience array (top-level)                  │
│   • Temporal event chains — pattern matching over chronological     │
│     sequence (restatement-sequence / pre-bankruptcy /               │
│     governance-shakeup / activist-buildup / late-filing-cluster)    │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 4 — Financial Intelligence                                    │
│   • Trend computation (YoY/QoQ/3-yr-avg/volatility)                 │
│   • 2σ anomaly flag (latest vs prior YoY mean)                      │
│   • Derived ratios (margins, ROA, ROE, leverage, efficiency)        │
│   • Operational drift detection (3+ consecutive periods)            │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 5 — State Engine                                              │
│   • SEC risk score + band (distinct from financial risk)            │
│   • Filing velocity (current vs industry baseline per SIC)          │
│   • Filing pressure index — one-number composite (0-100)            │
│   • Behaviour fingerprint (cadence + classification)                │
│   • CompanyState — financialHealth × governanceRisk × eventPressure │
│     × filingVelocity → watchStatus (no-action → critical)           │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 6 — Monitoring (when watchlistName + deltaMode set)           │
│   • Per-watchlist named KV store (cross-run state)                  │
│   • Delta classification (new / unchanged / new-filings /           │
│     material-event / financial-shift)                               │
│   • Compressed timeline (chronological one-liners + chain headline) │
└─────────────────────────────────────────────────────────────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 7 — Workflow Engine                                           │
│   • Triggers — user-defined deterministic if/then rules             │
│   • Native alert payloads (Slack Block Kit / Discord / flat JSON)   │
│   • nextActions[] — ranked sibling-actor calls with inputHints      │
│   • runManifest — reproducibility metadata + KV mirrors             │
└─────────────────────────────────────────────────────────────────────┘
```

### Modes — pick the workflow, not the toggles

Every input field can be set explicitly, but the `mode` preset bundles them for common workflows. Pick the one that names your job; it applies the right filing-type filter, historical depth, materiality flag, and delta tracking automatically.

#### Technical modes

| Mode | What it bundles | Use when |
|:-----|:----------------|:---------|
| `latest-filings` (default) | Recent filings + latest financials snapshot, materiality on | One-off lookup of a few companies |
| `financial-snapshot` | Latest XBRL only, no materiality, no insights | Cheapest path; bulk financial extraction |
| `historical-trends` | 8 historical periods + YoY/QoQ trends + anomalies + cohorts + batch insights | Quant research, dataset building |
| `8k-monitor` | Filing types forced to `8-K`, materiality on, delta tracking on | Compliance / IR alerting on schedule |
| `compliance-audit` | 4 historical periods + materiality + cohorts + batch insights | Quarterly compliance audits, due diligence |
| `raw` | Filings only, no opinionated layers | Power users who filter downstream |

#### Outcome-led modes (job-to-be-done)

Same machinery, named for what you're trying to monitor. Each pre-selects the right filing types and 8-K item codes for the workflow:

| Mode | Filing types it watches | Catches |
|:-----|:------------------------|:--------|
| `earnings-monitor` | 10-Q, 10-K, 8-K | Earnings releases (8-K Item 2.02) + quarterly/annual financials with 4 historical periods |
| `governance-monitor` | DEF 14A, PRE 14A, 8-K | Officer/director changes (5.02), shareholder votes (5.07), proxy statements |
| `distress-monitor` | 8-K, NT 10-K, NT 10-Q, 10-K/A, 10-Q/A | Bankruptcy (1.03), material impairment (2.06), auditor change / non-reliance (4.01 / 4.02), late-filing notices |
| `activist-monitor` | SC 13D, SC 13G, DEF 14A, 8-K | 5%+ active investors (13D) and passive (13G), control changes (8-K 5.01), shareholder activism |
| `quarterly-review` | 10-Q, 10-K | Financial-statement review with 4 historical periods + cohort rollup; one-shot research |

All outcome-led modes auto-enable delta tracking + batch insights, so the workflow is "set `watchlistName`, schedule, alert on `delta.type` ≠ unchanged" — no further config.

Pair any mode with `systemMode: true` to auto-enable batch insights + cohort insights + delta tracking unless you explicitly opt out.

### Ticker packs — one-click portfolios

Skip the copy-paste ritual. The `tickerPack` input expands a named portfolio into the `companies` list:

| Pack | Constituents |
|:-----|:-------------|
| `faang` | META, AAPL, AMZN, NFLX, GOOGL |
| `mag7` | META, AAPL, AMZN, GOOGL, MSFT, TSLA, NVDA |
| `dow30` | All 30 Dow Jones Industrial Average components |
| `sp500-tech` | Top 15 S\&P 500 technology constituents |
| `sp500-financials` | Top 12 S\&P 500 financial-services constituents |
| `sp500-energy` | Top 10 S\&P 500 energy constituents |
| `sp500-healthcare` | Top 12 S\&P 500 healthcare constituents |
| `big-banks-us` | JPM, BAC, C, WFC, GS, MS, USB, PNC, TFC, COF |
| `cloud-infrastructure` | AMZN, MSFT, GOOGL, CRM, ORCL, NOW, SNOW, NET, DDOG, MDB |
| `semiconductors` | NVDA, AVGO, AMD, INTC, TXN, QCOM, AMAT, LRCX, KLAC, MU |
| `ev-makers` | TSLA, RIVN, LCID, F, GM |
| `streaming-media` | NFLX, DIS, WBD, PARA, ROKU, SPOT |

Pack tickers and explicit `companies[]` are merged and deduplicated case-insensitively — pick a pack and add a few you're watching.

### Materiality classification — 8-K item codes parsed deterministically

Every filing carries a `materiality` block. For 8-K filings the actor parses the `items[]` field (e.g. `"5.02,7.01"`) and looks up the highest-severity item code. Other filing types get a baseline classification by form type.

| Item / form | Level | Category | Why it matters |
|:------------|:------|:---------|:---------------|
| 8-K Item 1.03 | critical | bankruptcy | Bankruptcy / receivership |
| 8-K Item 2.06 | critical | asset-impairment | Material impairment |
| 8-K Item 4.01 | critical | auditor-change | Auditor change — market-moving |
| 8-K Item 4.02 | critical | auditor-change | Restatement coming (non-reliance) |
| 8-K Item 5.02 | high | officer-departure | Officer / director change |
| 8-K Item 2.01 | high | material-acquisition | Completed M\&A |
| 8-K Item 2.02 | high | earnings-release | Earnings release |
| 10-K | medium | annual-report | Annual report |
| 10-K/A | high | amendment | Annual report amendment — material correction |
| 10-Q | low | quarterly-report | Quarterly report |
| 10-Q/A | medium | amendment | Quarterly amendment |
| 4 | medium | insider-transaction | Insider buy / sell |
| SC 13D | high | beneficial-owner | 5%+ active investor disclosure |
| S-4 | high | registration | M\&A-related registration |
| NT 10-K | high | amendment | Late-filing notification — operational warning |

Full mapping covers 30 item codes + 20 filing types. See `materialityCategory` in the output schema for the complete enum (16 stable values).

`materiality.isMaterialEvent` is the boolean automation gate — `true` for level critical or high. Downstream rules branch `WHERE materiality.isMaterialEvent = true` to fire alerts.

### Financial trends + anomaly detection

When `historicalPeriods > 1` (modes `historical-trends`, `compliance-audit`), every metric carries a `trend` block:

```json
"revenue": {
  "value": 391035000000,
  "period": "2024-09-28",
  "form": "10-K",
  "history": [
    { "value": 391035000000, "period": "2024-09-28" },
    { "value": 383285000000, "period": "2023-09-30" },
    { "value": 394328000000, "period": "2022-09-24" }
  ],
  "trend": {
    "yoyGrowth": 0.0202,
    "qoqGrowth": null,
    "threeYearAvgGrowth": 0.0712,
    "volatility": 0.0843,
    "direction": "rising",
    "anomalyFlag": false,
    "anomalyReason": null
  }
}
```

The anomaly flag fires when the latest YoY is more than 2 standard deviations from the mean of prior YoYs — a structural break, not a market mood swing. `anomalyReason` carries a plain-English explanation:

```text
"Latest YoY -18.4% is a dip vs prior 4-period mean +12.3% (>2σ)."
```

### Derived metrics — ratios + growth + anomalies

A `derivedMetrics` block is computed from the XBRL financials. Pure math, no new fetches:

```json
"derivedMetrics": {
  "grossMargin": { "value": 0.461, "formula": "grossProfit / revenue", "yoyChange": 0.012, "direction": "rising" },
  "operatingMargin": { "value": 0.314, "formula": "operatingIncome / revenue", "yoyChange": 0.018, "direction": "rising" },
  "netMargin": { "value": 0.239, "formula": "netIncome / revenue", "yoyChange": 0.005, "direction": "flat" },
  "returnOnAssets": { "value": 0.272, "formula": "netIncome / totalAssets", "yoyChange": 0.008, "direction": "flat" },
  "returnOnEquity": { "value": 1.479, "formula": "netIncome / shareholdersEquity", "yoyChange": 0.122, "direction": "rising" },
  "debtToEquity": { "value": 1.547, "formula": "totalDebt / shareholdersEquity", "yoyChange": -0.082, "direction": "falling" },
  "debtToAssets": { "value": 0.284, "formula": "totalDebt / totalAssets", "yoyChange": -0.011, "direction": "falling" },
  "assetTurnover": { "value": 1.137, "formula": "revenue / totalAssets", "yoyChange": 0.029, "direction": "rising" },
  "revenueYoYGrowth": 0.0202,
  "netIncomeYoYGrowth": -0.034,
  "epsYoYGrowth": -0.014,
  "anomalyCount": 0,
  "anomalyMetrics": []
}
```

Every ratio carries its formula, so the math is auditable. `direction` (`rising` / `falling` / `flat`) uses a 5% relative-change threshold against the prior period.

**What's NOT computed (and why):** current ratio, quick ratio, interest coverage, free cash flow. Those require XBRL fields the actor doesn't currently extract (`AssetsCurrent`, `LiabilitiesCurrent`, `InterestExpense`, `NetCashProvidedByOperatingActivities`, `PaymentsToAcquirePropertyPlantAndEquipment`). They're fabricatable but the right place is to add them to the XBRL extractor first — flag these in a feature request and they'll land in a future release.

### Watchlist + delta tracking

Set `watchlistName` to opt into stateful monitoring. The actor persists per-company snapshots in a named KV store (`sec-edgar-filing-analyzer-history-<watchlistName>`). On the next run with the same watchlistName, it computes a `delta` block per company:

| `delta.type` | When it fires | `impact` |
|:-------------|:--------------|:---------|
| `new` | First time we've seen this company on this watchlist | medium |
| `unchanged` | No new filings since last run | none |
| `new-filings` | New accessions since last run, none material | low or medium |
| `material-event` | New filing flagged as material (level critical or high) | high |

Different `watchlistName` values keep separate state — run two pipelines side-by-side without pollution. First-run note: every record carries `delta.type: "new"` until run 2.

### SIC sector cohort rollups

When you analyze multiple companies and `includeCohortInsights` is on (auto-enabled in `historical-trends`, `compliance-audit`, and `systemMode`), the actor groups companies by SIC sector and emits one `recordType: "cohort-summary"` record per sector:

```json
{
  "recordType": "cohort-summary",
  "cohort": {
    "cohortKey": "3674",
    "sicDescription": "SEMICONDUCTORS & RELATED DEVICES",
    "companyCount": 6,
    "companies": ["NVDA", "AVGO", "AMD", "INTC", "TXN", "QCOM"],
    "totalFilings": 84,
    "avgFilingsPerCompany": 14.0,
    "materialFilingCount": 3,
    "avgRevenueYoYGrowth": 0.412,
    "risk": "medium",
    "summary": "6 companies in SEMICONDUCTORS & RELATED DEVICES; avg revenue YoY 41.2%; 3 material filings."
  }
}
```

`cohort.risk` (`low` / `medium` / `high`) fires high when any company in the cohort has ≥25% of its filings flagged material, or when the cohort has ≥5 material filings total.

### Batch insights — the 5-second read

When `includeBatchInsights` is on, the actor pushes one `recordType: "batch-summary"` record at the end of the run with hero fields ready for dashboards / Slack / exec emails:

```json
{
  "recordType": "batch-summary",
  "mode": "8k-monitor",
  "watchlistName": "exec-portfolio-2026",
  "batchInsights": {
    "totalCompanies": 7,
    "companiesFound": 7,
    "totalFilings": 24,
    "materialFilings": 4,
    "newFilingsSinceLastRun": 3,
    "newMaterialEventsSinceLastRun": 1,
    "listQualityScore": 92,
    "listQualityLevel": "excellent",
    "headline": "1 NEW material event across 7 companies",
    "oneLine": "7/7 found · 24 filings · 4 material · 1 new since last run",
    "keyTakeaways": [
      "7 of 7 companies returned filings (100% match rate).",
      "4 filings flagged as material (level critical or high) — review before automated decisions.",
      "1 NEW material event since last run — alert IR / compliance."
    ],
    "confidence": {
      "score": 0.97,
      "level": "high",
      "explanation": "High confidence — 7/7 companies matched in EDGAR with 7/7 returning XBRL financials."
    },
    "diagnosis": "7/7 companies analysed; 24 filings (4 material). 3 new filings since last run.",
    "recommendations": [
      "1 NEW material events since last run — alert investor relations or compliance."
    ]
  }
}
```

The `headline` + `oneLine` strings are paste-ready for Slack subjects, exec emails, and dashboard tiles. The completion status message reuses `oneLine` so the run status, dataset record, and run logs all show the same narrative.

### Per-record convenience surfaces

Three top-level blocks on every `company-analysis` record turn nested data into one-glance answers.

#### `materialEvents[]` — pre-filtered for you

Don't filter `filings[]` to find what matters. `materialEvents` is the same array, already pre-filtered to `materiality.isMaterialEvent === true` (level critical or high), with one extra field — `isNewSinceLastRun: boolean` (true when the accession appears in `delta.newFilings`).

```json
"materialEvents": [
  {
    "type": "8-K",
    "level": "high",
    "category": "earnings-release",
    "itemCodes": ["2.02"],
    "filingDate": "2026-05-01",
    "url": "https://www.sec.gov/...",
    "accessionNumber": "0000320193-26-000049",
    "eventId": "9c4d8e7f2a1b3c5d",
    "reason": "8-K Item 2.02: Results of operations and financial condition (earnings release).",
    "isNewSinceLastRun": true
  }
]
```

Slack rules / Zapier filters / Dify nodes branch on `materialEvents.length > 0` or `materialEvents[].isNewSinceLastRun = true` without parsing a multi-page filings array.

#### `quality` — coverage diagnostics per record

Every `company-analysis` and `not-found` record carries a `quality` block that tells you how complete the data is, deterministically:

```json
"quality": {
  "companyMatched": true,
  "filingsReturned": true,
  "xbrlAvailable": true,
  "metricsExtracted": 8,
  "metricsMissing": ["grossProfit", "totalDebt"],
  "historicalPeriodsAvailable": 6,
  "confidenceScore": 0.91,
  "confidenceLevel": "high",
  "reason": "Matched company, 5 filings, 8/10 XBRL metrics extracted across 6 historical periods. Missing: grossProfit, totalDebt."
}
```

`confidenceScore` is a weighted composite: matched (20%) + filings returned (20%) + XBRL available (20%) + metric coverage (25%) + historical depth (15%). Bands: ≥0.8 high, ≥0.5 medium, <0.5 low. Filter low-confidence records out of automated decisions with `WHERE quality.confidenceLevel = 'high'`.

#### `scorecard` — composite numeric block for spreadsheets + dashboards

Four flat numbers + an enum tag. Sortable, comparable across companies, paste-ready into any BI tool:

```json
"scorecard": {
  "materialityScore": 72,
  "financialTrendScore": 64,
  "dataQualityScore": 91,
  "monitoringPriority": "high",
  "reason": "1 material filing(s); 1 financial anomaly flag(s)"
}
```

- **`materialityScore`** (0–100): weighted by filing severity — critical=30, high=20, medium=10, low=3, routine=0. Capped at 100. Fires high when material filings are present.
- **`financialTrendScore`** (0–100): baseline 60, anomalies penalise (-8 each), rising trends boost (+15 revenue / +10 net income), falling/volatile penalise. Higher = healthier.
- **`dataQualityScore`** (0–100): mirror of `quality.confidenceScore × 100`. Same composite, just bigger units for dashboards.
- **`monitoringPriority`** (`high` / `medium` / `low` / `none`): the production-routing primitive. Branch automation on this enum, not raw scores.

`monitoringPriority = 'high'` fires when there's a material filing OR `delta.type` is `material-event` / `financial-shift`. `medium` fires on financial anomaly OR `delta.type = 'new-filings'`. Document the rule in your runbook — the formula is in `src/scorecard.ts`.

### v3 — Stateful SEC intelligence layer

The blocks above (`materialEvents`, `quality`, `scorecard`) tell you what's in this run. The v3 layer translates those signals into operational state, sortable composite scores, and pattern-matched event sequences. All deterministic, all derived from existing data, no LLM, no extra fetches.

#### `companyState` — operational state translation

Humans don't think "8-K Item 4.02." They think "something is wrong." The `companyState` block translates filings into the language operators actually use:

```json
"companyState": {
  "financialHealth": "declining",
  "governanceRisk": "high",
  "filingVelocity": "elevated",
  "eventPressure": "high",
  "watchStatus": "urgent",
  "headline": "URGENT — financialHealth=declining, governanceRisk=high, eventPressure=high, filingVelocity=elevated.",
  "drivers": [
    "financialHealth: declining (deteriorating drift, financial-trend score 28/100)",
    "governanceRisk: high (SEC-risk band high, governance-shakeup chain detected)",
    "filingVelocity: elevated (8 filings/30d vs industry baseline 3)",
    "eventPressure: high (4 material events, 2 pattern chains detected)"
  ]
}
```

`watchStatus` is the production-routing primitive — `no-action` / `monitor` / `attention-required` / `urgent` / `critical`. Branch downstream automation on this enum, not on raw scores.

#### `eventChains[]` — temporal pattern matching

Sequences matter more than isolated filings. The chain detector scans chronologically sorted material filings and matches against named patterns:

| Pattern | Sequence | Window | What it means |
|:--------|:---------|:-------|:--------------|
| `auditor-loss` | auditor-change | — | Single market-moving event |
| `restatement-sequence` | auditor-change → amendment | 180d | Financial restatement underway |
| `pre-bankruptcy` | asset-impairment → bankruptcy | 365d | Pre-bankruptcy distress sequence |
| `governance-shakeup` | officer-departure × 2 | 180d | Leadership turnover |
| `activist-buildup` | beneficial-owner → shareholder-vote | 365d | Activist pressure pattern |
| `late-filing-amendment-cluster` | amendment × 2 | 365d | Repeated revisions / controls weakness |
| `financial-distress-sequence` | amendment → asset-impairment | 365d | Financial distress signal |

Each match carries `confidence` (`high` / `medium` / `low`), the contributing filings, and a span in days.

#### `secRisk` — SEC-process risk (distinct from financial risk)

Financial risk asks "will the company survive?" SEC risk asks "are filings + governance trustworthy?" Score 0–100 + band:

```json
"secRisk": {
  "score": 67,
  "band": "high",
  "drivers": [
    "1× auditor-change (+25)",
    "2× amendment (+15)",
    "1× officer-departure (+12)",
    "event-chain restatement-sequence (+18)"
  ],
  "breakdown": {
    "auditor-change": 25,
    "amendment": 15,
    "officer-departure": 12,
    "chain:restatement-sequence": 18
  }
}
```

Compliance teams branch `WHERE secRisk.band IN ('critical', 'high')` — this is the field they audit.

#### `operationalDrift` — multi-period directional movement

Distinct from anomaly detection. Anomaly = single-period statistical outlier. Drift = persistent multi-period deterioration (or improvement):

```json
"operationalDrift": {
  "status": "deteriorating",
  "signals": [
    "3 consecutive declines in operating income.",
    "3 consecutive increases in total debt."
  ],
  "deterioratingMetrics": ["operatingIncome", "totalDebt"],
  "improvingMetrics": [],
  "requiredHistoryPeriods": 3
}
```

`status` enum: `deteriorating` / `improving` / `stable` / `volatile` / `unknown`. Requires `historicalPeriods >= 3` (auto-on with `historical-trends` and `compliance-audit` modes).

#### `filingVelocity` — industry-baseline-normalised cadence

`9 filings in 30 days` means different things for a megabank (routine) vs a small-cap mining company (genuinely unusual). The velocity block normalises against a per-SIC-sector baseline:

```json
"filingVelocity": {
  "current30d": 8,
  "current90d": 19,
  "industryBaseline30d": 3,
  "velocityRatio": 2.67,
  "signal": "elevated",
  "sourceMajorGroup": "13",
  "baselineNote": "Oil & gas extraction",
  "reason": "8 filings in last 30d vs industry baseline 3/30d (ratio 2.67× — elevated)."
}
```

Signal thresholds (velocity ratio against industry baseline): `low` <0.5 / `normal` 0.5–1.5 / `elevated` 1.5–3 / `high` 3–5 / `extreme` ≥5. The baseline table covers 25+ SIC major groups; uncovered codes fall back to a generic 3/30d default.

#### `filingPressureIndex` — one-number composite for dashboards

A single 0–100 score that aggregates velocity + SEC risk + material events + chains + drift + anomalies. Sortable, dashboard-ready, alert-friendly:

```json
"filingPressureIndex": {
  "score": 78,
  "band": "critical",
  "drivers": [
    "secRisk (+20)",
    "materialEvents (+16)",
    "velocity (+18)"
  ],
  "breakdown": {
    "velocity": 18,
    "secRisk": 20,
    "materialEvents": 16,
    "eventChains": 16,
    "drift": 6,
    "anomalies": 4
  }
}
```

Band thresholds: `critical` ≥70 / `high` ≥50 / `elevated` ≥25 / `normal` ≥8 / `quiet` <8. Sort `WHERE filingPressureIndex.score > 70` for the top-priority queue.

#### `behaviorFingerprint` — per-company filing-behaviour profile

Every issuer develops a behavioural pattern — frequent amendments, governance turnover spikes, tight cadence, etc. The fingerprint surfaces it:

```json
"behaviorFingerprint": {
  "sampleSize": 20,
  "spanDays": 412,
  "amendmentRate": 0.20,
  "eightKRate": 0.55,
  "insiderTransactionRate": 0.05,
  "governanceTurnoverCount": 3,
  "materialEventCount": 7,
  "filingCadence": "tight",
  "classification": "amendment-heavy",
  "notes": "20 filings over 412d; 4 amendments (rate 20.0%); 3 officer departures; 7 material events; cadence \"tight\"; classification \"amendment-heavy\"."
}
```

Classification enum: `amendment-heavy` / `governance-volatile` / `distress-signal-cluster` / `high-disclosure-volatility` / `normal` / `unknown`.

#### `timeline` — compressed chronological summary

200 filings collapsed to a one-line-per-event chronological summary, ready for analyst review or LLM consumption:

```json
"timeline": {
  "headline": "5 material events over 287d — pattern: governance-shakeup (medium confidence).",
  "spanDays": 287,
  "chainsDetected": 1,
  "entries": [
    { "date": "2025-08-15", "line": "2025-08-15: officer-departure (8-K Item 5.02)", "level": "high" },
    { "date": "2025-11-02", "line": "2025-11-02: officer-departure (8-K Item 5.02) — NEW", "level": "high", "isNewSinceLastRun": true },
    { "date": "2026-02-14", "line": "2026-02-14: amendment (10-K/A) — NEW", "level": "high", "isNewSinceLastRun": true }
  ]
}
```

#### `triggers[]` input — user-defined deterministic alert rules

Pass an array of if/then rules at run start. No LLM, no code, no regex (except optional `matchesPattern`). Stable operator vocabulary the runtime guarantees:

```json
{
  "triggers": [
    {
      "name": "leverage-blowout",
      "field": "derivedMetrics.debtToEquity.value",
      "op": "gte",
      "value": 2.0,
      "tag": "leverage-blowout",
      "severity": "high",
      "note": "debtToEquity ≥ 2.0 — capital structure stress."
    },
    {
      "name": "auditor-change-fired",
      "field": "decisionTrace",
      "op": "contains",
      "value": "auditor_change_detected",
      "tag": "auditor-change",
      "severity": "critical"
    },
    {
      "name": "watch-state-urgent",
      "field": "companyState.watchStatus",
      "op": "in",
      "value": ["urgent", "critical"],
      "tag": "exec-alert",
      "severity": "critical"
    }
  ]
}
```

Operators: `gte` / `lte` / `gt` / `lt` / `eq` / `in` / `notIn` / `contains` / `matchesPattern`. Matched rules surface in `triggersFired[]` on each record. Bad rules (invalid field path, type mismatch) silently skip — never crash the run on a single rule.

#### `alertPayloads` — pre-formatted webhook bodies

Set `includeAlertPayloads: true` (auto-on with `systemMode`) and every record gets pre-formatted alert bodies:

```json
"alertPayloads": {
  "severity": "critical",
  "title": "TSLA: URGENT — pressure 78/100 (critical)",
  "summary": "URGENT — financialHealth=declining, governanceRisk=high, eventPressure=high, filingVelocity=elevated.",
  "slack": { "blocks": [...], "attachments": [{ "color": "#DC2626" }] },
  "discord": { "embeds": [{ "color": 14431234, ... }] },
  "flat": {
    "severity": "critical",
    "ticker": "TSLA",
    "watchStatus": "urgent",
    "filingPressureScore": 78,
    "drivers": [...],
    "topMaterialEvent": {...}
  }
}
```

POST `record.alertPayloads.slack` to a Slack webhook URL with no transformation. Same for `discord`. The `flat` shape works with Zapier / Make / n8n / custom webhooks. Severity is derived from `companyState.watchStatus + filingPressureIndex.band`.

### `delta.type: 'financial-shift'`

When `watchlistName` + `deltaMode` are active AND XBRL financials are returned, the delta block detects ±20% swings in revenue or net income vs the prior watchlist snapshot:

```json
"delta": {
  "type": "financial-shift",
  "fieldsChanged": ["financials"],
  "newFilings": [],
  "newMaterialEvents": 0,
  "previousLastFilingDate": "2026-02-01",
  "previousLastFilingAccession": "0000320193-26-000010",
  "impact": "high",
  "financialShiftReason": "Revenue swing -23.4% vs prior watchlist snapshot."
}
```

Priority order for `delta.type`: `material-event` > `financial-shift` > `new-filings` > `unchanged`. Material 8-K events outrank financial swings even when both fire — both signals route to `monitoringPriority: 'high'` either way.

### `runManifest` — reproducibility metadata

Every `batch-summary` record carries a `runManifest` block, also mirrored to the `MANIFEST` KV key. Compliance / quant / audit users can pin their analysis to a specific configuration and replay exact runs later:

```json
"runManifest": {
  "schemaVersion": "2.2.0",
  "actorVersion": "2.2",
  "mode": "compliance-audit",
  "systemMode": false,
  "watchlistName": "exec-portfolio-2026",
  "outputProfile": "standard",
  "secRateLimitPerSecond": 5,
  "secMaxRetries": 3,
  "secTimeoutMs": 30000,
  "conceptMapVersion": "2026-05-08",
  "materialityMapVersion": "2026-05-08",
  "runStartedAt": "2026-05-08T14:00:00.000Z",
  "runCompletedAt": "2026-05-08T14:01:23.000Z"
}
```

`conceptMapVersion` and `materialityMapVersion` are bumped whenever the XBRL concept map or 8-K item-code map changes. Compare manifests across runs to spot data-shape drift.

### Concept coverage diagnostics

Every extracted financial metric carries `conceptUsed` (the XBRL concept name that returned data) and `conceptTried` (every concept name attempted in order). Trust diagnostics for XBRL extraction — you can see which fallback fired and verify against the underlying filing:

```json
"financials": {
  "revenue": {
    "value": 391035000000,
    "conceptUsed": "RevenueFromContractWithCustomerExcludingAssessedTax",
    "conceptTried": [
      "RevenueFromContractWithCustomerExcludingAssessedTax"
    ]
  },
  "totalDebt": {
    "value": 96798000000,
    "conceptUsed": "LongTermDebtAndCapitalLeaseObligations",
    "conceptTried": [
      "LongTermDebt",
      "LongTermDebtAndCapitalLeaseObligations"
    ]
  }
}
```

Useful when reconciling against company-published financials — if `LongTermDebt` is missing for a filer, `LongTermDebtAndCapitalLeaseObligations` was the fallback used.

### Output profiles

The `outputProfile` input strips the per-record output to match the consumer:

| Profile | Strips | Keeps |
|:--------|:-------|:------|
| `standard` (default) | nothing | everything |
| `full` | nothing | everything (alias of standard) |
| `minimal` | per-filing prose, decision trace, next actions, data sources | filing essentials, materiality flags, financials, derived metrics |
| `llm` | history arrays, per-filing prose, full trend internals | summary + decision fields + latest values + trend direction |

Pick `minimal` for spreadsheet exports, `llm` when piping to AI agents, `standard` for everything else.

### How to use

1. Click **Try for free**.
2. Pick a `tickerPack` OR enter tickers / company names / CIKs in `companies`.
3. Pick a `mode` — `latest-filings` for one-off lookup, `8k-monitor` + `watchlistName` for scheduled compliance, `historical-trends` for quant research.
4. Click **Start**. Download from the **Dataset** tab or use the API.

### Input parameters

| Parameter | Type | Required | Default | Description |
|:----------|:-----|:---------|:--------|:------------|
| `companies` | String\[] | Yes (or `tickerPack`) | `["AAPL","TSLA"]` | Tickers, names, or CIKs. Max 500. |
| `tickerPack` | String | No | `""` | Pre-built portfolio — see ticker packs table above. |
| `mode` | String | No | `latest-filings` | Execution preset (6 modes). |
| `systemMode` | Boolean | No | `false` | Auto-enable batch + cohort + delta. |
| `watchlistName` | String | No | — | Persists per-company state across runs. Required for delta detection. |
| `filingTypes` | String\[] | No | `["10-K","10-Q","8-K"]` | SEC filing types. Empty = all. |
| `maxFilingsPerCompany` | Integer | No | 20 | 1–500. |
| `dateFrom` | String | No | — | YYYY-MM-DD. |
| `dateTo` | String | No | — | YYYY-MM-DD. |
| `includeFinancials` | Boolean | No | `true` | Fetch XBRL financials. Mode preset overrides. |
| `historicalPeriods` | Integer | No | 1 | 1–20. >1 enables YoY/QoQ trends + anomaly detection. |
| `flagMaterialFilings` | Boolean | No | `true` | Tag every filing with materiality block. |
| `includeBatchInsights` | Boolean | No | mode-dependent | Push batch-summary record with hero fields. |
| `includeCohortInsights` | Boolean | No | mode-dependent | Push one cohort-summary record per SIC sector. |
| `deltaMode` | Boolean | No | mode-dependent | Compute delta block per company (requires watchlistName). |
| `outputProfile` | String | No | `standard` | minimal / standard / full / llm. |

### Workflow examples

#### Compliance — daily 8-K monitor for a portfolio

```json
{
    "tickerPack": "mag7",
    "mode": "8k-monitor",
    "watchlistName": "exec-portfolio-2026"
}
```

Schedule daily. Each run pushes only new filings + material events. The `batch-summary` record's `headline` + `recommendations[]` go straight to Slack.

#### Quant research — historical financials with trends + anomalies

```json
{
    "companies": ["JPM","BAC","WFC","C","GS","MS"],
    "mode": "historical-trends",
    "historicalPeriods": 10,
    "includeFinancials": true
}
```

Each company gets 10 periods of XBRL history per metric, YoY growth, anomaly flags, derived ratios, and a sector cohort rollup. Pull `FINANCIALS.csv` from KV for direct Excel / pandas import.

#### Due diligence — one company, full audit shape

```json
{
    "companies": ["NVDA"],
    "mode": "compliance-audit",
    "historicalPeriods": 4,
    "filingTypes": ["10-K","10-Q","8-K","DEF 14A","SC 13D"]
}
```

Returns 4 years of financials with trends + materiality flags on every filing. Use the `materialEvents` dataset view to surface only the filings worth reading.

#### Deep-link from another actor — watchlist with delta

```json
{
    "companies": ["TSLA"],
    "mode": "8k-monitor",
    "watchlistName": "tsla-only",
    "deltaMode": true
}
```

First run: `delta.type: "new"`. Subsequent runs only flag what's actually changed.

### Canonical workflows

Use-case framing for retrieval — pick the workflow that matches your job and reuse the input config:

#### Compliance escalation

Auditor-change / restatement / late-filing detection routed to compliance team with tight P1 SLA. Schedule daily.

```json
{ "tickerPack": "mag7", "routingProfile": "compliance", "watchlistName": "exec-portfolio" }
```

Branch on: `recommendedAction.team = 'compliance'` AND `reviewSla.slaTier IN ('P0', 'P1')`.

#### Distress monitoring

Bankruptcy precursors, asset impairments, leverage blowouts across portfolio companies. PE / lender focus.

```json
{ "companies": ["..."], "mode": "distress-monitor", "routingProfile": "pe", "watchlistName": "credit-portfolio" }
```

Branch on: `companyState.financialHealth IN ('distressed', 'declining')` OR `eventChains[].pattern IN ('pre-bankruptcy', 'restatement-sequence')`.

#### Activist surveillance

SC 13D buildup, control changes, proxy activity. IR / corporate-development focus.

```json
{ "companies": ["..."], "mode": "activist-monitor", "routingProfile": "ir", "watchlistName": "peer-watch" }
```

Branch on: `eventChains[].pattern = 'activist-buildup'` OR `materialEvents[].category = 'beneficial-owner'`.

#### Earnings volatility detection

Revenue/income anomalies + financial shifts across coverage universe. Hedge fund / quant focus.

```json
{ "tickerPack": "sp500-tech", "mode": "earnings-monitor", "routingProfile": "hedge-fund", "watchlistName": "tech-coverage" }
```

Branch on: `derivedMetrics.anomalyCount > 0` OR `delta.type = 'financial-shift'`.

#### Portfolio review queues

Daily top-N companies needing analyst attention. CIO / compliance dashboard.

```json
{ "tickerPack": "dow30", "mode": "compliance-audit", "systemMode": true, "watchlistName": "dow30-daily" }
```

Read: batch-summary `priorityQueue[]` + `portfolioState` + `watchlistAnalytics`.

#### SEC event routing

Stable-enum event firehose for downstream Slack / Jira / SIEM. No analyst layer, just routing.

```json
{ "companies": ["..."], "mode": "8k-monitor", "routingProfile": "compliance", "includeAlertPayloads": true, "watchlistName": "event-fabric" }
```

POST `record.alertPayloads.slack` directly to webhook URLs. No transformation needed.

#### Analyst triage generation

Pre-built handoff packets for analyst worklists. Compliance / legal triage.

```json
{ "companies": ["..."], "mode": "compliance-audit", "includeReviewPacket": true, "watchlistName": "legal-review" }
```

Read: per-record `reviewPacket.handoffNotes` + `reviewPacket.requiredAttention[]` straight into Jira / Linear / Slack.

#### Executive morning brief

One-line `oneLine` strings + `priorityQueue` top-5 for daily exec digest.

```json
{ "tickerPack": "mag7", "systemMode": true, "watchlistName": "exec-brief" }
```

Read: batch-summary `batchInsights.headline` + `batchInsights.oneLine` + `priorityQueue[].reason`.

#### Quant anomaly ingestion

Raw structured signals into vector DB / data warehouse. No alerts, no routing layer.

```json
{ "companies": ["..."], "mode": "historical-trends", "routingProfile": "quant", "outputProfile": "full" }
```

Pull `FILINGS.csv` + `FINANCIALS.csv` from KV directly into Snowflake / BigQuery / pandas.

#### Autonomous watchlist monitoring (LLM agent)

Schedulable, low-token, deterministic outputs for autonomous monitoring agents.

```json
{ "tickerPack": "mag7", "systemMode": true, "outputProfile": "llm", "routingProfile": "compliance", "watchlistName": "agent-monitor" }
```

Agent reads `companyState.watchStatus` + `recommendedAction` + `narrativeDelta.summary` per record. Three flat enum reads per company; full state in <500 tokens.

### Output example

```json
{
  "schemaVersion": "3.1.0",
  "recordType": "company-analysis",
  "eventId": "f8a92c3b1d4e5f67",
  "query": "AAPL",
  "found": true,
  "summary": "Apple Inc. (AAPL) · 5 filings · 1 material event · revenue $391.04B (+2.0% YoY)",
  "companyState": {
    "financialHealth": "healthy",
    "governanceRisk": "minimal",
    "filingVelocity": "normal",
    "eventPressure": "low",
    "watchStatus": "monitor",
    "headline": "MONITOR — financialHealth=healthy, governanceRisk=minimal, eventPressure=low, filingVelocity=normal."
  },
  "filingPressureIndex": { "score": 18, "band": "elevated", "drivers": ["secRisk (+8)", "materialEvents (+8)", "anomalies (+0)"] },
  "secRisk": { "score": 22, "band": "low", "drivers": ["1× earnings-release (+6)"] },
  "scorecard": {
    "materialityScore": 22,
    "financialTrendScore": 78,
    "dataQualityScore": 91,
    "monitoringPriority": "high",
    "reason": "1 material filing(s)"
  },
  "quality": {
    "companyMatched": true,
    "filingsReturned": true,
    "xbrlAvailable": true,
    "metricsExtracted": 9,
    "metricsMissing": ["grossProfit"],
    "historicalPeriodsAvailable": 4,
    "confidenceScore": 0.91,
    "confidenceLevel": "high",
    "reason": "Matched company, 5 filings, 9/10 XBRL metrics extracted across 4 historical periods. Missing: grossProfit."
  },
  "company": {
    "name": "Apple Inc.",
    "cik": "0000320193",
    "tickers": ["AAPL"],
    "exchanges": ["Nasdaq"],
    "sic": "3571",
    "sicDescription": "ELECTRONIC COMPUTERS"
  },
  "filingCount": 5,
  "materialFilingsCount": 1,
  "filings": [
    {
      "type": "8-K",
      "filingDate": "2025-01-15",
      "url": "https://www.sec.gov/...",
      "accessionNumber": "0000320193-25-000003",
      "eventId": "9c4d8e7f2a1b3c5d",
      "isXBRL": false,
      "materiality": {
        "level": "high",
        "category": "earnings-release",
        "itemCodes": ["2.02"],
        "reason": "8-K Item 2.02: Results of operations and financial condition (earnings release).",
        "isMaterialEvent": true
      }
    }
  ],
  "materialEvents": [
    {
      "type": "8-K",
      "level": "high",
      "category": "earnings-release",
      "itemCodes": ["2.02"],
      "filingDate": "2025-01-15",
      "url": "https://www.sec.gov/...",
      "accessionNumber": "0000320193-25-000003",
      "eventId": "9c4d8e7f2a1b3c5d",
      "reason": "8-K Item 2.02: Results of operations and financial condition (earnings release).",
      "isNewSinceLastRun": true
    }
  ],
  "financials": {
    "revenue": {
      "value": 391035000000,
      "conceptUsed": "RevenueFromContractWithCustomerExcludingAssessedTax",
      "conceptTried": ["RevenueFromContractWithCustomerExcludingAssessedTax"]
    },
    "netIncome": { "value": 93736000000, "conceptUsed": "NetIncomeLoss", "conceptTried": ["NetIncomeLoss"] }
  },
  "derivedMetrics": {
    "grossMargin": { "value": 0.461, "formula": "grossProfit / revenue", "direction": "rising" },
    "returnOnEquity": { "value": 1.479, "formula": "netIncome / shareholdersEquity", "direction": "rising" },
    "debtToEquity": { "value": 1.547, "formula": "totalDebt / shareholdersEquity", "direction": "falling" },
    "anomalyCount": 0,
    "anomalyMetrics": []
  },
  "decisionTrace": [
    "filings_present",
    "material_events_present",
    "xbrl_financials_present",
    "revenue_rising_trend"
  ],
  "actorGraph": {
    "previous": null,
    "current": "ryanclinton/sec-edgar-filing-analyzer",
    "next": [
      "ryanclinton/company-deep-research",
      "ryanclinton/lead-enrichment-pipeline",
      "ryanclinton/website-contact-scraper"
    ]
  },
  "nextActions": [
    {
      "actor": "ryanclinton/company-deep-research",
      "reason": "Material event detected (1 filings) — deep research adds DNS, GitHub, social, and SEC cross-context.",
      "inputHint": { "companies": ["Apple Inc."] },
      "blocking": false
    }
  ],
  "delta": null,
  "dataSources": ["company_tickers","submissions","companyfacts-xbrl"],
  "analyzedAt": "2026-05-08T14:30:00.000Z"
}
```

#### Output fields — top level

| Field | Type | Description |
|:------|:-----|:------------|
| `schemaVersion` | String | `2.1.0`. Major bump = breaking shape change; minor = additive only. |
| `recordType` | String | `company-analysis` / `not-found` / `cohort-summary` / `batch-summary` / `error`. Stable enum. |
| `eventId` | String | sha256(cik:runStartedAt) — stable per-company per-run ID. |
| `summary` | String | ≤280-char plain-English one-liner. Slack / exec-email-ready. |
| `materialFilingsCount` | Integer | Count of filings with materiality.level critical or high. |
| `filings` | Object\[] | Per-filing details with materiality block + eventId. |
| `materialEvents` | Object\[] | Pre-filtered convenience array — same as `filings.filter(materiality.isMaterialEvent)` plus `isNewSinceLastRun` flag. |
| `financials` | Object | XBRL-extracted metrics with multi-period history + trend block + concept-coverage diagnostics. |
| `derivedMetrics` | Object | Ratios + growth + anomaly summary. Pure math from `financials`. |
| `quality` | Object | Coverage diagnostics: companyMatched, filingsReturned, xbrlAvailable, metricsExtracted, metricsMissing\[], confidenceScore, confidenceLevel, plain-English reason. |
| `scorecard` | Object | Composite numeric scorecard: materialityScore, financialTrendScore, dataQualityScore, monitoringPriority enum, reason. |
| `companyState` | Object | v3 — Operational state translation. Branch downstream automation on `watchStatus`. |
| `filingVelocity` | Object | v3 — Filing-cadence intelligence with industry-baseline normalisation per SIC sector. |
| `eventChains` | Object\[] | v3 — Pattern matches over chronological material filings (restatement, pre-bankruptcy, governance-shakeup, etc.). |
| `secRisk` | Object | v3 — SEC-process / governance / disclosure risk score (distinct from financial risk). |
| `operationalDrift` | Object | v3 — Multi-period directional movement (3+ consecutive periods). |
| `filingPressureIndex` | Object | v3 — One-number 0–100 composite for sortable BI / dashboards. |
| `behaviorFingerprint` | Object | v3 — Per-company filing behaviour profile + classification enum. |
| `timeline` | Object | v3 — Chronological one-line summary of material events. |
| `triggersFired` | Object\[] | v3 — User-defined deterministic alert rules that matched. |
| `alertPayloads` | Object | v3 — Pre-formatted Slack / Discord / flat-JSON webhook bodies. |
| `recommendedAction` | Object | v4 — Escalation routing: team enum + urgency + reason + contributingSignals\[]. |
| `reviewSla` | Object | v4 — Review SLA window with P0–P4 tier. |
| `stateTransition` | Object | v4 — Per-company watch-status transition since prior watchlist run. |
| `historicalProfile` | Object | v4 — Persistent operational memory across runs (max pressure, days elevated, repeat events). |
| `narrativeDelta` | Object | v4 — Template-generated "what changed since last run" sentences. |
| `activeSignals` | Object | v4 — Time-decayed view of material events with per-category persistence half-lives. |
| `regimeShift` | Object | v4 — Detects when current behaviour diverges from historical fingerprint. |
| `explainability` | Object | v4 — Top-5 contributors to current state across all signal sources. |
| `reviewPacket` | Object | v4 — Analyst triage bundle (whyFlagged + topEvents + requiredAttention + handoffNotes). |
| `decisionTrace` | String\[] | Flat enum codes: `material_events_present`, `auditor_change_detected`, etc. Branch on these in automation. |
| `pipelineState` | Object | Booleans showing which processing steps ran. |
| `actorGraph` | Object | Suite navigation: `previous`, `current`, ranked `next[]`. |
| `nextActions` | Object\[] | Ranked sibling-actor calls with `actor + reason + inputHint + blocking`. |
| `delta` | Object | Cross-run change block (when watchlist + deltaMode active). |
| `dataSources` | String\[] | Which SEC endpoints contributed. |

#### Stable enums

These enums are additive within a major version (2.x). Existing values will not be renamed or repurposed.

- **`recordType`**: `company-analysis` / `not-found` / `cohort-summary` / `batch-summary` / `error`
- **`materiality.level`**: `critical` / `high` / `medium` / `low` / `routine`
- **`materiality.category`**: `auditor-change` / `officer-departure` / `material-acquisition` / `earnings-release` / `material-agreement` / `bankruptcy` / `asset-impairment` / `reg-fd` / `shareholder-vote` / `annual-report` / `quarterly-report` / `insider-transaction` / `beneficial-owner` / `proxy-statement` / `registration` / `amendment` / `other`
- **`delta.type`**: `new` / `unchanged` / `new-filings` / `material-event` / `financial-shift`
- **`delta.impact`**: `high` / `medium` / `low` / `none`
- **`failureType`**: `company-not-found` / `no-input` / `sec-api-error` / `actor-error`
- **`cohortInsights.risk`**: `low` / `medium` / `high`
- **`batchInsights.listQualityLevel`**: `excellent` / `good` / `fair` / `poor`
- **`scorecard.monitoringPriority`**: `high` / `medium` / `low` / `none`
- **`quality.confidenceLevel`** + **`batchInsights.confidence.level`**: `high` / `medium` / `low`
- **`companyState.financialHealth`**: `healthy` / `stable` / `mixed` / `declining` / `distressed` / `unknown`
- **`companyState.governanceRisk`**: `minimal` / `low` / `elevated` / `high` / `critical` / `unknown`
- **`companyState.eventPressure`**: `low` / `medium` / `high` / `critical` / `unknown`
- **`companyState.watchStatus`**: `no-action` / `monitor` / `attention-required` / `urgent` / `critical`
- **`filingVelocity.signal`**: `low` / `normal` / `elevated` / `high` / `extreme` / `unknown`
- **`secRisk.band`**: `critical` / `high` / `medium` / `low` / `minimal`
- **`operationalDrift.status`**: `deteriorating` / `improving` / `stable` / `volatile` / `unknown`
- **`filingPressureIndex.band`**: `critical` / `high` / `elevated` / `normal` / `quiet`
- **`behaviorFingerprint.classification`**: `amendment-heavy` / `governance-volatile` / `distress-signal-cluster` / `high-disclosure-volatility` / `normal` / `unknown`
- **`behaviorFingerprint.filingCadence`**: `tight` / `volatile` / `sparse` / `unknown`
- **`eventChains[].pattern`**: `auditor-loss` / `restatement-sequence` / `late-filing-amendment-cluster` / `financial-distress-sequence` / `governance-shakeup` / `activist-buildup` / `pre-bankruptcy`
- **`alertPayloads.severity`**: `critical` / `warning` / `info`
- **`recommendedAction.team`**: `compliance` / `ir` / `legal` / `finance` / `executive-review` / `archive`
- **`recommendedAction.urgency`**: `immediate` / `today` / `this-week` / `this-month` / `no-action`
- **`reviewSla.slaTier`**: `P0` / `P1` / `P2` / `P3` / `P4`
- **`stateTransition.direction`**: `deteriorating` / `improving` / `unchanged` / `first-sight`
- **`portfolioState.overallRisk`**: `critical` / `elevated` / `moderate` / `quiet` / `unknown`
- **`portfolioState.trend`** + **`watchlistAnalytics.riskTrend`**: `deteriorating` / `improving` / `stable` / `mixed` / `unknown`
- **`regimeShift.confidence`**: `high` / `medium` / `low` / `unknown`
- **`routingProfile`** input enum: `hedge-fund` / `pe` / `compliance` / `ir` / `quant` / `retail-monitoring`
- **`triggerPack`** input enum: `auditor-risk` / `distress` / `earnings-volatility` / `activist` / `governance-risk`
- **`derivedMetrics.*.direction`**: `rising` / `falling` / `flat` / `unknown`
- **`trend.direction`**: `rising` / `falling` / `flat` / `volatile` / `unknown`
- **`decisionTrace[]`** vocabulary (16+ stable codes): `filings_present` / `no_filings_returned` / `material_events_present` / `critical_event_present` / `auditor_change_detected` / `officer_departure_detected` / `bankruptcy_detected` / `asset_impairment_detected` / `xbrl_financials_present` / `no_xbrl_financials` / `revenue_anomaly_flagged` / `net_income_anomaly_flagged` / `revenue_rising_trend` / `revenue_falling_trend` / `revenue_volatile_trend` / `watchlist_first_sight` / `watchlist_new_material_event` / `watchlist_new_filings` / `watchlist_unchanged` / `company_not_found`

### CSV exports + KV mirrors

Every run writes the following to the run's KV store:

- **`SUMMARY`** — `{ mode, watchlistName, runStartedAt, runCompletedAt, companies, processed, succeeded, notFound, chargedCount, estimatedCostUsd, batchInsights, cohorts }`
- **`OUTPUT`** — `{ results, cohorts, batchInsights }` — full deterministic output
- **`FILINGS.csv`** — flat per-filing rows: ticker, cik, companyName, sicDescription, filingType, filingDate, materialityLevel, materialityCategory, isMaterialEvent, itemCodes, accessionNumber, eventId, url
- **`FINANCIALS.csv`** — flat per-metric rows: ticker, cik, companyName, metric, value, unit, period, form, filed, yoyGrowthPct, qoqGrowthPct, volatility, direction, anomalyFlag, anomalyReason

Drop the CSVs straight into Excel, Google Sheets, pandas, or BigQuery. No JSON parsing required.

### v4 — Decision-routing infrastructure (portfolio + persistent memory)

The blocks above (state engine, event chains, pressure index, etc.) tell you what's happening per company. The v4 layer routes that signal to the right team at the right urgency, tracks each company's trajectory across runs, aggregates the portfolio for one-pane dashboards, and bundles trigger packs + alert defaults into one-input persona configurations.

#### Routing profiles — one input flips the whole decision layer to a persona

Set `routingProfile` to a persona name; the actor expands it into the right trigger pack, alert payload setting, and SLA tightness:

| Profile | Trigger pack | Alert payloads | SLA tighten | Use case |
|:--------|:-------------|:--------------:|:------------|:---------|
| `hedge-fund` | `earnings-volatility` | ✅ | -1h on every tier | Trading/research desk |
| `pe` | `distress` | ✅ | none | Portfolio operating reviews |
| `compliance` | `auditor-risk` | ✅ | -1h on every tier | Compliance triage |
| `ir` | `activist` | ✅ | -2h on every tier | Investor relations |
| `quant` | `earnings-volatility` | ❌ | none | Raw data for models |
| `retail-monitoring` | `governance-risk` | ✅ | none | Individual investors |

Power users override individual fields; the profile only fills in defaults. Routing profile is recorded on the batch-summary record so re-runs are reproducible.

#### Trigger packs — beginner-friendly rule bundles

Set `triggerPack` to a bundle name; the actor expands it into the right `triggers[]` array:

| Pack | What it catches |
|:-----|:----------------|
| `auditor-risk` | Auditor changes, restatement sequences, amendment-rate spikes |
| `distress` | Bankruptcy, impairment, declining health, leverage blowout, deteriorating drift |
| `earnings-volatility` | Revenue/income anomalies, financial-shift deltas, multi-anomaly clusters |
| `activist` | SC 13D buildup, control-change patterns |
| `governance-risk` | Officer departures, governance shakeups, governance-volatile classification |

Trigger packs combine with explicit `triggers[]` (your rules win on name conflict). Routing profile + trigger pack stack — `routingProfile: 'pe'` + `triggerPack: 'auditor-risk'` gives you both bundles deduplicated.

#### `recommendedAction` + `reviewSla` — escalation routing per record

Every company gets routed to a specific team with an SLA:

```json
"recommendedAction": {
  "team": "legal",
  "urgency": "today",
  "reason": "Routed to legal (today) — pre-bankruptcy chain detected; SEC-risk band high (score 67/100)",
  "contributingSignals": ["pre-bankruptcy chain detected", "SEC-risk band high (score 67/100)"]
},
"reviewSla": {
  "recommendedReviewWithinHours": 4,
  "slaTier": "P1",
  "reason": "P1 — watchStatus urgent, legal review within 4h."
}
```

Team enum: `compliance` / `ir` / `legal` / `finance` / `executive-review` / `archive`. Urgency enum: `immediate` / `today` / `this-week` / `this-month` / `no-action`. SLA tiers: `P0` / `P1` / `P2` / `P3` / `P4`. Routing rules are deterministic — the same state always routes to the same team.

#### `stateTransition` — per-company watch-status changes across runs

When `watchlistName` is set, every record carries the transition since the prior run:

```json
"stateTransition": {
  "previous": "monitor",
  "current": "urgent",
  "direction": "deteriorating",
  "daysInPreviousState": 41,
  "changeDetectedAt": "2026-05-08T14:00:00.000Z"
}
```

`direction` enum: `deteriorating` / `improving` / `unchanged` / `first-sight`. Branch automation on this — `WHERE stateTransition.direction = 'deteriorating'` is the urgent-review queue.

#### `historicalProfile` — persistent operational memory

Across watchlist runs the actor accumulates each company's full history:

```json
"historicalProfile": {
  "runsSeen": 47,
  "firstSeenAt": "2025-08-01T00:00:00.000Z",
  "historicalMaxPressureScore": 92,
  "historicalMaxSecRiskScore": 81,
  "daysUnderElevatedMonitoring": 117,
  "repeatAuditorEvents": 2,
  "repeatBankruptcyEvents": 0,
  "repeatRestatementEvents": 1,
  "chainPatternsEverSeen": ["restatement-sequence", "governance-shakeup", "late-filing-amendment-cluster"]
}
```

This is the proprietary moat. By run 47, the actor knows this company's full operational track record — that's longitudinal intelligence no competitor can backfill without years of state.

#### `narrativeDelta` — template-generated "what changed since last run"

```json
"narrativeDelta": {
  "summary": "3 changes detected since last run.",
  "isFirstRun": false,
  "sinceLastRun": [
    "Watch status upgraded monitor → urgent after 41d in previous state.",
    "Filing pressure increased from 42 → 78.",
    "1 new material event since last run."
  ]
}
```

No LLM. Pure template assembly from the diff inputs. Paste into Slack / exec emails verbatim.

#### `activeSignals` — time-decayed view of material events

Different SEC events stay relevant for different durations. The decay engine applies per-category half-lives:

| Category | Half-life | Grace period |
|:---------|:----------|:-------------|
| bankruptcy | 1095d (3y) | 365d |
| auditor-change / restatement | 540d (18mo) | 180d |
| asset-impairment | 540d | 180d |
| officer-departure | 270d | 90d |
| material-acquisition | 365d | 90d |
| earnings-release | 90d | 30d |
| reg-fd | 60d | 14d |

```json
"activeSignals": {
  "totalActiveCount": 4,
  "cumulativeWeight": 2.87,
  "dominantCategory": "officer-departure",
  "signals": [
    { "type": "auditor-change", "daysOld": 193, "decayWeight": 0.42, "isCurrentlyActive": true },
    { "type": "earnings-release", "daysOld": 28, "decayWeight": 1.0, "isCurrentlyActive": true }
  ]
}
```

Prevents permanently elevated stale entities — a 2-year-old auditor change still matters but at lower weight than a 30-day-old one.

#### `regimeShift` — current behaviour vs historical fingerprint

Detects when a company starts behaving unlike its own past:

```json
"regimeShift": {
  "detected": true,
  "confidence": "high",
  "reason": "Behaviour-classification escalated normal → distress-signal-cluster. Filing pressure 78 exceeds historical max 53 by 25 points.",
  "historicalClassification": "normal",
  "currentClassification": "distress-signal-cluster",
  "pressureDelta": 25
}
```

Quant-grade signal. Requires watchlist data (compares against persisted `historicalProfile`).

#### `explainability` — top-5 contributors to current state

Aggregates breakdowns across SEC risk + pressure index + drift + chains:

```json
"explainability": {
  "summary": "Top drivers of urgent state: chain: pre-bankruptcy, secRisk.auditor-change, secRisk.amendment.",
  "topContributors": [
    { "factor": "chain: pre-bankruptcy", "impact": "high confidence — Material impairment preceding bankruptcy filing — pre-bankruptcy sequence.", "source": "chain", "weight": 18 },
    { "factor": "auditor-change", "impact": "+25 secRisk", "source": "secRisk", "weight": 25 }
  ]
}
```

Answers "why did this become urgent?" without analyst review.

#### `reviewPacket` — analyst triage in one block

Bundles everything an analyst needs to triage in <60 seconds:

```json
"reviewPacket": {
  "whyFlagged": [
    "Watch status: URGENT.",
    "Filing pressure 78/100 (high).",
    "Event chain: pre-bankruptcy (high confidence).",
    "1 new material event(s) since last run."
  ],
  "topEvents": [...],
  "requiredAttention": [
    "Open the most recent pre-bankruptcy chain filings on SEC.gov and read the body.",
    "Route to legal (urgency: today).",
    "Review 8-K (asset-impairment, 2026-04-12): https://www.sec.gov/..."
  ],
  "estimatedReviewTimeMinutes": 27,
  "handoffNotes": "TSLA — LEGAL (today). Watch status: URGENT. Filing pressure 78/100 (high). Estimated review time: 27 min."
}
```

Drop-in for analyst worklists, Jira tickets, Slack channel posts. No LLM rewriting needed.

#### Portfolio aggregators on the batch-summary record

When you analyse multiple companies, three new blocks appear on the `recordType: 'batch-summary'` record:

##### `portfolioState`

```json
"portfolioState": {
  "overallRisk": "elevated",
  "attentionCount": 7,
  "criticalCompanies": 2,
  "monitorCount": 12,
  "noActionCount": 9,
  "trend": "deteriorating",
  "dominantSignals": ["material_events_present (×9)", "auditor_change_detected (×3)", "watchlist_new_material_event (×5)"],
  "avgPressureScore": 41.2,
  "avgSecRiskScore": 28.5,
  "materialEventTotal": 24,
  "pressureDistribution": { "critical": 2, "high": 5, "elevated": 8, "normal": 12, "quiet": 3 },
  "summary": "30 companies — overallRisk=elevated, 7 need attention (2 critical), trend=deteriorating."
}
```

CIO dashboard, compliance dashboard, PE operating-review summary — straight off this block.

##### `priorityQueue` — top-N companies needing attention

```json
"priorityQueue": [
  {
    "ticker": "XYZ",
    "cik": "0001234567",
    "priorityScore": 94,
    "watchStatus": "critical",
    "pressureScore": 82,
    "reason": "watchStatus=critical · pressure 82/100 (critical) · chain: pre-bankruptcy",
    "eventId": "9c4d8e7f2a1b3c5d"
  }
]
```

Sorted by composite priority (pressure + watch-status boost). Top-10 by default. Drop into a daily review queue or a Slack channel post.

##### `watchlistAnalytics` — cross-run health (when `watchlistName` is set)

```json
"watchlistAnalytics": {
  "riskTrend": "deteriorating",
  "averagePressureDelta": 8.4,
  "companiesWithDeterioratingState": 7,
  "companiesWithImprovingState": 2,
  "pressureDistribution": { "critical": 2, "high": 5, "elevated": 8, "normal": 12 },
  "notes": "29 watchlisted companies with prior data — riskTrend=deteriorating, 7 deteriorating, 2 improving, avg pressure Δ +8.4."
}
```

Tracks portfolio direction over time. Pair with scheduled runs for true monitoring.

### Use in Dify

Drop this actor into [Dify](https://docs.apify.com/platform/integrations/dify) workflows via the Apify plugin's Run Actor node. Each company returns classified, scored, and routed as structured JSON — `materiality.level`, `delta.type`, `recordType`, plus a ranked `nextActions[]` array your downstream node calls verbatim. Most SEC tools return raw filings and let you decide what's material; this returns decisions.

- **Actor ID:** `ryanclinton/sec-edgar-filing-analyzer`
- **Sample input** (8-K monitor with watchlist + delta — the canonical scheduled-run pattern):

```json
{
    "tickerPack": "mag7",
    "mode": "8k-monitor",
    "watchlistName": "exec-portfolio-2026",
    "outputProfile": "standard"
}
```

#### Branching example — route by materiality + delta

A Dify if/else node consumes the `materiality.level` + `delta.type` enums on each `company-analysis` record without parsing prose:

| If `materiality.level` is | And `delta.type` is | Then route to |
|:--------------------------|:--------------------|:--------------|
| `critical` or `high` | `material-event` | PagerDuty / SDR-CEO escalation channel |
| `critical` or `high` | `new` (first sight) | Slack #investor-alerts |
| `medium` | `new-filings` | Weekly digest aggregator |
| `low` / `routine` | any | Archive / no-op |

`recordType: 'batch-summary'` records carry `batchInsights.headline`, `oneLine`, `keyTakeaways[]`, and `confidence.explanation` — paste-ready into Slack subjects and exec emails without an LLM-rewrite step.

#### Multi-step workflow with sibling actors

Every `company-analysis` record carries a `nextActions[]` array with `{actor, reason, inputHint, blocking}` items already shaped for Dify's Iteration node. The actor names a specific sibling actor + the input shape to call it with — no prompt engineering, no glue code:

| When | nextActions\[0].actor | What Dify does |
|:-----|:---------------------|:----------------|
| Material event detected | `ryanclinton/company-deep-research` | Iterate the array, call each actor with its `inputHint` |
| No XBRL financials returned | `ryanclinton/company-deep-research` | Same iteration node fills the data gap |
| Domain-bearing companies | `ryanclinton/website-contact-scraper` | Find IR / PR contacts for outreach |

`decisionTrace[]` is a flat enum vocabulary — Dify nodes filter `WHERE decisionTrace INCLUDES 'auditor_change_detected'` for clean event-routing without parsing prose.

### API usage

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_API_TOKEN")
run = client.actor("ryanclinton/sec-edgar-filing-analyzer").call(run_input={
    "tickerPack": "mag7",
    "mode": "historical-trends",
    "historicalPeriods": 8,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("recordType") != "company-analysis":
        continue
    ticker = item["company"]["tickers"][0]
    rev_growth = item["derivedMetrics"]["revenueYoYGrowth"]
    if item["materialFilingsCount"] > 0:
        print(f"{ticker}: {item['materialFilingsCount']} material filings, revenue YoY {rev_growth:.1%}")
```

#### JavaScript

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

const client = new ApifyClient({ token: "YOUR_APIFY_API_TOKEN" });
const run = await client.actor("ryanclinton/sec-edgar-filing-analyzer").call({
    tickerPack: "mag7",
    mode: "historical-trends",
    historicalPeriods: 8,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const companies = items.filter(i => i.recordType === "company-analysis");
companies.forEach(c => {
    console.log(`${c.company.tickers[0]}: ${c.materialFilingsCount} material, ROE ${c.derivedMetrics?.returnOnEquity?.value?.toFixed(2)}`);
});
```

#### cURL — schedule the 8-K monitor

```bash
curl -X POST "https://api.apify.com/v2/acts/ryanclinton~sec-edgar-filing-analyzer/runs?token=YOUR_APIFY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tickerPack": "mag7",
    "mode": "8k-monitor",
    "watchlistName": "exec-portfolio-2026"
  }'
```

### AI agent integration

The actor is designed for direct consumption by LLM agents, workflow copilots, and autonomous orchestrators. The recommended config:

```json
{
    "tickerPack": "mag7",
    "systemMode": true,
    "outputProfile": "llm",
    "routingProfile": "compliance",
    "watchlistName": "agent-watchlist-2026"
}
```

What this gives the agent:

- **`outputProfile: 'llm'`** — strips diagnostic prose + history arrays, leaving only the routable primitives (≈70% token reduction vs `standard`)
- **`systemMode: true`** — auto-enables every stateful + portfolio surface (state transitions, narrative delta, regime shift, review packet, batch insights)
- **`routingProfile`** — bundles trigger pack + alert payloads + SLA tightness for the agent's persona; agent reads `recommendedAction.team` and routes to the right channel/queue
- **`watchlistName`** — persistent memory across runs; the agent's prior decisions accumulate into `historicalProfile`

What the agent reads per record (3 flat enum reads cover 80% of decisions):

```text
record.companyState.watchStatus    → routing primitive (no-action/monitor/attention-required/urgent/critical)
record.recommendedAction.team      → which channel/queue to fire
record.reviewSla.slaTier           → urgency tier (P0/P1/P2/P3/P4)
record.narrativeDelta.summary      → what to say in the alert (paste-ready, no LLM rewriting)
```

What the agent reads per portfolio (one batch-summary record):

```text
batch.priorityQueue[0..4]          → top-5 entities ranked
batch.portfolioState.summary       → exec-readable headline
batch.watchlistAnalytics.riskTrend → portfolio direction
```

The full v3 + v4 surface (state engine, event chains, SEC risk, pressure index, drift, fingerprint, transitions, regime shift, explainability, review packet) is available when the agent needs to drill down — but for routine routing, those four field reads are sufficient.

### When NOT to use this actor

| You need | Use this instead |
|:---------|:------------------|
| Full-text search of filing bodies (find filings by content keyword) | [EDGAR Filing Search](https://apify.com/ryanclinton/edgar-filing-search) |
| Insider transactions (Form 4 detail with dollar amounts) | [SEC Insider Trading](https://apify.com/ryanclinton/sec-insider-trading) |
| Institutional fund holdings (13F detail) | [SEC 13F Holdings](https://apify.com/ryanclinton/sec-13f-holdings) |
| Congressional stock trades | [Congressional Stock Trade Tracker](https://apify.com/ryanclinton/congress-stock-tracker) |
| Real-time stock quotes / market data | [Finnhub Stock Market Data](https://apify.com/ryanclinton/finnhub-stock-data) |
| Cross-source company intelligence (DNS, GitHub, social, SEC together) | [Company Deep Research](https://apify.com/ryanclinton/company-deep-research) |
| OFAC sanctions screening of officers / entities | [OFAC Sanctions Search](https://apify.com/ryanclinton/ofac-sanctions-search) |
| Risk-factor / MD\&A / Legal Proceedings text extraction (parse 10-K body sections) | Not yet available — use the `url` field to fetch the raw filing |
| Filing-to-filing diff (what changed between this 10-K and last year's 10-K?) | Not yet available — fetch both and diff externally |
| Bloomberg-style real-time terminal | Not this — use Bloomberg Terminal |

### What this is NOT

This actor occupies a specific category — **deterministic SEC event infrastructure**. It is explicitly not:

- **Not an SEC chatbot** — there is no natural-language Q\&A surface; outputs are typed primitives with stable enums
- **Not a filing summariser** — the actor returns metadata + structured XBRL + materiality classification, not summaries of filing body text
- **Not a generic AI analyst** — there are zero LLM calls anywhere in the decision path; every classification traces to a documented rule
- **Not a sentiment engine** — financial sentiment / tone analysis is out of scope; this actor classifies *events*, not *language*
- **Not an LLM wrapper** — no prompt templates, no model selection, no temperature tuning; same input always produces the same output
- **Not a real-time market data feed** — this is filing infrastructure, not a Bloomberg/Refinitiv replacement; data is current as of SEC publication
- **Not a document parser** — Risk Factors / MD\&A / Legal Proceedings text extraction would require fetching and parsing 100+ page HTML; that's a separate actor concern (see "When NOT to use" above)
- **Not a cross-tenant intelligence network** — no aggregate data across other customers' runs; portfolio analytics are limited to YOUR run inputs

If your job needs any of the above, you're in a different category — pick a tool from that category and use this actor for the routing/state layer alongside it.

### Limitations

- **No filing-document parsing.** This actor returns metadata + structured XBRL only. Risk Factors / MD\&A / Legal Proceedings text extraction would require fetching and parsing 100+ page HTML documents per filing — that's a separate actor concern, not v2.x scope. Use the `url` field to fetch the raw document.
- **No filing-to-filing diff engine.** Same reason — diffing requires document parsing. Coming as a sibling actor.
- **XBRL coverage is post-2009.** Older filings may not have machine-readable financials. Companies that recently IPO'd may have thin XBRL history.
- **Concept-name variations.** The actor maps 10 metrics across multiple US-GAAP + IFRS concept names but doesn't cover every possible variation. Less common metrics (current ratio, quick ratio, free cash flow) are not yet extracted.
- **Recent filings only.** SEC submissions endpoint returns the most-recent ~1,000 filings per company. For deep history use the EDGAR full-text search API separately.
- **Company name lookup is fuzzy.** Common names ("United") may match unexpected entities. Tickers and CIKs are reliable; names use a precedence order (exact > startsWith > contains).
- **Rate limiting.** Conservatively 5 req/sec (SEC published limit is 10). Large batches scale linearly.

### Responsible use

- All data comes from the SEC's public EDGAR system, designed for programmatic access.
- The actor stays within SEC's published rate limits (10 req/sec) with a conservative 5 req/sec throttle. Do not bypass.
- Daily monitoring is appropriate; sub-minute polling is excessive.
- XBRL data is extracted directly from filings. Always verify critical financial data against the primary documents before investment decisions.
- The User-Agent header includes a real contact (`contact@apifyforge.com`) per SEC EDGAR's published requirements.

### Common filing types reference

| Type | Name | Description |
|:-----|:-----|:------------|
| 10-K | Annual Report | Audited annual financials, MD\&A, risk factors |
| 10-Q | Quarterly Report | Unaudited quarterly financials |
| 8-K | Current Report | Material events (earnings, M\&A, leadership, restatements) |
| DEF 14A | Proxy Statement | Executive comp, board nominees, shareholder votes |
| 4 | Insider Trading | Officer/director stock transactions |
| S-1 | Registration | IPO registration |
| S-4 | M\&A Registration | Registration related to business combination |
| 13F-HR | Institutional Holdings | Quarterly fund holdings ≥$100M AUM |
| SC 13D | Beneficial Ownership (Active) | 5%+ holder, often activist signal |
| SC 13G | Beneficial Ownership (Passive) | 5%+ holder, passive investor |
| 20-F | Foreign Annual Report | Annual report from foreign private issuer |
| NT 10-K / NT 10-Q | Late-Filing Notice | Operational warning |

### FAQ

**Do I need an API key?**
No. SEC EDGAR is completely free and public.

**What financial metrics are extracted?**
Up to 10 metrics: revenue, netIncome, totalAssets, totalLiabilities, shareholdersEquity, EPS, operatingIncome, cashAndEquivalents, totalDebt, grossProfit. Plus 8 derived ratios (margins, ROA, ROE, leverage, efficiency) and growth rates computed from those.

**How current is the data?**
The actor queries SEC EDGAR in real time. Filing data appears within minutes of SEC processing.

**Can I search for non-US companies?**
Yes if they file with the SEC (typically via ADRs or direct US listings). Both US-GAAP and IFRS XBRL taxonomies are supported.

**What is a CIK number?**
Central Index Key — SEC's 10-digit unique identifier per filer. Apple is `0000320193`. You can search by CIK, ticker, or name.

**How many companies can I analyze in one run?**
Hard cap of 500 per the input schema. Above 100 the actor logs a cost warning. Each company is a separate PPE event.

**How does the watchlist work across runs?**
Set the same `watchlistName` on every scheduled run. The actor opens a named KV store keyed by the name and persists per-company snapshots (last filing accession, last filing date, FIFO of seen accessions, latest financial fingerprint). On the next run, the `delta` block tells you what's new.

**Can I get results in CSV format?**
Yes — `FILINGS.csv` and `FINANCIALS.csv` are written to the run's KV store. The Apify dataset also exports to CSV via `format=csv` query parameter.

**Why is a metric missing for some companies?**
Smaller filers, recent IPOs, and foreign issuers sometimes report under non-standard XBRL concepts the actor doesn't yet map. The `dataSources` field shows whether companyfacts-xbrl was even available; `pipelineState.financialsFetched: false` means we tried but XBRL was empty.

**Does the actor scrape filing documents?**
No — only structured metadata + XBRL. Document-body extraction (Risk Factors, MD\&A, Legal Proceedings) is a separate actor concern. The `url` field on every filing points to the raw document on SEC.gov.

### How much does it cost?

Pay-per-event: **$0.30 per company analyzed.** The actor charges only after a successful `pushData()` — no charge for not-found companies, no charge for failed API calls, no charge above your spending limit (the run breaks cleanly when `eventChargeLimitReached` fires).

| Scenario | Companies | Cost |
|:---------|:----------|:-----|
| Mag 7 — historical trends | 7 | $2.10 |
| Dow 30 — compliance audit | 30 | $9.00 |
| 100-company quant batch | 100 | $30.00 |
| Daily 8-K monitor on Mag 7 | 7/day × 30 = 210/mo | $63.00/mo |
| Daily 8-K monitor on Dow 30 | 30/day × 30 = 900/mo | $270.00/mo |

The $5 Apify Free Tier covers ~16 companies / month. SEC EDGAR API itself is free.

### Integrations + downstream destinations

The actor is built to drop directly into existing event-driven, monitoring, and orchestration stacks. Every output field is a stable enum or typed primitive — downstream consumers read fields directly, no prose-parsing required.

#### Alert + notification channels

- **Slack** — POST `record.alertPayloads.slack` (Slack Block Kit) directly to a webhook URL. Severity colour-coded.
- **Discord** — POST `record.alertPayloads.discord` (embed format) directly to a Discord webhook.
- **Microsoft Teams** — Use the `flat` payload + a generic Teams webhook adapter.
- **Email** — Send `batchInsights.headline` + `keyTakeaways[]` + `priorityQueue[].reason` as digest emails.
- **PagerDuty / Opsgenie** — Branch on `recommendedAction.urgency = 'immediate'` AND `reviewSla.slaTier = 'P0'` to trigger paging.

#### Workflow orchestration

- **Dify** — `nextActions[]` array drops directly into an Iteration node + Run Actor node for multi-step actor chains.
- **n8n** — Stable enums (`materiality.level` / `delta.type` / `recommendedAction.team`) feed if/else branches without prose parsing.
- **Zapier / Make** — Filter rules read flat-enum fields directly (`WHERE companyState.watchStatus IN ('urgent', 'critical')`).
- **Apache Airflow** — Schedule the actor as a daily DAG task; downstream tasks branch on `decisionTrace[]` codes.
- **Temporal / Cadence** — Workflow signals on `eventChains[].pattern` enum values.

#### Ticket / incident systems

- **Jira / Linear** — `recommendedAction.team` + `reviewPacket.handoffNotes` map cleanly to issue title + description fields.
- **GitHub Issues** — Same shape; the `reviewPacket` block is paste-ready into issue body.
- **ServiceNow** — Route `recommendedAction.team = 'compliance'` records into compliance-incident queues.

#### Data warehouse + analytics

- **Snowflake / BigQuery / Redshift** — Pull `FILINGS.csv` + `FINANCIALS.csv` from KV directly via Apify dataset export. Flat schemas.
- **Google Sheets** — Direct CSV import.
- **dbt / metabase / Looker** — Stable enum vocabulary makes SEMANTIC LAYER joins predictable; field names don't drift across versions.

#### SIEM + security operations

- **Splunk / Datadog / Elastic** — Ingest `recordType: 'company-analysis'` records as typed events; alert rules branch on `companyState.watchStatus` + `secRisk.band`.

#### Vector DB + RAG

- **Pinecone / Weaviate / Qdrant / Chroma** — `outputProfile: 'llm'` strips noise; embed the `summary` + `narrativeDelta.summary` strings for retrieval-augmented agent flows.

#### AI agents + LLM workflows

- **AI agents (any framework)** — See "AI agent integration" section above. Optimised for low-token agent consumption with persona-driven `routingProfile`.
- **LLM tool-call selection** — Stable enum vocabulary + structured outputs make this actor a reliable tool in agent registries; no hallucinations to guard against.
- **Apify MCP servers** — Register as a tool; agent calls it like any other deterministic API.

#### Apify-native

- **Webhooks** — `Actor.addWebhook` already wired for failure events.
- **Scheduler** — Schedule any `routingProfile` configuration on a daily / weekly cadence; `watchlistName` persistence does the rest.
- **REST API** — Call programmatically from any language. Full `ApifyClient` examples above.

# Changelog

This Actor's version history is a separate document: https://apify.com/ryanclinton/sec-edgar-filing-analyzer/changelog.md

# Actor input Schema

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

Company tickers, names, or CIK numbers to look up (e.g. AAPL, Tesla, 0000320193). Combine with a tickerPack to add a pre-built portfolio on top of your explicit list.

## `tickerPack` (type: `string`):

Optional pre-built portfolio of tickers. When set, expands into the companies list (then deduped against your explicit companies). One-click sector / index analysis.

## `mode` (type: `string`):

Execution preset bundling filing types + materiality flagging + cohort/batch insights + delta tracking.

Technical modes:
• latest-filings — recent filings + latest financials snapshot (default).
• financial-snapshot — latest financial metrics only; fastest, cheapest path.
• historical-trends — multi-period financials with YoY/QoQ trends + anomaly flags.
• 8k-monitor — 8-K material-event monitor; pair with watchlistName.
• compliance-audit — historical financials + materiality + cohort rollup.
• raw — raw filings only, no opinionated layers.

Outcome-led modes (same machinery, named for the user's job):
• earnings-monitor — 10-Q + 10-K + 8-K Item 2.02. Schedule for earnings tracking.
• governance-monitor — DEF 14A + 8-K Item 5.02 / 5.07. Schedule for leadership / shareholder vote alerts.
• distress-monitor — 8-K Item 1.03 / 2.06 / 4.01 / 4.02 + late-filing notices.
• activist-monitor — SC 13D + SC 13G + DEF 14A + 8-K Item 5.01. Track 5%+ holders + control changes.
• quarterly-review — 10-Q + 10-K with 4 historical periods + cohort rollup.

## `systemMode` (type: `boolean`):

When true, automatically enables batch insights + cohort insights + delta tracking unless you explicitly set them or your mode preset disables them. Pair with watchlistName to flip the actor from one-shot to monitoring product.

## `watchlistName` (type: `string`):

Persists per-company state across runs in a named KV store (sec-edgar-filing-analyzer-history-<watchlistName>). Required for delta detection. Different watchlistName values keep separate state — run two pipelines side-by-side without pollution. First-run note: every record will carry delta.type="new" until run 2.

## `filingTypes` (type: `array`):

SEC filing types to retrieve (e.g. 10-K, 10-Q, 8-K, 4, DEF 14A). Leave empty for all types. The 8k-monitor mode forces 8-K only unless overridden here.

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

Maximum number of filings to return per company.

## `dateFrom` (type: `string`):

Only include filings after this date (YYYY-MM-DD format).

## `dateTo` (type: `string`):

Only include filings before this date (YYYY-MM-DD format).

## `includeFinancials` (type: `boolean`):

Fetch structured financial data (revenue, net income, assets, etc.) from XBRL filings. Mode preset overrides this when set.

## `historicalPeriods` (type: `integer`):

How many historical periods to extract per financial metric. 1 = latest only (no trend). 2-8 = enables YoY/QoQ trend analysis + anomaly detection. Mode preset overrides this when set (historical-trends → 8, compliance-audit → 4, others → 1).

## `flagMaterialFilings` (type: `boolean`):

Tag every filing with a materiality block (level critical/high/medium/low + category + reason). 8-K item codes drive the classification — Item 4.01 (auditor change), 5.02 (officer departure), 1.03 (bankruptcy) flip to critical/high. Mode preset overrides this when set.

## `includeBatchInsights` (type: `boolean`):

Push a batch-summary record at the end of the run with hero fields (headline / oneLine / keyTakeaways / confidence) + list-quality score + recommendations. Useful for multi-company runs. Auto-on with most modes + systemMode.

## `includeCohortInsights` (type: `boolean`):

Group companies by SIC sector and emit one cohort-summary record per sector with avg revenue YoY, material-filing count, and risk tag. Auto-on with historical-trends, compliance-audit, and systemMode.

## `deltaMode` (type: `boolean`):

Compute delta block per company: new (first sight), unchanged, new-filings (new accessions since last run), material-event (new HIGH/CRITICAL filing). Auto-on with 8k-monitor and systemMode.

## `outputProfile` (type: `string`):

Strip output detail to match the consumer.

• standard — default, all blocks.
• minimal — strip diagnostic prose; keep filing essentials, materiality flags, financials.
• full — same as standard.
• llm — drop history arrays + per-filing prose; keep summary + decisions for LLM consumption.

## `triggers` (type: `array`):

User-defined deterministic triggers — no LLM, no code, no regex (except matchesPattern). Each rule: { name, field, op, value, tag, severity, note }. Operators: gte / lte / gt / lt / eq / in / notIn / contains / matchesPattern. Field paths: scorecard.materialityScore, scorecard.financialTrendScore, scorecard.dataQualityScore, scorecard.monitoringPriority, secRisk.score, secRisk.band, filingVelocity.current30d, filingVelocity.velocityRatio, filingVelocity.signal, filingPressureIndex.score, filingPressureIndex.band, derivedMetrics.debtToEquity.value, derivedMetrics.returnOnEquity.value, derivedMetrics.anomalyCount, materialFilingsCount, delta.type, delta.impact, operationalDrift.status, companyState.financialHealth, companyState.governanceRisk, companyState.eventPressure, companyState.watchStatus.

Matched rules surface in triggersFired\[] on each record.

## `includeAlertPayloads` (type: `boolean`):

When true, every record gets a pre-formatted alertPayloads block: Slack Block Kit message, Discord embed, and a generic flat-JSON shape for Zapier / Make / n8n. Severity is derived from companyState.watchStatus + filingPressureIndex.band. Default: auto-on with systemMode.

## `includeBehaviorFingerprint` (type: `boolean`):

Per-company filing-behaviour profile — amendmentRate, governance turnover, cadence enum, classification (high-disclosure-volatility / amendment-heavy / governance-volatile / distress-signal-cluster / normal). Default: auto-on with systemMode.

## `includeTimeline` (type: `boolean`):

Emit a chronological one-line summary of material events, sorted oldest → newest, with chain-pattern headline. Default: auto-on with systemMode.

## `routingProfile` (type: `string`):

Pre-built persona configuration that bundles trigger pack + alert payloads + SLA tightness defaults.

• hedge-fund — earnings + financial-shift focus, immediate alerting.
• pe — distress + drift focus.
• compliance — auditor + governance + restatement, tightest SLAs.
• ir — activist + governance + earnings.
• quant — full data shape, no opinionated alert formatting.
• retail-monitoring — governance + earnings only.

## `triggerPack` (type: `string`):

Pre-built deterministic trigger bundle. Combines with explicit triggers\[] (user triggers win on name conflict).

• auditor-risk — auditor changes, restatements, amendment clusters.
• distress — bankruptcy, impairment, declining health, leverage blowout.
• earnings-volatility — anomalies + financial shifts.
• activist — SC 13D buildup + control-change patterns.
• governance-risk — officer departures + governance shakeups.

## `includePortfolioState` (type: `boolean`):

Emit portfolioState + priorityQueue + watchlistAnalytics on the batch-summary record. Default: on for multi-company runs.

## `includeReviewPacket` (type: `boolean`):

reviewPacket bundles whyFlagged + topEvents + requiredAttention + estimatedReviewTimeMinutes + handoffNotes — paste-ready for Slack triage. Default: auto-on with systemMode.

## `includeNarrativeDelta` (type: `boolean`):

Template-generated 'what changed since last run' sentences (no LLM). Requires watchlistName. Default: auto-on with systemMode.

## `includeActiveSignals` (type: `boolean`):

Per-event decay weight using per-category persistence half-lives (bankruptcy 3y, auditor change 18mo, earnings release 90d). Default: auto-on with systemMode.

## `includeRegimeShift` (type: `boolean`):

Detects when current behaviour diverges from historical fingerprint. Requires watchlistName for prior-data comparison. Default: auto-on with systemMode.

## `includeExplainability` (type: `boolean`):

Top-5 contributors to current state across SEC risk + pressure + drift + chains. Default: auto-on with systemMode.

## Actor input object example

```json
{
  "companies": [
    "AAPL",
    "TSLA"
  ],
  "tickerPack": "",
  "mode": "latest-filings",
  "systemMode": false,
  "filingTypes": [
    "10-K",
    "10-Q",
    "8-K"
  ],
  "maxFilingsPerCompany": 20,
  "outputProfile": "standard",
  "routingProfile": "",
  "triggerPack": "",
  "includePortfolioState": true
}
```

# Actor output Schema

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

No description

# 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 = {
    "companies": [
        "AAPL",
        "TSLA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/sec-edgar-filing-analyzer").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 = { "companies": [
        "AAPL",
        "TSLA",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/sec-edgar-filing-analyzer").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 '{
  "companies": [
    "AAPL",
    "TSLA"
  ]
}' |
apify call ryanclinton/sec-edgar-filing-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ryanclinton/sec-edgar-filing-analyzer"
        }
    }
}
```

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/WzyzKk9d1gUbwahK5/builds/aW8gNpDBZf7iKM3Qc/openapi.json
