CourtListener Case Law Scraper
Pricing
from $3.34 / 1,000 results
CourtListener Case Law Scraper
Search US court opinions, RECAP dockets and oral arguments from CourtListener: case name, court, docket number, judges, citations, filing dates and opinion snippets. Free public API.
Pricing
from $3.34 / 1,000 results
Rating
0.0
(0)
Developer
Farhan Febrian Nauval
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
CourtListener Case Law Scraper — US Opinions, Dockets & Oral Arguments
Search CourtListener's corpus of US case law: case name, court, docket number, judges, citations and cite counts, filing dates, and the opening text of each opinion. Also covers RECAP dockets, oral arguments and judges.
Please use a free API token
CourtListener is run by the Free Law Project, a non-profit, and its API is
rate-limited on purpose. Measured: 5 requests a minute anonymously, then a 429 with an honest
Retry-After. That is about 100 results a minute at best.
A token is free from courtlistener.com and lifts the limit substantially. Without one this actor deliberately paces itself to one request every 13 seconds and says so in the log. It is not trying to be slow; it is trying not to hammer a charity's servers, and no proxy setting changes that — the limit is a published rate limit, not an anti-bot measure.
Input
| Field | Type | Default | Description |
|---|---|---|---|
searchQueries | array | required | Same syntax as CourtListener's own search box |
searchType | string | opinions | opinions, recap, oral-arguments, people |
courts | array | — | Court IDs, e.g. scotus, ca9, dcd |
filedAfter / filedBefore | string | — | YYYY-MM-DD |
maxItemsPerQuery | integer | 100 | 20 results per request |
apiToken | string (secret) | — | Free from courtlistener.com — see above |
Output
{"_input": "copyright fair use","_source": "S1-courtlistener-api","_scrapedAt": "2026-09-09T13:22:07Z","clusterId": 9231237, "docketId": 65678901,"url": "https://www.courtlistener.com/opinion/9231237/fort-bend-cnty-v-davis/","caseName": "Fort Bend Cnty. v. Davis","caseNameFull": "Fort Bend County, Texas v. Lois M. Davis","docketNumber": "No. 18-525","status": "Published","court": "Supreme Court of the United States","courtId": "scotus","courtCitationString": "SCOTUS","dateFiled": "2019-06-03", "dateArgued": "2019-04-22","judge": "Ginsburg","attorney": "Benjamin J. Horwich, San Francisco, CA, argued the cause for…","citations": ["587 U.S. 541", "139 S. Ct. 1843"],"citeCount": 398,"lexisCite": "…", "scdbId": "…","opinionCount": 1,"opinions": [{"opinionId": 9231238, "type": "combined-opinion","authorId": 8589, "perCuriam": false,"downloadUrl": "…", "localPath": "pdf/…", "citesCount": 41,"snippet": "Justice GINSBURG delivered the opinion of the Court…"}],"snippet": "Justice GINSBURG delivered the opinion of the Court…","searchType": "opinions"}
Two things worth knowing
Cursor pages overlap slightly. Paging by the next cursor, page 2 repeated one of page 1's
twenty results in testing. The actor tracks cluster IDs and emits each case once, so a run of N
requests can return slightly fewer than 20 × N rows — that is correct, not a shortfall.
Several fields are real but sparse. posture, proceduralHistory, syllabus, panelNames,
panelIds, neutralCite, dateReargued and dateReargumentDenied are genuine CourtListener
fields that are empty for most cases; suitNature and courtJurisdiction populate for a minority
(4 and 1 of 20 in a mixed-court sample, and none at all in a Supreme Court sample). They are shipped
rather than hidden, because when they are present they matter — but an empty value here means the
corpus has none, not that the scrape failed.
Full opinion text is not fetched. Each opinion carries a snippet — the opening of the text —
plus downloadUrl and localPath pointing at the source document. Retrieving complete opinions
would mean one request per case against the same rate limit, so it is deliberately out of scope.
Errors
_error | Meaning |
|---|---|
invalid_input | Empty search query |
no_results | The search ran and matched nothing |
unexpected_shape | A 200 without a results list |
blocked | Every TLS profile was refused |
network_error | The ladder never reached the server |
A rejected API token fails the whole run immediately rather than repeating the mistake for every remaining query — nothing downstream can succeed with bad credentials.