# Court Records Scraper | CourtListener Dockets & Opinions (`s-r/courtlistener-scraper`) Actor

Search US court records on CourtListener: federal dockets, case law opinions and RECAP documents. Filter by court, date, party or docket number and get case details, citations, PDF links and optional party roles with attorney contacts.

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

## Pricing

from $3.00 / 1,000 court cases

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

## Court Records Scraper for CourtListener

Search US court records from CourtListener and export federal dockets, case law opinions and RECAP court documents as clean rows. Built for legal tech teams, due diligence and KYC analysts, litigation researchers and paralegals who need a court docket lookup by party, court, docket number or filing date, with optional party roles and attorney contacts, without writing code against an API.

### What this court records scraper does

CourtListener is a public legal research service run by the non-profit Free Law Project. It holds millions of US court opinions and the RECAP archive of federal court filings that people have retrieved from PACER. This Actor turns a CourtListener search into a dataset you can download as JSON, CSV or Excel, or pull through the Apify API.

You choose what to search:

- **Dockets**: federal case files with case name, docket number, court, assigned judge, filing and termination dates, cause, nature of suit, parties and attorneys.
- **Opinions**: case law from federal and state courts with citations, citation count, argued date and publication status.
- **RECAP documents**: individual filings and attachments with document number, description, page count and a PDF link when one is available.

Optional details add each party's role (Plaintiff, Defendant, Debtor and so on) and the attorneys who represent it, with firm, address, phone and fax as listed on the public record.

#### Which court records are covered

The Actor searches what CourtListener has indexed. Federal RECAP dockets depend on documents contributed to RECAP and can be incomplete or older than the latest PACER activity. State case law is included where CourtListener has it, but this is not a search of every state or county trial court. Unavailable values stay empty; the Actor never infers case outcomes, party identities or legal conclusions.

### Input

Provide at least one of `query`, `party_name`, `case_name`, `docket_number` or `court`. Every other field narrows the search.

| Field | Type | Default | What it does |
|---|---|---|---|
| `query` | string | | Keyword query with CourtListener syntax: quoted phrases, AND/OR, `field:value` |
| `search_type` | string | `dockets` | `dockets`, `opinions` or `recap_documents` |
| `court` | list of strings | | CourtListener court IDs, for example `["txed"]` or `["txed", "cand"]`; API callers may send one ID as a string |
| `filed_after` / `filed_before` | date | | Inclusive filing date range, YYYY-MM-DD: document date for RECAP documents, case date for dockets, opinion date for opinions |
| `party_name` | string | | Party name filter (dockets and RECAP documents) |
| `case_name` | string | | Case name filter |
| `docket_number` | string | | Docket number; combine with `court`, because the same number exists in several courts |
| `nature_of_suit` | string | | Nature of suit code or text, for example `830` for patent (dockets and RECAP documents) |
| `judge` | string | | Judge filter (opinions) |
| `opinion_status` | string | source default: Published | `Published`, `Unpublished`, `Errata`, `Separate`, `In-chambers`, `Relating-to`, `Unknown` |
| `available_only` | boolean | `false` | RECAP documents: only filings available in RECAP |
| `sort` | string | `relevance` | `relevance`, `date_desc` (newest filing first) or `date_asc`, using the same date as the filing range |
| `max_items` | integer | `50` | Maximum primary results, up to 1,000; optional document rows come on top |
| `include_details` | boolean | `false` | Dockets: party roles and associated attorney contacts |
| `include_documents` | boolean | `false` | Append nested filing matches (dockets) or opinion documents (opinions) after each case |
| `cursor` | string | | `next_cursor` from an earlier run with identical input, to continue a large search |

`include_documents` returns links and metadata; it does not download PDF files. Example input, the newest patent cases in the Western District of Texas:

```json
{"query":"patent","court":["txwd"],"nature_of_suit":"830","filed_after":"2026-01-01","sort":"date_desc","max_items":2}
```

### Output

The dataset has two row types, marked in `record_type` (and `_type`): `court_case` and `court_document`. Every row carries `row_id`, `source` and a UTC `fetched_at` timestamp for the request that retrieved it; continued pages receive a fresh timestamp. `row_id` is stable and unique across dockets, opinion clusters, RECAP documents and opinion documents, so you can deduplicate continued searches safely. Document rows follow their case when you request documents.

This is a real row returned for the example input above, captured from CourtListener on 2026-10-05:

