# Litigation Check — Company Litigation History Screener (`zinin/litigation-check`) Actor

Screen a counterparty for litigation history across US federal PACER dockets, UK case law and Poland's SAOS judgment index — party-name search where the source supports it, keyless, no login.

- **URL**: https://apify.com/zinin/litigation-check.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Litigation Check — Company Litigation History Screener

Screen any counterparty for litigation history before you sign a contract or onboard a client. This Actor checks a company name against US federal PACER dockets, UK case law and Poland's SAOS judgment index, and returns one row per company × jurisdiction with the case count and the top cases found — no API key, no login, no browser.

### What you get

- **US federal dockets by party name, not full text.** CourtListener's structural `party:"..."` search matches the company as an actual named party in a PACER docket — not a passing mention somewhere in a document.
- **UK case law, same structural guarantee.** England & Wales and UK Supreme Court judgments, filtered by the official caselaw.nationalarchives.gov.uk API's own `party=` parameter — a genuine party-to-the-case match, not a full-text scan. (For "Tesla, Inc." that's 3 real Tesla-as-litigant cases, not the 42 you'd get from a plain keyword search.)
- **Poland, honestly labeled.** SAOS is a full-text search — every Polish row carries `signal:"fulltext-mention"` so you never mistake a keyword hit for a confirmed litigant the way US/UK rows are.
- **A clean history is a result, not a null.** `caseCount: 0` with `found: true` means the check ran and came back clean — that's the due-diligence answer you're paying for, not a failed lookup.
- **No API key, no login, no browser.** Three keyless public HTTP endpoints, called directly.
- Runs on Apify: schedule it, monitor it, call it from the API or the MCP server, export to JSON, CSV or Excel, or push straight into your own pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste company legal names into **Companies**, one per line — e.g. `Tesla, Inc.`.
3. Pick which **Jurisdictions** to check: `US`, `UK`, `PL` (defaults to `US` only).
4. Press **Start**. Results appear in the dataset — read them in the UI, pull them from the API, or have a webhook push them onward.

### Pricing

Pay-per-event: **$0.005 per run start + $0.02 per completed check** (one company × one jurisdiction). No monthly seat, no minimum.

A completed check is billed **whether the result is dirty or clean** — `caseCount: 0` is a real answer, not a failure. What is *not* billed: a row where the source itself failed — timeout, HTTP error, a response cut off mid-read, or a payload that isn't the shape this Actor expects (e.g. a CDN error page instead of real data) — or where you asked for a jurisdiction this Actor doesn't cover. All of these come back as `found: false` with an `error`, free.

