# Piotroski F-Score, Altman Z, Beneish M: SEC XBRL, No API Key (`willed_nursery/sec-financial-health-score`) Actor

Enter tickers or CIKs and get one row per company with Piotroski F, Altman Z'/Z'' (book equity), and Beneish M, computed from official SEC XBRL with the exact tags used and a data-completeness %. No key needed. You only pay when a score is computed. Not investment advice.

- **URL**: https://apify.com/willed_nursery/sec-financial-health-score.md
- **Developed by:** [Joel Sumner](https://apify.com/willed_nursery) (community)
- **Categories:** AI, Business, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 company scoreds

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

## Piotroski F-Score, Altman Z'/Z'' & Beneish M-Score by Ticker — SEC EDGAR XBRL, No API Key

**Stock fundamentals screener for financial-distress and earnings-manipulation risk**, computed straight from official SEC EDGAR XBRL filings. The Altman score is the **book-equity Z'/Z''** variant (no market prices) — see the caveat below.
Give it a list of tickers or CIKs. You get one row per company with **Piotroski F-score (0–9, all 9 flags)**, **Altman Z'/Z'' book-equity score (`altman_z_book`, Z' for manufacturers, Z'' otherwise; model in `altman_model`) and its zone** — this is NOT classic market-value Z; do not apply the 1.81/2.99 cutoffs, **Beneish M-score with a manipulation flag**, plus **data-completeness %**, `missing_fields`, the XBRL `tags_used` for each input, the fiscal period ends, and a plain-English `explain` line.
Source: SEC's official `data.sec.gov/api/xbrl/companyfacts` and `submissions` (for SIC). No API key. Deterministic formulas, no LLM.

### Raw SEC facts vs computed scores

| | SEC EDGAR financials Actors | This Actor |
|---|---|---|
| Output | raw XBRL facts / filings | Piotroski F (9 flags), Altman Z'/Z'' + zone, Beneish M + flag |
| Fiscal-year alignment, tag variance, restatements | you handle it | handled; `tags_used` shows every tag |
| Missing data | silent | `data_completeness_pct`, `missing_fields`, partial F, `beneish_confidence` |
| API key | varies | none |

### Why

Other SEC actors return raw facts. To get F, Z or M from them you still have to align fiscal years, deal with tag variance (Revenues vs RevenueFromContractWithCustomer…, ProfitLoss vs NetIncomeLoss) and handle restatements. This actor does that and tells you exactly which tag it used and what was missing.

### Formulas

- **Piotroski F** uses the two most recent annual filings (10-K, 10-K/A, 20-F, 40-F, with ~365-day durations, latest restatement wins). The tests are ROA>0, CFO>0, ΔROA>0, CFO/A>ROA, Δleverage≤0 (long-term debt / assets; if LTD is not tagged in either year — after trying LongTermDebtNoncurrent, LongTermDebt, LongTermDebtAndCapitalLeaseObligations, then DebtInstrumentCarryingAmount — the test is null, never treated as zero debt), Δcurrent ratio>0, no share dilution (basic weighted shares ≤ +0.5%), Δgross margin>0 and Δasset turnover>0. ROA uses beginning-of-year assets. If any test can't be computed, `piotroski_f` is null and `partial_score` plus `tests_available` are reported.
- **Altman**: we don't use price data, so the market-value Z isn't available. SIC 2000–3999 uses **Z'** = 0.717X1+0.847X2+3.107X3+0.420X4+0.998X5, with zones safe >2.9 and distress <1.23. Everything else uses **Z''** = 6.56X1+3.26X2+6.72X3+1.05X4, with zones safe >2.6 and distress <1.1. X4 = book equity / total liabilities. Banks and insurers (SIC 6000–6799) are flagged `not_meaningful_for_financials`.
- **Beneish M** (8-variable) = −4.84+0.92DSRI+0.528GMI+0.404AQI+0.892SGI+0.115DEPI−0.172SGAI+4.679TATA−0.327LVGI. A score above −1.78 gets the flag `likely_manipulator_zone`. If DEPI or SGAI is missing, it is set to a neutral 1, listed in `imputed_neutral`, noted in `explain` (e.g. "SGAI imputed") and `beneish_confidence` is `reduced` (else `full`). TATA = (net income − CFO) / total assets — the common cash-flow variant, not Beneish's original balance-sheet accruals. LVGI is null (M null) when long-term debt is untagged. If any other variable is missing, M is null.
- Fallbacks: gross profit = revenue − cost of revenue; liabilities = assets − equity; EBIT = pretax income + interest expense. Each fallback is shown in `tags_used`.

