How to Use the CourtListener API: Auth, Endpoints, Rate Limits

Short answer: to use the CourtListener API, create a free account, copy your token from your profile, then send Authorization: Token <your-token> on every request to https://www.courtlistener.com/api/rest/v4/. A new free account gets 5 requests per minute, 50 per hour, and 125 per day (Free Law Project, API overview, v4.4, June 2026). A free Free Law Project membership or a commercial agreement raises those limits.

TL;DR

  • What it is: free programmatic access to roughly eight million US federal and state court opinions, plus PACER docket data via RECAP, oral arguments, citation resolution, and judge biographies.
  • Current version: REST API v4.4, base URL https://www.courtlistener.com/api/rest/v4/. Auth is Authorization: Token <key> on every request.
  • Rate limits changed in May 2026. A plain new account now gets 5/min, 50/hr, 125/day, down from the old 5,000-per-hour default. Higher limits come with a membership (free for students and academics) or a commercial deal.
  • The endpoints you actually use: /search/, /opinions/, /clusters/, /dockets/, /citation-lookup/, /people/, /audio/.
  • What bites you on day one: the new low rate limits, search being slow on cold queries, and plain_text sometimes being empty on older opinions.
  • Two ways in: raw REST (curl or the official Python SDK) or an MCP server if you are building inside Claude, Cursor, or VS Code.
Quick check

What is the daily request cap for a new free CourtListener API account after the May 2026 change?

Part of our MCP and developer guide series.

For related MCP / API / developer coverage, see CourtListener Citation Lookup API: Resolve and Validate Citations and CourtListener MCP: US Federal & State Court Research.

CourtListener product screenshot

CourtListener is run by the Free Law Project, a non-profit that started as a Stanford CIS clinic in 2010 and has spent fifteen years scraping, OCR'ing, citation-mapping, and publishing the largest free corpus of US case law on the open web.

As of 2026 the database holds roughly eight million court opinions covering SCOTUS, all federal circuit and district courts, every state supreme and appellate court, plus a growing pool of state trial courts. PACER federal-filing data lives alongside the opinions through the RECAP archive.

There are no closed-source equivalents at this price point. Westlaw and Lexis sit on top of similar underlying data and charge accordingly.

If you are building anything that needs to ground an answer in a US court opinion (a citation-checking widget, a research agent, a brief generator, a docket monitor) the CourtListener API is the practical starting point. The other path is to scrape the courts yourself, which Free Law Project's juriscraper library has been doing for over a decade so you do not have to.

One note before the technical part: Free Law Project runs on donations and the API now sits behind their membership tiers. If your product makes money on top of their data, a paid membership both raises your rate limits and funds the corpus you depend on.

Step 1: get a token

The API is free to access with any account, but you still need a token. Go to courtlistener.com, create a free account, open your profile, then the Profile > API page, and copy the token.

It is permanent until you regenerate it. Treat it like a password. The rate limits are per-token, so a leaked token is a leaked quota.

Anonymous (no-token) requests are throttled hard and are not usable for a product. Even an authenticated free account is now capped at 5 requests per minute (more on that in Step 3), so plan to either request a membership or cache aggressively.

Step 2: auth

The token goes in the Authorization header on every request, prefixed with the literal word Token:

GET /api/rest/v4/search/ HTTP/1.1
Host: www.courtlistener.com
Authorization: Token abc123yourtokenhere

In curl:

curl -H "Authorization: Token abc123yourtokenhere" \
  "https://www.courtlistener.com/api/rest/v4/search/?q=qualified+immunity&type=o"

Two common mistakes new users make. First, they use Bearer abc123... (Bearer is the OAuth standard, but CourtListener pre-dates the move to Bearer and stuck with Token).

Second, they send the token as a query parameter (?token=...), which used to be supported but is deprecated and will eventually return 401. Always use the header.

Step 3: rate limits and what they actually mean (read this, it changed in 2026)

This is the part that trips up anyone following an older tutorial. On May 7, 2026 Free Law Project lowered the default API rate limits and folded the higher tiers into membership (Free Law Project, "Full CourtListener Data Access via API Now Included with Membership," May 7, 2026). The old default of 5,000 requests per hour is gone.

The current default for a plain authenticated account is, per the v4.4 API overview (Free Law Project, June 2026):

TierPer minutePer hourPer day
New free account (default)550125
Free Law Project membershiphigherhigherhigher
Commercial agreementnegotiatednegotiatednegotiated