5 companies × 3 jurisdictions = 15 checks ≈ **$0.305**. The worst-case input (20 companies × 3 jurisdictions = 60 checks, this Actor's runtime cap) ≈ **$1.21**.

Set a lower run budget (`maxTotalChargeUsd`) than the input implies, and the Actor stops early rather than exceeding it: the pairs that were never checked simply aren't in the dataset, and the last row explains that the run halted for budget reasons — see Output.

If you watch this Actor's run log, a `chargedCount` number sometimes appears next to a "budget limit reached" line. That is the Apify SDK's own internal count of billed *events* for a single result row — typically `2` (one for `result-found`, one for the platform's own per-dataset-item bookkeeping event), not the number of paid rows delivered and not a dollar amount. Ignore it for cost purposes; the dataset row count and the Pricing math above are the real numbers.

Both promises above — that error/unsupported-jurisdiction rows are free, and that the worst case tops out at $1.21 — hold as long as this Actor's own Pricing tab prices only `apify-actor-start` and `result-found`. If its automatic per-dataset-row event were ever priced too, every row (including the "free" ones) would carry that extra charge; this Actor checks for that on every run, and rather than let that happen silently, it fails the run outright — no rows at all, not even an explanation row, since writing one would itself be billed at that broken price — see Output.

### Input

| Field | Required | What it does |
|---|---|---|
| `companies` | yes | Legal names to screen, one per line. Up to 20. Use the full legal name for the cleanest match (`Tesla, Inc.`, not `Tesla`). |
| `jurisdictions` | no | Which court systems to check: `US`, `UK`, `PL`. Defaults to `["US"]`. Up to 3. Any other code comes back as a free "unsupported jurisdiction" row instead of being rejected. |
| `maxCasesPerRow` | no | How many individual cases to list per row, 1-50 (default 20). `caseCount` reports the true total matched for US/PL — approximate above ~2000 matches, see Output — even when fewer are listed; for UK it can be a lower bound when `partial` is `true` (see Output). |
| `maxConcurrency` | no | How many companies to check in parallel, 1-2 (default 2). Each company's jurisdictions are always fetched in parallel with each other. |

```json
{
    "companies": ["Tesla, Inc."],
    "jurisdictions": ["US"]
}
```

### Output

One dataset row per company × jurisdiction. A run can end early with one of five self-explanatory final rows instead of the full result set — always check `sourceNote` on whichever one shows up. For most of these, "early" means genuinely unchecked pairs remain (if every pair you asked for already has a row, no halt row is added even if the budget ran out on the very last one) — the one exception is the delivery-error row, noted below, where that is not knowable.

- `company: "(run halted — budget exhausted)"` — your run's maximum charge was reached; the remaining pairs were never checked or charged for. Raise `maxTotalChargeUsd` to get the full set.
- `company: "(run halted — pricing misconfigured)"` — `result-found` itself isn't billable on this run (a deployment/Pricing-tab mismatch), and this Actor refuses to give away paid rows for free rather than silently working for nothing. That one is on us, not your budget: raising `maxTotalChargeUsd` will not fix it — open an issue on this Actor's page. (If instead this Actor's automatic per-dataset-item event is priced — or this run's pricing tariff could not be read at all, so that price is simply unknown — there is no halt row at all: writing one would itself risk being billed at an unconfirmed price, so the run ends as **FAILED** with no output rows and the reason in its status message and log, not in the dataset. This should never happen on a correctly configured deployment.)
- `company: "(run halted — budget check failed)"` — reading the remaining budget itself failed unexpectedly (rare, usually transient). Retrying the run should work.
- `company: "(run halted — delivery error)"` — a push/charge call to the platform failed partway through, on a row that would have been billed. That specific pair's row may or may not have already been delivered without being billed — this Actor can't tell from here, so it stops rather than risk a duplicate or an unbilled row. This is the one halt row that can appear even when every pair technically has a row already — it errs toward over-explaining rather than silently leaving out the caveat. Usually transient; retrying the run should work.
- `company: "(run halted — delivery failure)"` — a plain (free, uncharged) dataset write failed unexpectedly — an error row or an unsupported-jurisdiction row never made it into the dataset. Usually transient; retrying the run should work.

This is real data from a live run against CourtListener:

```json
{
    "company": "Tesla, Inc.",
    "jurisdiction": "US",
    "found": true,
    "caseCount": 592,
    "partial": false,
    "cases": [
        {
            "name": "Marina Faragalla v. Tesla, Inc.",
            "court": "C.D. Cal.",
            "date": "2025-07-11",
            "number": "5:25-cv-01752",
            "url": "https://www.courtlistener.com/docket/70764837/marina-faragalla-v-tesla-inc/",
            "signal": "party"
        },
        {
            "name": "Molina v. Tesla, Inc.",
            "court": "S.D. Tex.",
            "date": "2026-06-12",
            "number": "2:26-cv-00167",
            "url": "https://www.courtlistener.com/docket/73480220/molina-v-tesla-inc/",
            "signal": "party"
        }
    ],
    "sourceNote": "US federal PACER dockets via CourtListener v4, structural party-name search (party:\"Tesla, Inc.\"). 592 total docket(s) matched; showing up to 20.",
    "checkedAt": "2026-07-28T18:41:00.000Z"
}
```

| Field | What it means |
|---|---|
| `company` | The company name you passed — except on the one halt row a run can end with, where it's a self-explanatory placeholder (`"(run halted — budget exhausted)"`, `"(run halted — pricing misconfigured)"`, `"(run halted — budget check failed)"`, `"(run halted — delivery error)"`, or `"(run halted — delivery failure)"`, see above; a mis-tariffed dataset-item price, or a tariff that couldn't be read at all, produces no row at all, only a FAILED run status, see above) |
| `jurisdiction` | `US`, `UK` or `PL` — `null` on a halt row |
| `found` | Whether the check completed — `true` even for a clean (`caseCount: 0`) result. `false` when the source itself failed, the jurisdiction isn't supported, or (on the one possible halt row) the run stopped early |
| `caseCount` | Total cases matched. For US/PL, the source's own total regardless of pagination — exact for PL, and exact for US up to roughly 2000 matches (CourtListener switches to a cardinality-estimate count above that volume, +/-~6%; still the right number to report, just not exact at high volume — `sourceNote` flags it when this applies). For UK it's the count on the one feed page fetched — a **lower bound** when `partial` is `true` |
| `partial` | `true` only for UK, only when more result pages exist beyond the one fetched — meaning `caseCount` undercounts the true total. Always `false` for US/PL. A `partial: true` row is still billed: the check ran and returned a real (if not exhaustive) answer |
| `cases` | Up to `maxCasesPerRow` cases: `name`, `court`, `date`, `number` (docket/case number), `url`, and `signal` (`"party"` — a named party in an official docket/case title, US or UK, or `"fulltext-mention"` — a keyword hit, Poland only) |
| `sourceNote` | Which source answered and how to read the count |
| `error` | Present only when `found` is `false` — why the check didn't complete |
| `checkedAt` | When this Actor ran the check |

### Other tools we built

#### Need the rest of the picture?

These run on the same account, take the same shape of input and bill the same way, so they slot into an existing pipeline without new plumbing.

| Actor | What it does |
|---|---|
| [AI Answer Change Alert](https://apify.com/zinin/ai-answer-change-alert) | Track whether an AI assistant's answer to a query you care about changed since last time — new sources… |
| [AI Crawler Access Checker](https://apify.com/zinin/ai-crawler-access-checker) | Check which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended & more) can access your website |
| [AI Overview Citation Tracker](https://apify.com/zinin/ai-overview-tracker) | For each query that matters, see which sources and domains AI assistants cite in their answer — grounded… |
| [B2B Lead Enricher](https://apify.com/zinin/b2b-lead-enricher) | Turn a list of company websites into sales-qualified lead cards: detected tech stack, a rough revenue… |
| [Chotot Vietnam Listings Scraper](https://apify.com/zinin/chotot-listings) | Pull live classified ad listings (real estate, vehicles, electronics, jobs and more) straight from… |

### FAQ / Limitations

**Is this a legal opinion?** No. This is a screening tool — a fast first pass to flag counterparties worth a closer look, not a substitute for a lawyer or a paid PACER/Companies House pull.

**Why only US, UK and Poland?** These are the jurisdictions with a public, keyless, machine-readable search that actually works today. Brazil's DataJud API structurally cannot return party names (LGPD — the field isn't in the response at all), and the Netherlands' public case-law search isn't built to search by company name. Both are excluded rather than faked with a workaround that would silently mislead you.

**Why is Poland different from US/UK?** SAOS is a full-text search over judgment documents, not a structural party-name index like CourtListener or find-caselaw. A hit means the company name appears somewhere in the text — it could be the litigant, a cited third party, or a passing reference. Every Polish row is tagged `signal:"fulltext-mention"` for exactly this reason, and SAOS's own ingestion lags real court activity by months.

**What this is NOT.** It does not read case documents or judgment text, does not assess case merit or outcome likelihood, and does not cover state/provincial courts, arbitration, or jurisdictions outside US/UK/PL.

Found a wrong result, or need a jurisdiction we don't cover? Open an issue on this Actor's page.

***

Built by [zinin](https://apify.com/zinin). Questions? Telegram [@timzinin](https://t.me/timzinin).

# Actor input Schema

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

Legal names of companies / counterparties to screen for litigation history. One row is produced per company per selected jurisdiction, up to your run's maximum charge (maxTotalChargeUsd) — if that budget runs out early, the remaining pairs are skipped and a final row explains why. Use the full legal name for the cleanest match (e.g. "Tesla, Inc." rather than "Tesla").

## `jurisdictions` (type: `array`):

Which court systems to check: US, UK, PL. US = federal PACER dockets via CourtListener (structural party-name search). UK = England & Wales / UK Supreme Court case law (structural party-name search, same guarantee as US). PL = Poland SAOS full-text judgment search — a keyword mention, not a confirmed party (see README). Any other code is returned as a free, graceful "unsupported jurisdiction" row rather than rejected — see the README for what's excluded and why.

## `maxCasesPerRow` (type: `integer`):

How many individual cases to list per company x jurisdiction row. caseCount reports the true total matched for US/PL (approximate above ~2000 matches — CourtListener's own count estimate), even when fewer are listed here; for UK it can be a lower bound when the output row's partial field is true (see README).

## `maxConcurrency` (type: `integer`):

How many companies to check in parallel. Each company's selected jurisdictions are always fetched in parallel with each other regardless of this setting.

## Actor input object example

```json
{
  "companies": [
    "Tesla, Inc."
  ],
  "jurisdictions": [
    "US"
  ],
  "maxCasesPerRow": 10,
  "maxConcurrency": 2
}
```

# 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": [
        "Tesla, Inc."
    ],
    "jurisdictions": [
        "US"
    ],
    "maxCasesPerRow": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/litigation-check").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": ["Tesla, Inc."],
    "jurisdictions": ["US"],
    "maxCasesPerRow": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("zinin/litigation-check").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "Tesla, Inc."
  ],
  "jurisdictions": [
    "US"
  ],
  "maxCasesPerRow": 10
}' |
apify call zinin/litigation-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zinin/litigation-check",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ybyRD5b0ztnevr87N/builds/0m13Zwpiccu1rkyso/openapi.json
