Midpage Search API
The Search API from Midpage — 1 operation(s) for search.
The Search API from Midpage — 1 operation(s) for search.
openapi: 3.0.1
info:
title: Midpage Legal Database Opinions Search API
description: REST API for Midpage's US legal database ("Caselaw Building Blocks"). Search court opinions with semantic (vector), keyword (full-text), or hybrid search; retrieve full opinion data by ID, citation, or docket number with citator treatments; and read the authenticated user's identity and subscription status. Authenticate with a bearer token (API key) in the Authorization header.
termsOfService: https://www.midpage.ai/
contact:
name: Midpage
url: https://www.midpage.ai/
version: '1.0'
servers:
- url: https://app.midpage.ai/api/v1
description: Production server
security:
- apiKey: []
tags:
- name: Search
paths:
/search:
post:
operationId: searchOpinions
tags:
- Search
summary: Search opinions
description: 'Search for opinions using semantic (vector), keyword (full-text), or hybrid search.
Search modes: `semantic` (vector similarity using AI embeddings), `keyword` (Elasticsearch full-text with Lexis/Westlaw-style boolean operators), and `hybrid` (semantic + keyword combined with reciprocal rank fusion and deduplication).
Boolean operators (keyword mode only, must be UPPERCASE): AND, OR, NOT, "..." (exact phrase), * and ? (wildcards), W/n (proximity within n words), and () for grouping.
Pagination uses `page` (1-indexed) and `page_size` (max 100). Semantic search supports limited deep pagination (~500 unique results); keyword and hybrid support deep pagination via Elasticsearch.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SearchRequest'
responses:
'200':
description: Search results
content:
application/json:
schema:
$ref: '#/components/schemas/SearchResponse'
'400':
description: Bad request
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: query is required and must be a string
'401':
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Unauthorized
message:
type: string
example: Invalid API key
components:
schemas:
PaginationMeta:
type: object
properties:
page:
type: integer
description: Current page number
page_size:
type: integer
description: Results per page
total_results:
type: integer
description: Total matching results (capped at 10,000 for keyword/hybrid)
total_pages:
type: integer
description: Total pages available
has_next:
type: boolean
description: Whether more pages exist
has_prev:
type: boolean
description: Whether previous pages exist
SearchResponse:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/SearchResultItem'
pagination:
$ref: '#/components/schemas/PaginationMeta'
metadata:
type: object
properties:
mode:
type: string
enum:
- semantic
- keyword
- hybrid
description: Search mode used
query:
type: string
description: Original query
processing_time_ms:
type: integer
description: Server processing time in milliseconds
boolean_query:
type: object
description: Present in keyword mode when boolean operators are detected
properties:
detected:
type: boolean
description: Whether boolean operators were detected
operators:
type: array
items:
type: string
description: List of detected operators (e.g., ["AND", "OR", "W/5"])
facets:
$ref: '#/components/schemas/SearchFacets'
SearchRequest:
type: object
required:
- query
properties:
query:
type: string
description: Search query text
example: breach of fiduciary duty
mode:
type: string
enum:
- semantic
- keyword
- hybrid
default: semantic
description: 'Search mode: `semantic` (vector similarity, default), `keyword` (full-text), or `hybrid` (combined semantic and keyword results using reciprocal rank fusion).'
page:
type: integer
minimum: 1
default: 1
description: Page number (1-indexed)
page_size:
type: integer
minimum: 1
maximum: 100
default: 20
description: Results per page (max 100)
filters:
$ref: '#/components/schemas/SearchFilters'
include_facets:
type: boolean
default: false
description: Include facet breakdowns in the response showing result counts by court, jurisdiction, state, and year. Facets are only available in `keyword` and `hybrid` modes (not `semantic`). In `hybrid` mode, facet counts reflect keyword search results only.
SearchFilters:
type: object
description: Optional filters to narrow search results
properties:
court_ids:
type: array
items:
type: string
description: Filter by court IDs (e.g., "ca9", "scotus", "nysd")
example:
- ca9
- ca2
jurisdictions:
type: array
items:
type: string
enum:
- Federal Appellate
- Federal District
- State Supreme
- State Appellate
- State Trial
- Federal Bankruptcy
- Federal Bankruptcy Panel
- Federal Special
- Military Appellate
- State Attorney General
- State Special
- U.S. Territory
- Committee
- International
- Tribal
- Tribal Appellate
- Tribal Supreme
- Tribal Trial
description: Filter by jurisdiction type using canonical values from Midpage court metadata.
example:
- Federal Appellate
- State Supreme
states:
type: array
items:
type: string
description: Filter by state using full canonical names from Midpage court metadata.
example:
- California
- New York
publish_status:
type: string
description: Filter by publication status. Use `unknown` to include opinions where publication metadata is missing or uncertain.
enum:
- published
- unpublished
- unknown
- in_chambers
- separate
- errata
- relating_to
example: published
date_filed:
type: object
description: Filter by filing date range
properties:
start:
type: string
format: date
description: Start date (YYYY-MM-DD)
example: '2020-01-01'
end:
type: string
format: date
description: End date (YYYY-MM-DD)
example: '2024-12-31'
SearchResultItem:
type: object
properties:
opinion_id:
type: string
description: Opinion identifier
score:
type: number
description: 'Relevance score. Scale varies by mode: semantic 0-1 (cosine similarity), keyword 0-100+ (BM25 score).'
case_name:
type: string
description: Case name/caption
court_id:
type: string
description: Court identifier
court_name:
type: string
description: Full court name
court_abbreviation:
type: string
description: Court citation abbreviation
jurisdiction:
type: string
description: Jurisdiction type
state:
type: string
nullable: true
description: State name (null for federal courts)
publish_status:
type: string
nullable: true
description: Publication status, when available
enum:
- published
- unpublished
- unknown
- in_chambers
- separate
- errata
- relating_to
date_filed:
type: string
format: date
description: Filing date (YYYY-MM-DD)
docket_number:
type: string
nullable: true
description: Court docket number, when available
snippet:
type: string
description: Relevant text excerpt from the opinion
source:
type: string
enum:
- semantic
- keyword
description: 'Source of this result. Always present in API responses: semantic mode "semantic", keyword mode "keyword", hybrid mode varies per item.'
SearchFacets:
type: object
description: 'Facet breakdowns showing result counts by various dimensions. Only present when `include_facets: true` in request and mode is `keyword` or `hybrid`. Counts are computed across the full result set (after filters), not just the current page.'
properties:
court_abbreviation:
type: array
items:
$ref: '#/components/schemas/FacetBucket'
description: Breakdown by court abbreviation (e.g., "9th Cir.", "S.D.N.Y.")
jurisdiction:
type: array
items:
$ref: '#/components/schemas/FacetBucket'
description: Breakdown by jurisdiction type
state:
type: array
items:
$ref: '#/components/schemas/FacetBucket'
description: Breakdown by state name
year_filed:
type: array
items:
$ref: '#/components/schemas/FacetBucket'
description: Breakdown by filing year
note:
type: string
description: Explanatory note about facet limitations.
example: Facet counts reflect keyword search results only; semantic (Pinecone) results are not included in these counts.
FacetBucket:
type: object
description: A single bucket in a facet breakdown
properties:
key:
type: string
description: The value (e.g., "9th Cir.", "Federal Appellate", "2024")
count:
type: integer
description: Number of documents matching this value
securitySchemes:
apiKey:
type: http
scheme: bearer
description: API key authentication. Get your API key from the Midpage Developer Portal at https://app.midpage.ai/developers