Limits are a rolling window, not a calendar-day reset, so going over earns a 429 and you wait the window out. Accounts that historically made 1,000+ requests were grandfathered to their old limits, and student/academic (EDU) memberships are free, which raises the cap without a payment.

What this means in practice: 125 requests per day on a free account is tiny. A single search call returns 20 results by default and is paginated, so one broad crawl exhausts your daily quota fast. Bump page_size toward its maximum and use the next URL on the response rather than incrementing page= yourself, because the underlying ordering can shift between requests.

If you are doing anything beyond casual testing, get a membership (free for EDU, otherwise a donation tier) or a commercial agreement before you build. Do not architect around the old 5,000/hr number.

The seven endpoints that matter

Most CourtListener integrations only ever use a handful of endpoints. Here they are, ranked by how often you will hit them:

  1. /search/ is the workhorse. Boolean queries against opinions (type=o), dockets (type=r), oral arguments (type=oa), and judges (type=p). Returns lists of matching clusters or dockets with snippet highlighting.
  2. /opinions/ returns a single opinion record by ID. Use this when you have an opinion ID from a search hit and want the full text.
  3. /clusters/ is the parent record that groups opinions for a single decision (majority, concurrence, dissent). Most "cases" in normal English are clusters, not opinions.
  4. /dockets/ is the case-level record, including PACER metadata from RECAP. A docket aggregates filings, parties, judges, and any opinions associated with the case.
  5. /citation-lookup/ takes a citation string ("410 U.S. 113") and returns the matching opinion or cluster. Indispensable for citation verification.
  6. /people/ is the judge database. Useful for assignment patterns, biographical context, opinion authorship attribution.
  7. /audio/ is the oral-argument archive. Useful if you are doing anything with appellate-argument transcripts.

There are more endpoints (recap, financial-disclosures, fjc-integrated-database) but the seven above cover 95% of production usage.

EndpointPurposeTypical use
/search/Boolean and semantic searchLists of matches across opinions, dockets, oral args, judges
/opinions/One opinion by IDPull full text after a search hit
/clusters/Decision-level recordGroup majority / concurrence / dissent for one case
/dockets/Case-level recordPACER metadata, filings, parties
/citation-lookup/Resolve a citation stringVerify a cite, catch hallucinations
/people/Judge databaseAuthorship, assignment patterns, bios
/audio/Oral-argument archiveAppellate-argument transcripts and audio

Worked example 1: search SCOTUS opinions and fetch the full text of one

You want every Supreme Court opinion from 2024 that mentions "qualified immunity," then the full text of the first one.

# 1. Search opinions, filter to SCOTUS (court=scotus) and 2024
curl -H "Authorization: Token YOUR_TOKEN" \
  "https://www.courtlistener.com/api/rest/v4/search/?q=qualified+immunity&type=o&court=scotus&filed_after=2024-01-01&filed_before=2024-12-31&page_size=20"

The response is JSON with a results array. Each result has id, cluster_id, caseName, dateFiled, snippet, plus a few attribution fields. Pull the first hit's id.

# 2. Fetch the full opinion text
curl -H "Authorization: Token YOUR_TOKEN" \
  "https://www.courtlistener.com/api/rest/v4/opinions/{id}/"

The opinion response includes plain_text, html, html_with_citations, and a cluster URL pointing to the parent record. plain_text is what you want for LLM ingestion. html_with_citations is what you want if you are rendering the opinion in a UI with hyperlinked citations.

The gotcha: plain_text is sometimes empty. Older opinions are stored as html or xml_harvard only. Real production code checks all three fields in priority order: plain_text, then html with HTML stripped, then xml_harvard.

Worked example 2: the same search in Python (raw requests and the official SDK)

For curl-free work you have two clean options. The first is the requests library against the raw API, which keeps you close to the JSON:

import requests

BASE = "https://www.courtlistener.com/api/rest/v4"
headers = {"Authorization": "Token YOUR_TOKEN"}

# 1. Search SCOTUS opinions mentioning qualified immunity, filed in 2024
params = {
    "q": "qualified immunity",
    "type": "o",
    "court": "scotus",
    "filed_after": "2024-01-01",
    "filed_before": "2024-12-31",
}
search = requests.get(f"{BASE}/search/", headers=headers, params=params).json()
first = search["results"][0]

# 2. Pull the full text of the first hit, falling back across text fields
op = requests.get(f"{BASE}/opinions/{first['id']}/", headers=headers).json()
text = op.get("plain_text") or op.get("html") or op.get("xml_harvard") or ""
print(first["caseName"], "-", len(text), "chars")

