Query Refinement
The CourtListener APIs support advanced query refinement.
This page discusses how to filter, sort, count, paginate, and refine API responses.
Note
This page does not apply to the Search API, which uses its own filtering and sorting techniques.
Filtering
To see how an endpoint can be filtered, do an OPTIONS request on the API and inspect the filters key in the response. The filters key explains the fields that can be used for filtering along with their types, lookup fields, and any values (aka choices) that can be used for specific lookups.
For example, this uses jq to look at the filters on the docket API:
curl -X OPTIONS \
--header 'Authorization: Token <your-token-here>' \
"https://www.courtlistener.com/api/rest/v4/dockets/" | jq '.filters'
That returns something like:
{
"id": {
"type": "NumberRangeFilter",
"lookup_types": [
"exact",
"gte",
"gt",
"lte",
"lt",
"range"
]
},
...
This means that you can filter dockets using the ID field, and that you can do exact, greater than or equal, greater than, less than or equal, less than, or range filtering.
You can use these filters with a double underscore. For example, this gets IDs greater than 500 and less than 1,000:
curl \
--header 'Authorization: Token <your-token-here>' \
"https://www.courtlistener.com/api/rest/v4/dockets/?id__gt=500&id__lt=1000" | jq '.count'
499
It also allows ranges (inclusive):
curl \
--header 'Authorization: Token <your-token-here>' \
"https://www.courtlistener.com/api/rest/v4/dockets/?id__range=500,1000" | jq '.count'
501
Filters can be combined using multiple GET parameters.
Related Filters
There are a few special types of filters. The first are Related Filters, which allow you to join filters across APIs. For example, when you are using the docket API, you'll see that it has a filter for the court API:
"court": {
"type": "RelatedFilter",
"lookup_types": "See available filters for 'Courts'"
}
This means that you can use any of the court filters on the docket API. If you do an OPTIONS request on the court API, you'll see its filters:
curl -X OPTIONS \
--header 'Authorization: Token <your-token-here>' \
"https://www.courtlistener.com/api/rest/v4/courts/" | jq '.filters'
Again, one of the filters is the ID field, but it only allows exact values on this API:
"id": {
"type": "CharFilter",
"lookup_types": [
"exact"
]
}
This is where it gets powerful. You can now filter across API endpoints. For example, this uses the exact lookup from the Court API to look up dockets where the court is SCOTUS and the ID is between 500 and 1,000:
curl \
--header 'Authorization: Token <your-token-here>' \
"https://www.courtlistener.com/api/rest/v4/dockets/?court=scotus&id__range=500,1000" | jq '.count'
36
This opens up many possibilities. For example, another filter on the Court endpoint is for the name of the court. To use it, you could set a GET parameter like court__name=foo. In this case, the double underscore allows you to join the filter from the other court API to the docket API.
Finally, the Court.name filter allows you to search for courts by name. This means you can find dockets that are in courts that start with foo by doing: court__full_name__startswith=foo.
RelatedFilters can span many objects. For example, if you want to get all the Supreme Court Opinion objects, you will need to do that with a query such as:
curl "https://www.courtlistener.com/api/rest/v4/opinions/?cluster__docket__court=scotus"
This uses the Opinion API to get Opinions that are part of Opinion Clusters that are on Dockets in the Court with the ID of scotus.
To understand this data model better, see the [case law][case-law-api] and [data model][dm] documentation.
Date Filtering
To use date filters, supply dates in ISO-8601 format.
Filter Exclusion
Any filter can be converted into an exclusion filter by prepending it with an exclamation mark. For example, this returns Dockets where the jurisdiction is not F (Federal Appellate):
curl "https://www.courtlistener.com/api/rest/v4/dockets/?court__jurisdiction!=F"
More Examples
You can see more examples of filters in our automated tests.
Ordering
With the exception of the search API, you can see which fields can be used for ordering by looking at the ordering key in an OPTIONS request. For example, the Position endpoint contains this:
"ordering": [
"id",
"date_created",
"date_modified",
"date_nominated",
"date_elected",
"date_recess_appointment",
"date_referred_to_judicial_committee",
"date_judicial_committee_action",
"date_hearing",
"date_confirmation",
"date_start",
"date_retirement",
"date_termination"
]
This means that you can order using any of these fields in conjunction with the order_by parameter.
Descending order can be done using a minus sign.
Tie-breaker fields can be requested using a comma-separated list. For example, this returns judicial Positions from the Judge API ordered by the most recently modified, then by the most recently elected:
curl "https://www.courtlistener.com/api/rest/v4/positions/?order_by=-date_modified,-date_elected"
Ordering by fields with duplicate values is non-deterministic. If you wish to order by such a field, you should provide a second field as a tie-breaker to consistently order results. For example, ordering by date_filed will not return consistent ordering for items that have the same date, but this can be fixed by ordering by date_filed,id. In that case, if two items have the same date_filed value, the tie will be broken by the id field.
Counting
To retrieve the total number of items matching your query without fetching all the data, you can use the count=on parameter. This can be useful for verifying filters and understanding the scope of your query results without incurring the overhead of retrieving full datasets.
For example, this uses the Citations API to count how many decisions cite opinion 2812209:
curl "https://www.courtlistener.com/api/rest/v4/opinions-cited/?citing_opinion=2812209&count=on"
{"count": 147}
When count=on is specified:
- The API returns only the
countkey with the total number of matching items. - Pagination parameters like
cursorare ignored. - The response does not include any result data, which improves performance for large datasets.
In standard paginated responses, a count key is included with the URL to obtain the total count for your query:
curl "https://www.courtlistener.com/api/rest/v4/opinions-cited/?citing_opinion=2812209"
{
"count": "https://www.courtlistener.com/api/rest/v4/opinions-cited/?citing_opinion=2812209&count=on",
"next": "https://www.courtlistener.com/api/rest/v4/opinions-cited/?citing_opinion=2812209&cursor=cD0yOTA3NTI3ODg%3D",
"previous": null,
"results": [
// paginated results
]
}
Use this URL to get the total count of items matching your query.
Field Selection
To save bandwidth, increase serialization performance, and optimize our backend queries, use the fields parameter. This allows you to select the fields you want. Use the omit parameter to remove fields from your response. Each parameter accepts a comma-separated list of fields. Use double-underscore __ notation to choose or omit nested fields.
This is an important optimization, particularly for resources with large fields.
For example, to only receive the educations and date_modified fields from the Judge API you could do:
curl "https://www.courtlistener.com/api/rest/v4/people/?fields=educations,date_modified"
{
"educations": [
...nested values here...
],
"date_modified": "2023-03-31T07:15:28.409594-07:00"
},
...
Or, to include only the date_modified and id fields within each education entry (note the use of the double-underscore):
curl "https://www.courtlistener.com/api/rest/v4/people/?fields=educations__date_modified,educations__id"
{
"educations": [
{
"id": 12856,
"date_modified": "2023-03-31T07:15:28.556222-07:00",
}
]
},
...
And to exclude the nested degree_detail field within each education entry:
curl "https://www.courtlistener.com/api/rest/v4/people/?omit=educations__degree_detail"
{
"resource_uri": "https://www.courtlistener.com/api/rest/v4/educations/12856/",
"id": 12856,
"school": {
"resource_uri": "https://www.courtlistener.com/api/rest/v4/schools/4240/",
"id": 4240,
"is_alias_of": null,
"date_created": "2010-06-07T17:00:00-07:00",
"date_modified": "2010-06-07T17:00:00-07:00",
"name": "University of Maine",
"ein": 16000769
},
"person": "https://www.courtlistener.com/api/rest/v4/people/16214/",
"date_created": "2023-03-31T07:15:28.556198-07:00",
"date_modified": "2023-03-31T07:15:28.556222-07:00",
"degree_level": "jd",
"degree_year": 1979
}
...
We highly recommend using this feature to optimize your requests.
Pagination
Most APIs can be paginated by using the page GET parameter, but that will be limited to 100 pages of results.
As of API v4, deep pagination is generally enabled for requests that are ordered by the id, date_modified, or date_created field. When sorting by these fields, the next and previous keys of the response are how you must paginate results, and the page parameter will not work.
Some API endpoints support slightly different fields for deep pagination:
/api/rest/v4/recap-fetch/also supports thedate_completedfield./api/rest/v4/alerts/and/api/rest/v4/docket-alerts/only support thedate_createdfield.