```json
{
  "record_type": "court_case",
  "row_id": "case:docket:74910277",
  "kind": "docket",
  "case_id": "74910277",
  "case_name": "Flash Uplink LLC v. Rapid7, Inc.",
  "docket_number": "7:26-cv-00401",
  "court": "District Court, W.D. Texas",
  "court_id": "txwd",
  "judge": "Walter David Counts III",
  "filing_date": "2026-10-02",
  "termination_date": null,
  "cause": "35:271 Patent Infringement",
  "nature_of_suit": "830 Patent",
  "jurisdiction_type": "Federal Question",
  "jury_demand": "Plaintiff",
  "parties": [
    {"name": "Flash Uplink LLC", "role": null, "attorneys": []},
    {"name": "Rapid7, Inc.", "role": null, "attorneys": []}
  ],
  "attorneys": ["Bryan N. Dematteo"],
  "firms": ["DeMatteo Law LLC"],
  "citations": [],
  "details_fetched": false,
  "url": "https://www.courtlistener.com/docket/74910277/flash-uplink-llc-v-rapid7-inc/"
}
```

**Case rows** contain `case_name`, `case_name_full`, `case_id`, `docket_id`, `cluster_id`, `docket_number`, `court`, `court_id`, `court_citation`, `judge`, `panel`, `filing_date`, `termination_date`, `argued_date`, `cause`, `nature_of_suit`, `referred_to`, `jurisdiction_type`, `jury_demand`, `chapter`, `trustee`, `pacer_case_id`, `parties`, `attorneys`, `firms`, `citations`, `opinion_status`, `cite_count`, `more_documents`, `details_fetched` and `url`. An opinion row, for example Cqv Co., Ltd. v. Merck Patent Gmbh in the Federal Circuit, carries the citation `130 F.4th 1344`, its argued date and status `Published`.

Party names come with every docket; their `role` stays null until details are retrieved. With `include_details`, `details_fetched` becomes true and each party lists its attorneys with `name`, `firm`, `address`, `phone`, `fax` and `designations` (for example ATTORNEY TO BE NOTICED) where the public record shows them. Email addresses are not promised. Opinion rows keep `attorneys` empty because the source provides unstructured text with firms and roles. That original text is preserved as `attorney_text` (string or null); docket rows have `attorney_text: null`.

**Document rows** contain `document_id`, `case_id`, `docket_id`, `case_name`, `docket_number`, `court_id`, `document_type`, `document_number`, `description`, `long_description`, `filing_date`, `page_count`, `pdf_url`, `url`, `docket_entry_id`, `entry_number`, `attachment_number`, `is_available`, `pacer_doc_id`, `snippet`, `per_curiam` and `source_download_url`. A snippet is an excerpt, not the full text.

The run output (key-value store record `OUTPUT`) holds row counts, `next_cursor` and warnings. A failed detail lookup keeps the case row and names the docket in a warning. An unusable source record is skipped with a warning and does not count towards `max_items` or charges; other cases and documents are retained. Missing values are null and missing lists are empty arrays, so absence is never confused with an invented value.

### Use cases

- **Due diligence and KYC**: check whether a company or person appears as a party in federal litigation or bankruptcy before a deal, loan or onboarding.
- **Litigation monitoring**: schedule a daily run with `sort: date_desc` on a court and nature of suit (for example patent cases in E.D. Texas) and get new filings as rows.
- **Legal tech and AI**: feed case law, citations and docket metadata into search, RAG or analytics products through the Apify API.
- **Paralegal research**: export a docket lookup by docket number and court, with document descriptions and PDF links, into a spreadsheet.
- **Business development for law firms**: find recent cases by nature of suit and see which firms and attorneys appear on them.

### How it compares

| Option | What you get | Trade-off |
|---|---|---|
| PACER | The official federal record, newest filings | Paid per page, one court at a time, no bulk export |
| CourtListener website | Free search of the same collections | Manual, page by page |
| CourtListener API directly | Full flexibility | You write and maintain the client: authentication for some endpoints, paging, rate limits, party page parsing |
| Other court records actors | Often one collection (only opinions or only dockets) | Fewer filters, no party roles or attorney contacts, or a higher price per row |
| **This Actor** | Dockets, opinions and RECAP documents in one schema, party roles and attorney contacts, cursor continuation | Coverage is CourtListener's; it does not buy unavailable PACER documents |

### Pricing

You pay per delivered row, at the rates shown in the Actor's Pricing tab:

- `court_case`: each delivered case row (docket or opinion cluster).
- `court_document`: each delivered document row, so `include_documents` adds document charges.
- `case_details`: each delivered case whose public party details were retrieved successfully. A failed detail lookup is not charged.