The second is the official Python SDK, courtlistener-api-client, maintained by Free Law Project (Free Law Project, GitHub / PyPI, June 2026). It reads your token from COURTLISTENER_API_TOKEN and handles pagination for you:

from courtlistener import CourtListener

client = CourtListener()  # reads COURTLISTENER_API_TOKEN, or pass api_token="..."

# List queries return a ResourceIterator that paginates automatically
results = client.opinions.list(cluster__case_name="Miranda")
for opinion in results:          # iterates across all pages
    print(opinion)

# Fetch one opinion by ID
opinion = client.opinions.get(1)

The SDK is the faster path if you are doing ordinary list-and-fetch work. Drop to raw requests when you need a field or filter the SDK does not surface yet.

How to use the CourtListener API for citation verification

This is the endpoint you actually want when you are building a citation-verification feature, and the one most developers do not discover until they have already built a regex-based parser they regret. It is a POST endpoint (not GET). You send a block of text and it parses and validates every citation in it (Free Law Project, Citation Lookup and Verification API, v4.4, June 2026):

curl -X POST \
  -H "Authorization: Token YOUR_TOKEN" \
  --data 'text=Brown v. Board of Education, 347 U.S. 483 (1954)' \
  "https://www.courtlistener.com/api/rest/v4/citation-lookup/"

The response is an array, one object per citation found, each with a status, the normalized_citations (typo-corrected forms), start_index/end_index positions, and a clusters array of matching cases. The status is the field you branch on:

statusMeaning
200Found and matched in the database
404Looks like a valid citation but not in CourtListener
400Parsed as a citation but the reporter is invalid
300Ambiguous, multiple cases match
429You hit the rate limit

If your LLM generated the citation and CourtListener returns 404, you almost certainly have a hallucination on your hands.

You can also look up a single citation by passing volume, reporter, and page instead of text. Two throttle facts to design around: the endpoint matches at most 250 citations per request (extra citations are parsed but not matched) and 60 valid citations per minute. To bulk-check a long brief, chunk it.

Things nobody documents

A few production-grade gotchas that took us months to learn the hard way.

Pin to v4 and read the real response shape. The current version is v4.4 and the v3 endpoints are frozen legacy. v4 stabilized several response field names (consistent absolute_url, caseName capitalization, reliably present cluster_id on opinion responses). The change log moves quickly: v4.5 already removed text filter lookups like contains and icontains, so read the actual JSON rather than trusting an older field guarantee.

/search/ is slow on cold queries. First time a query hits the index, expect 2 to 8 seconds. Cached queries are sub-second. Build retries with exponential backoff for the cold-cache case. If you are showing search to end users, debounce input aggressively.

RECAP downloads cost real money. PACER charges per-page for federal filings. CourtListener buffers what it can through the RECAP archive (filings other users have already pulled), but if you trigger a fresh PACER pull through their API, you are spending real PACER credits.

Always check whether a docket entry is already in RECAP before fetching.

Pagination order is not stable across long crawls. If you are paginating through hundreds of pages of search results and new data lands while you crawl, page 47 today is not page 47 tomorrow.

Use the next URL field on the response rather than incrementing page=, and consider using a date filter to lock the result set.

Citation lookup does not catch every malformed cite. It is good at recognized reporters (U.S., F.3d, S.Ct., F.Supp.2d, plus most state reporters). It is less good at parallel cites, statutory cites, and informal cite formats.

For belt-and-suspenders verification, run candidates through both /citation-lookup/ and a downstream check against the actual opinion text.

Semantic search, the November 2025 addition

CourtListener added semantic search to its /search/ API on November 5, 2025 (Free Law Project, "Semantic Search API Now Live!," Nov 5, 2025), and rolled it out to the website in May 2026 (Free Law Project, "Semantic Search Is Now on CourtListener," May 4, 2026). It changes the kind of queries you should send.

Keyword search does Boolean matching plus relevance ranking. Semantic search embeds opinions with a retrieval-tuned encoder model, so a natural-language query returns conceptually similar opinions even when no keyword overlaps. Check the current Search API docs for the exact parameter, since the flag has shifted across releases.

If you are building an LLM-driven research agent, semantic search is usually what you want. If you are building a Boolean precision tool for litigators, keep keyword search. Most apps want both available and switchable.

When you should not call the API directly

