# CourtListener Judge Analytics Scraper (`parseforge/courtlistener-judge-analytics-scraper`) Actor

Judge analytics from CourtListener: opinions authored, cases assigned, nature of suit mix, tenure and appointer, one row per judge. Export to CSV, JSON, Excel or XML.

- **URL**: https://apify.com/parseforge/courtlistener-judge-analytics-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Lead generation, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.53 / 1,000 results

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

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

## What's an Apify Actor?

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

![ParseForge Banner](https://github.com/ParseForge/apify-assets/blob/ad35ccc13ddd068b9d6cba33f323962e39aed5b2/banner.jpg?raw=true)

## 📊 CourtListener Judge Analytics Scraper

> 🚀 **Export a measured caseload and authorship profile for any US judge in seconds.** Pick a court, a party, a law school or an appointing president, and get one 43-field row per judge: opinions authored, cases assigned, the nature of suit mix, the most cited decisions, tenure and confirmation dates. The judiciary database holds 15,119 profiles across 3,359 courts.

CourtListener publishes three separate things about the American judiciary: who the judges are, which dockets they were assigned, and which opinions they wrote. Nothing joins them. This Actor does the join. It reads the judiciary database through the public REST API, then runs the opinion index and the RECAP docket index against each judge and hands back one flat, spreadsheet-ready row of measured analytics per person.

The numbers are real counts, not estimates. Judge Jed Rakoff of the Southern District of New York comes back with 512 authored opinions and 8,344 assigned dockets. Judge Charles Breyer of the Northern District of California comes back with 124 and 16,640. Every row carries the two archive totals, a career span measured from the first record to the last, a nature of suit breakdown, the five most cited opinions with their citation counts, and the seats, appointer, party and confirmation dates behind them.

| 🎯 Target Audience | 💡 Primary Use Cases |
| --- | --- |
| Litigators and trial teams | Read the bench before you file: what a judge actually handles and how fast it closes |
| Legal analytics and litigation finance | Judge-level caseload and authorship features with stable CourtListener IDs |
| Law firm business intelligence | Which judges take the patent, copyright or civil rights work in a district |
| Academics and judicial politics researchers | Appointer, party, ABA rating and tenure joined to measured output |
| Journalists and court watchers | Who is on the bench, how long, and what they have written |

### 📋 What the CourtListener Judge Analytics Scraper does

> 💡 **Why it matters:** CourtListener has a judge database, an opinion index and a docket index, and no way to ask "how many opinions has this judge written and what kind of cases land on their docket". Answering it by hand is two field queries per judge plus a distribution you have to count yourself. This Actor sends those queries, counts the distribution, and returns it as one row you can sort in a spreadsheet.

- Counts opinions authored per judge with a verified `author_id` field query, not a name match.
- Counts assigned RECAP dockets per judge with a verified `assigned_to_id` field query.
- Measures the career span from the first authored opinion and the first assigned case to the latest.
- Breaks the recent caseload down by nature of suit, with counts and shares.
- Ranks the judge's most cited opinions and returns them with citation counts and links.
- Reports the pending share and the median days from filing to termination on the sampled cases.
- Carries the seat, the court, the appointing president or governor, the party, the ABA rating, the confirmation date and years on the bench.
- Selects judges by court, name, law school, appointer, party, selection method or birth window, or by pasting profile URLs.
- Exports to CSV, Excel, JSON or XML from the dataset tab.

### 🎬 Full Demo (🚧 Coming soon)

A walkthrough video is in production. Until it lands, the sample records below are a real run of the default input.

### 📊 Output

Each row is one judge. The two totals (`opinionsAuthored`, `casesAssigned`) are the counts CourtListener reports for the whole archive. Every share, median and breakdown beside them is counted over the sampled window, and `sampledOpinions` and `sampledCases` tell you exactly how wide that window was.

| Field | What it holds |
| --- | --- |
| 🆔 `judgeId` / 👩‍⚖️ `name` / 🔗 `url` | CourtListener person ID, full name and profile URL |
| 🟢 `status` | Active if any seat is still open, Former once every seat has terminated |
| 💺 `currentPosition` / 🏛 `currentCourt` / 🏷 `currentCourtId` | The seat held today, or the last seat held |
| 🖊 `appointedBy` / 🎗 `politicalAffiliation` / 🗳 `selectionMethod` | Who put the judge there, the recorded party, and how the seat was filled |
| 📅 `dateFirstTookOffice` / ✅ `dateConfirmation` / ⏳ `yearsOnBench` | First start date, latest confirmation date, and years to today or to the last termination |
| 🏛 `courtsServedCount` / ⭐ `abaRating` | How many distinct courts the judge has sat on, and the ABA rating of record |
| 📝 `opinionsAuthored` | Opinions the judge authored, counted across the whole opinion index |
| 🥇 `firstOpinionDate` / 🕘 `latestOpinionDate` / 📏 `opinionYearsSpan` / 📈 `opinionsPerYear` | The authorship span and the rate over it |
| 🔬 `sampledOpinions` / 🔗 `sampledOpinionCitations` / 📢 `publishedSharePct` | Size of the opinion sample, citations across it, and the published share of it |
| 🏆 `topCitedOpinion` / 🔢 `topCitedOpinionCitations` / 🔗 `topCitedOpinionUrl` | The most cited decision in the sample |
| 📂 `casesAssigned` | RECAP dockets assigned to the judge, counted across the whole docket index |
| 🥇 `firstCaseFiledDate` / 🕘 `latestCaseFiledDate` | The span of assigned dockets on record |
| 🔬 `sampledCases` / ⏸ `pendingSharePct` / ⏱ `medianDaysToTermination` | Size of the case sample, share still open, and the median filing-to-termination gap on the closed ones |
| ⚖️ `topSuitNature` / 📊 `topSuitNatureSharePct` | The most common nature of suit in the sample and its share |
| 🏛 `courtsServed` / 📝 `opinionCourts` / 📂 `caseCourts` | Every court on the record, plus the court IDs seen in each sample |
| 📊 `suitNatureBreakdown` | The full nature of suit distribution over the sampled cases, with counts and shares |
| 🎓 `schools` | Schools recorded on the profile |
| 🏆 `topOpinions` | The five most cited opinions: case, court, date, docket number, precedential status, citation count, reporter citation, opinion type, per curiam flag, URL |
| 📂 `recentCases` | The sampled dockets: case, court, docket number, filing and termination dates, pending flag, nature of suit, cause, jurisdiction type, bankruptcy chapter, URL |
| 🕒 `scrapedAt` / ❌ `error` | ISO timestamp of the run, and the error column (null on a good row) |

Three real records from a run of the default input, with `topOpinions` and `recentCases` trimmed to their first entry and `suitNatureBreakdown` to its first three for readability:

```json
[
  {
    "judgeId": 65,
    "name": "Robert Peter Aguilar",
    "url": "https://www.courtlistener.com/person/65/robert-peter-aguilar/",
    "status": "Former",
    "currentPosition": "Judge",
    "currentCourt": "N.D. California",
    "currentCourtId": "cand",
    "appointedBy": "Carter, Jimmy",
    "politicalAffiliation": "Democratic",
    "selectionMethod": "Appointment (President)",
    "dateFirstTookOffice": "1980-06-18",
    "dateConfirmation": "1980-06-18",
    "yearsOnBench": 16,
    "courtsServedCount": 1,
    "abaRating": "Qualified",
    "opinionsAuthored": 71,
    "firstOpinionDate": "1980-09-25",
    "latestOpinionDate": "2004-09-30",
    "opinionYearsSpan": 24,
    "opinionsPerYear": 3,
    "sampledOpinions": 20,
    "sampledOpinionCitations": 359,
    "publishedSharePct": 100,
    "topCitedOpinion": "Vance v. County of Santa Clara",
    "topCitedOpinionCitations": 181,
    "topCitedOpinionUrl": "https://www.courtlistener.com/opinion/1446939/vance-v-county-of-santa-clara/",
    "casesAssigned": 253,
    "firstCaseFiledDate": "1984-10-29",
    "latestCaseFiledDate": "1996-05-22",
    "sampledCases": 20,
    "pendingSharePct": 0,
    "medianDaysToTermination": 46,
    "topSuitNature": "442 Civil rights jobs",
    "topSuitNatureSharePct": 21.1,
    "courtsServed": [
      "N.D. California"
    ],
    "opinionCourts": [
      "cand"
    ],
    "caseCourts": [
      "cand"
    ],
    "suitNatureBreakdown": [
      {
        "suitNature": "442 Civil rights jobs",
        "cases": 4,
        "sharePct": 21.1
      },
      {
        "suitNature": "550 Prisoner - civil rights",
        "cases": 3,
        "sharePct": 15.8
      },
      {
        "suitNature": "840 Trademark",
        "cases": 3,
        "sharePct": 15.8
      }
    ],
    "schools": [],
    "topOpinions": [
      {
        "caseName": "Vance v. County of Santa Clara",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "dateFiled": "1996-06-11",
        "docketNumber": "C-92-20275 RPA",
        "precedentialStatus": "Published",
        "citationCount": 181,
        "citation": "928 F. Supp. 993",
        "opinionType": "combined-opinion",
        "perCuriam": "No",
        "url": "https://www.courtlistener.com/opinion/1446939/vance-v-county-of-santa-clara/"
      }
    ],
    "recentCases": [
      {
        "caseName": "Rutherford v. Oregon, State of",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "docketNumber": "5:96-cv-20399",
        "dateFiled": "1996-05-22",
        "dateTerminated": "1996-06-03",
        "isPending": "No",
        "suitNature": "550 Prisoner - civil rights",
        "cause": "Not Disclosed",
        "jurisdictionType": "Federal question",
        "chapter": "N/A",
        "url": "https://www.courtlistener.com/docket/10234590/rutherford-v-oregon-state-of/"
      }
    ],
    "scrapedAt": "2026-09-08T06:42:04.822Z",
    "error": null
  },
  {
    "judgeId": 89,
    "name": "William Haskell Alsup",
    "url": "https://www.courtlistener.com/person/89/william-haskell-alsup/",
    "status": "Active",
    "currentPosition": "Judge",
    "currentCourt": "N.D. California",
    "currentCourtId": "cand",
    "appointedBy": "Clinton, William Jefferson",
    "politicalAffiliation": "Democratic",
    "selectionMethod": "Appointment (President)",
    "dateFirstTookOffice": "1999-08-17",
    "dateConfirmation": "1999-07-30",
    "yearsOnBench": 27.1,
    "courtsServedCount": 1,
    "abaRating": "Well Qualified",
    "opinionsAuthored": 125,
    "firstOpinionDate": "1999-10-15",
    "latestOpinionDate": "2011-10-27",
    "opinionYearsSpan": 12,
    "opinionsPerYear": 10.4,
    "sampledOpinions": 20,
    "sampledOpinionCitations": 139,
    "publishedSharePct": 100,
    "topCitedOpinion": "Xavier v. Philip Morris USA Inc.",
    "topCitedOpinionCitations": 47,
    "topCitedOpinionUrl": "https://www.courtlistener.com/opinion/2183003/xavier-v-philip-morris-usa-inc/",
    "casesAssigned": 8029,
    "firstCaseFiledDate": "1978-06-30",
    "latestCaseFiledDate": "2025-09-09",
    "sampledCases": 20,
    "pendingSharePct": 25,
    "medianDaysToTermination": 154,
    "topSuitNature": "820 Copyright",
    "topSuitNatureSharePct": 21.4,
    "courtsServed": [
      "N.D. California"
    ],
    "opinionCourts": [
      "cand"
    ],
    "caseCourts": [
      "cand"
    ],
    "suitNatureBreakdown": [
      {
        "suitNature": "820 Copyright",
        "cases": 3,
        "sharePct": 21.4
      },
      {
        "suitNature": "442 Civil Rights: Jobs",
        "cases": 2,
        "sharePct": 14.3
      },
      {
        "suitNature": "110 Insurance",
        "cases": 1,
        "sharePct": 7.1
      }
    ],
    "schools": [
      "Mississippi State University",
      "Harvard University"
    ],
    "topOpinions": [
      {
        "caseName": "Xavier v. Philip Morris USA Inc.",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "dateFiled": "2011-04-18",
        "docketNumber": "C 10-02067 WHA",
        "precedentialStatus": "Published",
        "citationCount": 47,
        "citation": "787 F. Supp. 2d 1075",
        "opinionType": "combined-opinion",
        "perCuriam": "No",
        "url": "https://www.courtlistener.com/opinion/2183003/xavier-v-philip-morris-usa-inc/"
      }
    ],
    "recentCases": [
      {
        "caseName": "Ballentine v. Meta Platforms, Inc",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "docketNumber": "3:25-cv-07671",
        "dateFiled": "2025-09-09",
        "dateTerminated": "2001-07-03",
        "isPending": "No",
        "suitNature": "442 Civil Rights: Jobs",
        "cause": "42:1981 Civil Rights",
        "jurisdictionType": "Federal Question",
        "chapter": "N/A",
        "url": "https://www.courtlistener.com/docket/11257933/ballentine-v-meta-platforms-inc/"
      }
    ],
    "scrapedAt": "2026-09-08T06:42:13.226Z",
    "error": null
  },
  {
    "judgeId": 126,
    "name": "Saundra Brown Armstrong",
    "url": "https://www.courtlistener.com/person/126/saundra-brown-armstrong/",
    "status": "Active",
    "currentPosition": "Judge",
    "currentCourt": "N.D. California",
    "currentCourtId": "cand",
    "appointedBy": "Bush, George H.W.",
    "politicalAffiliation": "Republican",
    "selectionMethod": "Appointment (President)",
    "dateFirstTookOffice": "1991-06-18",
    "dateConfirmation": "1991-06-14",
    "yearsOnBench": 35.2,
    "courtsServedCount": 1,
    "abaRating": "Qualified",
    "opinionsAuthored": 81,
    "firstOpinionDate": "1991-11-21",
    "latestOpinionDate": "2011-09-30",
    "opinionYearsSpan": 19.9,
    "opinionsPerYear": 4.1,
    "sampledOpinions": 20,
    "sampledOpinionCitations": 139,
    "publishedSharePct": 100,
    "topCitedOpinion": "Lewis v. UBS Financial Services Inc.",
    "topCitedOpinionCitations": 19,
    "topCitedOpinionUrl": "https://www.courtlistener.com/opinion/2144060/lewis-v-ubs-financial-services-inc/",
    "casesAssigned": 8702,
    "firstCaseFiledDate": "1978-02-28",
    "latestCaseFiledDate": "2021-10-22",
    "sampledCases": 20,
    "pendingSharePct": 0,
    "medianDaysToTermination": 178,
    "topSuitNature": "446 American with Disabilities - Other",
    "topSuitNatureSharePct": 30,
    "courtsServed": [
      "N.D. California"
    ],
    "opinionCourts": [
      "cand"
    ],
    "caseCourts": [
      "cand"
    ],
    "suitNatureBreakdown": [
      {
        "suitNature": "446 American with Disabilities - Other",
        "cases": 3,
        "sharePct": 30
      },
      {
        "suitNature": "American with Disabilities - Other",
        "cases": 3,
        "sharePct": 30
      },
      {
        "suitNature": "Civil Rights: Other",
        "cases": 1,
        "sharePct": 10
      }
    ],
    "schools": [
      "Merritt College",
      "Pacific School of Religion"
    ],
    "topOpinions": [
      {
        "caseName": "Lewis v. UBS Financial Services Inc.",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "dateFiled": "2011-09-30",
        "docketNumber": "Case C 10-04867 SBA",
        "precedentialStatus": "Published",
        "citationCount": 19,
        "citation": "818 F. Supp. 2d 1161",
        "opinionType": "combined-opinion",
        "perCuriam": "No",
        "url": "https://www.courtlistener.com/opinion/2144060/lewis-v-ubs-financial-services-inc/"
      }
    ],
    "recentCases": [
      {
        "caseName": "Comet v. Lotus Management Inc.",
        "court": "District Court, N.D. California",
        "courtId": "cand",
        "docketNumber": "4:21-cv-08253",
        "dateFiled": "2021-10-22",
        "dateTerminated": "2022-01-04",
        "isPending": "No",
        "suitNature": "Not Disclosed",
        "cause": "Not Disclosed",
        "jurisdictionType": "Not Disclosed",
        "chapter": "N/A",
        "url": "https://www.courtlistener.com/docket/60670912/comet-v-lotus-management-inc/"
      }
    ],
    "scrapedAt": "2026-09-08T06:42:45.520Z",
    "error": null
  }
]
```

### ✨ Why choose this Actor

| | What you get |
| --- | --- |
| **A measured join, not a profile dump** | CourtListener's judiciary database gives you a judge's seats. This Actor adds what the judge has actually done: the opinion count from the opinion index, the docket count from RECAP, and a nature of suit breakdown counted from the records themselves. |
| **ID field queries, not name matching** | Opinions are counted with `author_id` and cases with `assigned_to_id`, both verified against the live API. Two judges with the same surname never contaminate each other's numbers, which is exactly what a name search does. |
| **Honest about the sample** | There is no aggregation endpoint on the public API, so shares and medians are counted over the records the run reads. The row states the window with `sampledOpinions` and `sampledCases`, and you can widen it to 200 records per judge. The two totals are always the true archive counts. |
| **A verified court list** | All 3,359 CourtListener courts are pickable by name, taken from the source's own courts endpoint rather than typed from memory. Several courts in one run are ORed. |
| **Career span, not just a headcount** | The first authored opinion and the first assigned case come from an ascending page of each index, so you get the real span. When the sample already covers the whole record, the extra request is skipped. |
| **No account needed** | CourtListener throttles anonymous callers at 5 requests a minute and 50 an hour per IP. The proxy is on by default so every request gets a fresh exit IP, and a free CourtListener key removes the limit outright. |
| **You pay for what you keep** | Rows are billed as they are written and capped at `maxItems`. A judge that fails to analyse is written as an error row and is never charged. |

### 📈 How it compares to alternatives

| | This Actor | Judge profile scrapers | Docket scrapers | PACER directly |
| --- | --- | --- | --- | --- |
| Opinions authored | Counted by `author_id` across the whole index | Not available | Not available | Not available |
| Cases assigned | Counted by `assigned_to_id` across RECAP | Not available | One row per case, you count them | Per court, per login |
| Nature of suit mix | Counted per judge with shares | Not available | Raw field, no aggregation | Raw field |
| Tenure, appointer, party, ABA rating | On every row | On every row | Judge name only | Not available |
| Most cited opinions | Top five with citation counts and links | Not available | Not available | Not available |
| Rows a free account can preview | 10 | Varies | Varies | None |
| Sampling honesty | Window size printed on every row | Not applicable | Not applicable | Not applicable |
| Ceiling | Anonymous API throttle of 5 requests a minute per IP, lifted by a free key or the proxy | Same source, same ceiling | Same source, same ceiling | Per-page fees |

### 🚀 How to use

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [CourtListener Judge Analytics Scraper](https://apify.com/parseforge/courtlistener-judge-analytics-scraper?fpr=vmoqkp).
3. Pick the courts you care about, narrow with party, school, appointer or a birth window, then click **Start**.
4. Export the results as CSV, Excel, JSON, or XML from the **Dataset** tab.

One typical run: `courts` `["cand"]`, `bornAfter` `01/01/1930`, `bornBefore` `01/01/1960`, `sampleSize` `20`, `maxItems` `25`. Run it programmatically through the [Apify API](https://docs.apify.com/api/v2) or the [ApifyClient](https://docs.apify.com/api/client/js) for JavaScript and Python.

### 💼 Business use cases

#### ⚖️ Read the bench before you file

Set `courts` to the district you are filing in and run the whole bench. The `topSuitNature`, `suitNatureBreakdown` and `medianDaysToTermination` columns tell you which judges see your kind of case regularly and how quickly matters close in front of them. A trial team walks into a scheduling conference already knowing the shape of the docket.

#### 📊 Build judge features for a litigation model

Every row is a feature vector with a stable `judgeId`: opinion volume, authorship rate, published share, citation weight in the sample, pending share, median time to termination, tenure and appointer. Litigation finance and legal analytics teams join it to their own case outcomes and refresh it on a schedule.

#### 🧑‍💼 Map practice areas across a district

Run a court, sort by `topSuitNature`, and you have the district's work split by judge. Firms use it to see which judges carry the patent, copyright, employment or prisoner civil rights load, and to brief laterals on where their practice actually lands.

#### 🎓 Study the bench itself

`appointedBy`, `politicalAffiliation`, `selectionMethod`, `abaRating`, `schools` and `yearsOnBench` sit on the same row as the measured output, so questions about appointment cohorts and productivity are a group-by rather than a research project.

### 🔌 Automating CourtListener Judge Analytics Scraper

- **Make / Zapier:** refresh a judge table on a schedule and push changes to a CRM or a Google Sheet.
- **Slack:** post a one-line judge brief to a case channel whenever a matter is assigned.
- **Airbyte:** land the dataset in Snowflake, BigQuery or Postgres and join it to your matter table.
- **GitHub:** commit the JSON export to a repository to keep a versioned history of the bench.
- **Google Drive:** drop the CSV or Excel export into a shared folder for the litigation team.

### 🌟 Beyond business use cases

- **Research:** compare opinion output across appointment cohorts, courts or decades.
- **Personal:** look up the judge on your own case and see what usually lands on that docket.
- **Non-profit:** track the composition and workload of a district bench over time.
- **Experimentation:** feed the judge features into a model of case duration, or build a bench brief generator on top of the JSON export.

### 🤖 Ask an AI assistant about this scraper

Give an AI agent live access to US judge analytics through the Model Context Protocol:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/courtlistener-judge-analytics-scraper"
```

Then prompt it in plain language:

- *"How many opinions has Judge William Alsup authored, and what kind of cases land on his docket?"*
- *"List the Northern District of California judges appointed by Clinton, with their caseload totals."*
- *"Which judges in this district handle the most copyright cases?"*

Copy this into ChatGPT, Claude, or Cursor to start:

```
Use the Apify Actor "parseforge/courtlistener-judge-analytics-scraper" to profile US judges. Input: { "courts": ["cand"], "name": "<judge>", "appointer": "<president>", "politicalAffiliation": "d"|"r", "school": "<school>", "sampleSize": 20-200, "maxItems": <n> }. It returns opinions authored, cases assigned, nature of suit breakdown, most cited opinions, tenure, appointer and confirmation dates per judge. Call it with the ApifyClient and my APIFY_TOKEN.
```

### ❓ Frequently Asked Questions

#### ❓ Do I need a CourtListener account?

No. The search API answers anonymous callers and the default run needs nothing. A free CourtListener key (Profile > API on courtlistener.com) lifts the anonymous throttle and makes long runs much faster, and it goes in the optional `courtListenerKey` field.

#### ❓ Where do the numbers come from?

`opinionsAuthored` is the count the opinion index returns for `author_id:<judge>`. `casesAssigned` is the count the RECAP docket index returns for `assigned_to_id:<judge>`. Both are ID field queries against the live API, so they are exact counts of what CourtListener holds, not estimates.

#### ❓ What exactly is sampled, and what is not?

The two totals above are never sampled. The shares, the median, the nature of suit breakdown, the citation sum and the most cited opinions are counted over the most recent `sampleSize` records of each index, because the public API publishes no aggregation endpoint and no facets. Every row prints its own window in `sampledOpinions` and `sampledCases`.

#### ❓ Why does a district judge show 0 opinions authored?

Because CourtListener's opinion corpus covers published decisions, and most district court work is unpublished orders that never enter it. The judge's output shows up in `casesAssigned` instead. It is real coverage, not a failure.

#### ❓ Why does an appellate judge show 0 cases assigned?

RECAP mirrors district and bankruptcy dockets, which have an assigned judge. Circuit and Supreme Court judges have no RECAP assignments, so their row is an authorship profile with a zero caseload.

#### ❓ Does it report reversals or affirmance rates?

No, and nothing that claims to from this source is measuring it. CourtListener's public API exposes no appellate treatment signal: no reversal flag, no Shepard-style history. Citation counts are in the row because they are real; a reversal rate is not, so it is not shipped.

#### ❓ How many judges are there?

15,119 judiciary profiles across 3,359 courts, including state judges. Of those, 3,717 were appointed by a president, 3,577 by a governor, 3,847 are recorded as Democratic and 3,404 as Republican.

#### ❓ How fast is it, and what is the ceiling?

Anonymous callers get 5 requests a minute and 50 an hour per IP, and each judge costs two to four requests. With the proxy on, a five judge run takes about a minute. Turn the proxy off and the Actor honours the source's `Retry-After` instead, which is correct but slow. A free API key removes the ceiling.

#### ❓ What does `sampleSize` cost me?

It is rounded to the nearest multiple of 20, the fixed page size of the API. 20 costs two requests per judge; 200 costs twenty. Widen it when you want a nature of suit distribution you can trust over a busy docket, leave it at 20 for a bench overview.

#### ❓ Why is a first case date earlier than the judge took office?

RECAP records the docket's filing date, and a case can be reassigned to a judge years after it was opened. The Actor reports the source's dates as they stand rather than clamping them to the confirmation date.

#### ❓ Can I analyse specific judges instead of a whole court?

Yes. Paste their CourtListener profile URLs into `startUrls`. The Actor reads the person ID out of each URL and resolves twenty of them per request.

#### ❓ Is this the same as the judge profile scraper?

No. The profile scraper returns the raw judiciary record with the full positions array. This Actor returns the derived analytics: what the judge wrote, what was assigned to them, and the shape of it. Run both and join on `judgeId`.

#### ❓ How fresh is the data?

As fresh as CourtListener. Opinions appear as the courts publish them, and RECAP dockets appear as users and the Free Law Project's feeds contribute them. A judge assigned a case yesterday may not show it until the docket is mirrored.

#### ❓ What happens if one judge fails?

That judge is written as an error row with the message, the run continues, and no charge is made for it. Real rows and error rows are never billed the same way.

#### ❓ How many rows per run?

Free accounts preview 10. Paid accounts go to 1,000,000, though the throttle and the two-to-four requests per judge are the practical limit; a free API key is what makes a large run comfortable.

### 🔌 Integrate with any app

The dataset is available through the Apify API and the JavaScript and Python clients, and every run can be scheduled, triggered by webhook or wired into Make, Zapier, n8n, Airbyte, Google Sheets, Slack and GitHub from the **Integrations** tab.

### 🔗 Recommended Actors

- [CourtListener Judge and Attorney Profiles Scraper](https://apify.com/parseforge/courtlistener-attorney-profiles-scraper?fpr=vmoqkp): the raw judiciary record with every seat, the input side of this Actor's join.
- [CourtListener Civil Cases Scraper](https://apify.com/parseforge/courtlistener-civil-cases-scraper?fpr=vmoqkp): the federal civil dockets counted in `casesAssigned`, one row per case.
- [CourtListener Bankruptcy Scraper](https://apify.com/parseforge/courtlistener-bankruptcy-scraper?fpr=vmoqkp): US bankruptcy petitions by chapter, court and trustee.
- [CourtListener Adversary Proceedings Scraper](https://apify.com/parseforge/courtlistener-adversary-scraper?fpr=vmoqkp): the lawsuits filed inside a bankruptcy, by nature of suit.
- [CourtListener Opinions Scraper](https://apify.com/parseforge/courtlistener-scraper?fpr=vmoqkp): the published case law counted in `opinionsAuthored`, with full text.

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge) for more court, government and public-records scrapers.

**🆘 Need Help?** [Open our contact form](https://tally.so/r/BzdKgA) with your run ID, your input, and what you expected.

> **⚠️ Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the Free Law Project or CourtListener. It collects only publicly available court data through the public API. You are responsible for using the data in compliance with CourtListener's terms and applicable laws. These records concern real people: do not use this data to identify, profile, or target individuals.

# Actor input Schema

## `startUrls` (type: `array`):

CourtListener judge pages such as https://www.courtlistener.com/person/2652/jed-saul-rakoff/. Each URL is resolved by its numeric person id, twenty per request. Leave empty to pick judges with the filters below instead.

## `maxItems` (type: `integer`):

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000. Leave empty on a paid plan for 100 judges. One item is one fully analysed judge.

## `query` (type: `string`):

Full text search across the judiciary database. Leave empty to rely on the filters below.

## `name` (type: `string`):

Match on the name field only, which is stricter than the full text search. Example: Rakoff.

## `courts` (type: `array`):

Return only judges who have held a seat at one of these courts. Several courts are combined with OR in a single search, so picking more courts widens the result set. All 3,359 CourtListener courts are listed.

## `school` (type: `string`):

Match judges who attended a school by name. Example: Yale University.

## `appointer` (type: `string`):

Match on the person who appointed the judge to at least one seat. Example: Obama.

## `politicalAffiliation` (type: `string`):

Party recorded for the judge. Democratic and Republican cover most of the database; the historical parties are small but real.

## `selectionMethod` (type: `string`):

Selection method recorded on at least one of the judge positions.

## `bornAfter` (type: `string`):

Keep judges born on or after this date, written as MM/DD/YYYY. A good proxy for the modern bench: 01/01/1950 leaves 781 profiles.

## `bornBefore` (type: `string`):

Keep judges born on or before this date, written as MM/DD/YYYY. Pairs with the field above to isolate one generation of the bench.

## `orderBy` (type: `string`):

CourtListener sorts judge results two ways only. Relevance is the default; the reverse name order walks the database alphabetically by last name.

## `sampleSize` (type: `integer`):

How many of the most recent opinions and assigned cases to read per judge. Rounded to the nearest multiple of 20, which is the fixed page size. 20 costs two requests per judge, 200 costs twenty.

## `includeCareerSpan` (type: `boolean`):

Add the first authored opinion date and the first assigned case date. Costs up to two extra requests per judge, and is skipped automatically when the sample already covers the judge whole record.

## `courtListenerKey` (type: `string`):

A free CourtListener API key (Profile > API on courtlistener.com, sign up at https://www.courtlistener.com/sign-up/) lifts the anonymous throttle and makes long runs much faster. Leave empty to run anonymously through the proxy.

## `proxyConfiguration` (type: `object`):

On by default because this Actor is request heavy per row: a fresh exit IP per request means a fresh throttle allowance. Turn it off to call CourtListener directly, which is slower but works. Not used when an API key is supplied.

## Actor input object example

```json
{
  "startUrls": [],
  "maxItems": 10,
  "courts": [
    "cand"
  ],
  "bornAfter": "01/01/1930",
  "bornBefore": "01/01/1960",
  "orderBy": "name_reverse asc",
  "sampleSize": 20,
  "includeCareerSpan": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields: judge, court, seat, appointer, tenure, opinions authored, cases assigned, nature of suit mix

## `fullData` (type: `string`):

Complete dataset with all 43 fields, including the most cited opinions and recent cases arrays

# 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 = {
    "startUrls": [],
    "maxItems": 10,
    "courts": [
        "cand"
    ],
    "bornAfter": "01/01/1930",
    "bornBefore": "01/01/1960",
    "orderBy": "name_reverse asc",
    "sampleSize": 20,
    "includeCareerSpan": true,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/courtlistener-judge-analytics-scraper").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 = {
    "startUrls": [],
    "maxItems": 10,
    "courts": ["cand"],
    "bornAfter": "01/01/1930",
    "bornBefore": "01/01/1960",
    "orderBy": "name_reverse asc",
    "sampleSize": 20,
    "includeCareerSpan": True,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/courtlistener-judge-analytics-scraper").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 '{
  "startUrls": [],
  "maxItems": 10,
  "courts": [
    "cand"
  ],
  "bornAfter": "01/01/1930",
  "bornBefore": "01/01/1960",
  "orderBy": "name_reverse asc",
  "sampleSize": 20,
  "includeCareerSpan": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parseforge/courtlistener-judge-analytics-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parseforge/courtlistener-judge-analytics-scraper"
        }
    }
}

```

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/nOAHwCRSh2VpJZRbp/builds/1MJlDsV56FFzWYQii/openapi.json