There is no start fee, and a search that returns no rows costs nothing. Free users receive at most ten dataset rows per run, document rows included, and are charged only for the rows actually delivered. Paying users collect up to `max_items` primary results plus any selected document rows, within their run spending limit.

### FAQ

#### Does this search every US court?

It searches CourtListener's collections: federal RECAP case files and indexed federal and state case law. Local and county court coverage varies. For a complete case file, compare with the court itself or PACER.

#### Can I get every document from a docket?

`include_documents` adds up to three matching filings per docket, not the full docket. Use `search_type: recap_documents` with `query: "docket_id:45814286"` to search all filings of one case. A PDF link is returned only when the source has one; the Actor does not purchase PACER documents.

#### Are full opinion texts included?

No. Opinion metadata, citations, snippets and available PDF links are included. Download the linked PDF if you need the full text.

#### Why are party roles or attorneys missing?

Roles and attorneys come from the public parties page, which you request with `include_details` (dockets only). Some cases list no parties or representation, and a lookup can fail. Check `details_fetched` and the run warnings; the case row stays, and you are not charged for details that were not delivered.

#### How do I continue a large search?

The Actor follows continuation pages automatically up to `max_items`. In API integrations you can pass `next_cursor` from the run output as `cursor` with the same input. Stop when `next_cursor` is null.

#### Do I need a CourtListener account or API token?

No. You only need an Apify account; the Actor handles the requests and returns the rows.

### Source

[Free Law Project's search API documentation](https://wiki.free.law/c/courtlistener/help/api/rest/v4/search) describes the collections, publication statuses and query syntax. Keep the CourtListener `url` with exported data so each case or document can be checked against its source.

# Actor input Schema

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

CourtListener keyword query; quotes, AND/OR and field:value operators are supported.

## `search_type` (type: `string`):

Choose case law opinions, RECAP dockets or individual RECAP documents.

## `court` (type: `array`):

List of lowercase CourtListener court IDs, for example \["txed"] or \["txed", "cand"].

## `filed_after` (type: `string`):

Earliest filing date, inclusive, YYYY-MM-DD. Uses the document filing date for recap_documents, the case filing date for dockets and the opinion date for opinions.

## `filed_before` (type: `string`):

Latest filing date, inclusive, YYYY-MM-DD. Uses the document filing date for recap_documents, the case filing date for dockets and the opinion date for opinions.

## `party_name` (type: `string`):

Party name filter for dockets and RECAP documents.

## `case_name` (type: `string`):

Case name filter.

## `docket_number` (type: `string`):

Court docket number; combine with court because numbers are not globally unique.

## `nature_of_suit` (type: `string`):

Nature of suit code or text for dockets and RECAP documents, for example 830.

## `judge` (type: `string`):

Judge filter for opinions only.

## `opinion_status` (type: `string`):

Opinion publication status; omitted means the source default of published opinions.

## `available_only` (type: `boolean`):

For recap_documents, return only documents available in RECAP.

## `sort` (type: `string`):

Result ordering. Date ordering uses the document filing date for recap_documents, the case filing date for dockets and the opinion date for opinions.

## `max_items` (type: `integer`):

Maximum primary results across all cursor calls. Optional child documents are additional dataset rows.

## `include_details` (type: `boolean`):

For dockets, fetch public party roles and associated attorney phone, fax, firm and address.

## `include_documents` (type: `boolean`):

For dockets or opinions, append available nested document search matches after their case. No PDF downloads.

## `cursor` (type: `string`):

Opaque next_cursor from a previous response with identical input; source search cursors are also accepted.

## Actor input object example

```json
{
  "query": "patent",
  "search_type": "dockets",
  "court": [
    "txwd"
  ],
  "filed_after": "2026-01-01",
  "nature_of_suit": "830",
  "available_only": false,
  "sort": "relevance",
  "max_items": 50,
  "include_details": false,
  "include_documents": false
}
```

# Actor output Schema

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

Delivered records in the default dataset.

## `output` (type: `string`):

Delivered-row counts, status and warnings.

# 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 = {
    "query": "patent",
    "court": [
        "txwd"
    ],
    "filed_after": "2026-01-01",
    "nature_of_suit": "830"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/courtlistener-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 = {
    "query": "patent",
    "court": ["txwd"],
    "filed_after": "2026-01-01",
    "nature_of_suit": "830",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/courtlistener-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 '{
  "query": "patent",
  "court": [
    "txwd"
  ],
  "filed_after": "2026-01-01",
  "nature_of_suit": "830"
}' |
apify call s-r/courtlistener-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/courtlistener-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/bGJ3RXpRBvdoA9vtE/builds/hk7dz5tg1IeKWad50/openapi.json