Three cases where the raw API is the wrong layer:

  1. You are building inside Claude, Cursor, ChatGPT Desktop, VS Code, or Windsurf. These clients speak the Model Context Protocol. An open-source CourtListener MCP server exists that exposes 28+ tools wrapping the API in MCP-native form, with bring-your-own-token so the server never stores keys.

    The MCP path saves you a week of integration work and gives users the same surface across every MCP-compatible client.

  2. You need answers, not documents. The CourtListener API returns opinions. If you need a synthesized, citation-grounded answer to a legal question, you also need an LLM layer plus verification on top of the raw retrieval.

    That is a research product, not an API call, and the realistic options are licensing one or building it.

Vaquill AI US statutes and Code coverage across federal and 50-state law

  1. You need US statutes plus case law in one call. CourtListener's strength is case law, dockets, and judges. It is not a statutes API: no US Code, no 50-state statutes, no Federal Rules of Procedure. If your product needs all of US primary law in one query, you are stitching multiple APIs together or layering a statutes API alongside CourtListener.

What to do next

  1. Create a free account at courtlistener.com and copy your token from Profile > API.
  2. Hit /api/rest/v4/search/?q=test&type=o with your token to confirm it works.
  3. Pick your layer. For ordinary list-and-fetch in Python, install the official courtlistener-api-client SDK. For raw control, use curl or requests. If you are building inside Claude, Cursor, or VS Code, use a CourtListener MCP server instead.
  4. Get a membership before you ship anything past testing. The free 125-requests-per-day cap will not carry a product, and a membership funds the corpus you depend on.

For more depth on the related pieces, see CourtListener Citation Lookup API: Resolve and Validate Citations, how to verify AI legal citations before filing, and composing CourtListener, CanLII, and Vaquill AI into one workflow.

CourtListener handles case law. For the other half of US primary law, Vaquill AI's statutes API covers US Code, the CFR, and all 50 state codes in one call, so you can run it alongside CourtListener without stitching together a dozen state sources yourself. (Vaquill AI's public API is statutes-only; for case law it uses CourtListener, same as you.)

FAQ

Is the CourtListener API free? Yes, the API is free to use with any CourtListener account. As of May 2026 the higher rate limits moved behind membership tiers, but a free account still gets real access at 5 requests per minute, 50 per hour, and 125 per day. Student and academic (EDU) memberships are free and raise those limits.

What are the current CourtListener API rate limits? A new free authenticated account gets 5 requests per minute, 50 per hour, and 125 per day on a rolling window (Free Law Project, June 2026). The old 5,000-per-hour default was removed on May 7, 2026. Accounts with 1,000+ historical requests were grandfathered, and memberships or commercial agreements raise the cap.

How do I authenticate with the CourtListener API? Put your token in the Authorization header on every request, prefixed with the literal word Token: Authorization: Token your-key-here. Do not use Bearer, and do not pass the token as a query parameter. The base URL is https://www.courtlistener.com/api/rest/v4/.

What is the latest version of the CourtListener API? v4.4 is the current REST API version as of June 2026, at https://www.courtlistener.com/api/rest/v4/. The v3 endpoints still respond but are frozen. The change log moves fast, so read the live JSON rather than relying on older field guarantees.

Is there an official CourtListener Python library? Yes. Free Law Project maintains courtlistener-api-client, installable with pip install courtlistener-api-client. It reads your token from COURTLISTENER_API_TOKEN and handles pagination through a ResourceIterator. Drop to raw requests when you need a field or filter the SDK does not expose.

How do I check a citation with the CourtListener API? POST a block of text to /api/rest/v4/citation-lookup/ with your token. It returns one object per citation, each with a status (200 found, 404 valid but not in the database, 400 invalid reporter, 300 ambiguous). It matches up to 250 citations per request and 60 valid citations per minute.

Does the CourtListener API include statutes? No. CourtListener covers case law, dockets, oral arguments, and judges, not the US Code, state statutes, or court rules. For statutes you need a separate source such as a dedicated statutes API running alongside CourtListener.

What is the difference between an opinion and a cluster? A cluster is the decision-level record that groups the opinions for a single case (majority, concurrence, dissent). An opinion is one of those documents. Most "cases" in plain English map to clusters, so reach for /clusters/ when you want the case and /opinions/ when you want a specific document's full text.

Legal AI that reads your documents and knows the law.
Ask a legal question, review a contract, or search thousands of your files. Every answer shows where it came from. 7-day free trial, no card.
18 min read

New legal AI guides, weekly.

Priyansh Khodiyar

Priyansh Khodiyar

Co-Founder & CTO

Priyansh leads engineering and AI at Vaquill, from the matter workbench to drafting, document comparison, document matrix, and citation-verified research.