### Example input

```json
{"companies":["AAPL","F","0000789019"],"userAgentEmail":"you@example.com"}
```

### Output sample (MSFT, live smoke, trimmed)

```json
{"ticker":"MSFT","cik":"0000789019","piotroski_f":6,"altman_model":"Z''","altman_z_book":4.593,"altman_zone":"safe",
 "beneish_m":-2.6647,"beneish_confidence":"reduced","beneish":{"imputed_neutral":["SGAI"]},
 "data_completeness_pct":94,"missing_fields":["sga"],"explain":"... SGAI imputed ..."}
```

### All input options

`companies` (array of tickers or CIKs), `userAgentEmail` (required by SEC fair-access policy). Requests are capped at 8/s.

### Output (key fields)

- `piotroski_f` (null unless all 9 tests computable), `piotroski.partial_score`, `piotroski.tests_available`, `piotroski.components`
- `altman_model` (`Z'` or `Z''`), `altman_z_book` (book-equity Z'/Z''), `altman_z` (deprecated alias of `altman_z_book`, same book-equity value — not market Z), `altman_zone`
- `beneish_m`, `beneish_flag`, `beneish_confidence` (`full` / `reduced` when DEPI/SGAI imputed), `beneish.imputed_neutral`, `beneish.tata_definition`
- `data_completeness_pct`, `missing_fields`, `tags_used`, `explain`

### Pricing (pay per event)

$0.00005 per actor start + **$0.004 per company with at least one computed score** — i.e. charged when any one of F/Z/M is computed. Example: Ford returns a partial F (8 of 9 tests, LTD untagged) plus Z' 0.69 and null M → charged once, $0.004. Unknown tickers, companies without XBRL, and rows with no score are **free**.

### Limits

- Data comes only from XBRL as filed. Companies that use unusual custom tags can come back partial.
- A newly re-registered holding company (e.g. XOM's ticker now maps to a 2026 holding-company CIK) may have no annual history yet. Pass the predecessor CIK instead.
- Captive finance arms (F, GM, CAT): the SIC is non-financial but consolidated finance receivables/debt distort Z'/Z'' and leverage; treat those scores as weak.
- Energy and financial filers often omit GrossProfit, so GMI/gross-margin tests (and M) can be null.
- Not investment advice. Not affiliated with the SEC.

### Disclaimer

Scores are mechanical calculations from SEC XBRL filings for research and screening. Not investment advice; not affiliated with the SEC. Altman here is book-equity Z'/Z'', not market-value Z.

### More Actors by willed_nursery

- Healthcare credentialing pair: [NPI Roster Validator](https://apify.com/willed_nursery/npi-roster-validator) ↔ [OIG LEIE Screener](https://apify.com/willed_nursery/leie-exclusion-roster-screen)
- KYB/lead: [Domain Contact Enricher](https://apify.com/willed_nursery/domain-contact-enricher)
- IP docket: [USPTO Trademark Deadlines](https://apify.com/willed_nursery/trademark-portfolio-deadline-scorer)
- Financial risk: [SEC Health Score](https://apify.com/willed_nursery/sec-financial-health-score)

# Actor input Schema

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

US tickers (AAPL, BRK.B) or SEC CIK numbers. Max 5000 per run.

## `userAgentEmail` (type: `string`):

SEC fair-access policy requires a contact email in the User-Agent. Sent only to sec.gov.

## Actor input object example

```json
{
  "companies": [
    "AAPL",
    "F",
    "0000789019"
  ],
  "userAgentEmail": "your-email@example.com"
}
```

# 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",
        "F",
        "0000789019"
    ],
    "userAgentEmail": "your-email@example.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("willed_nursery/sec-financial-health-score").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",
        "F",
        "0000789019",
    ],
    "userAgentEmail": "your-email@example.com",
}

# Run the Actor and wait for it to finish
run = client.actor("willed_nursery/sec-financial-health-score").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",
    "F",
    "0000789019"
  ],
  "userAgentEmail": "your-email@example.com"
}' |
apify call willed_nursery/sec-financial-health-score --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,willed_nursery/sec-financial-health-score"
        }
    }
}
```

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/YW4YWt3edwvBmP4RS/builds/UZ6PVjaZTpfxDq6EV/openapi.json
