Every Indian legaltech or background-verification team has a folder somewhere called scraper_v7 and a Slack channel called ecourts_down. The public services.ecourts.gov.in portal is a national asset. It is not a production API. The openjustice-in GitHub library describes it as “intentionally single-threaded”. That is fine for a journalist on deadline. It is not fine for a product with a customer-facing SLA. This post is the quickstart for the API you build on when scraping is no longer your day job.

Where the API sits
Three layers. At the bottom is services.ecourts.gov.in, the district and High Court portal run by the e-Committee of the Supreme Court of India. Alongside it is the NJDG, the National Judicial Data Grid, which publishes aggregates. The eCourtsIndia API sits above these, with a live index of over 27 crore case records refreshed against the source, clean JSON responses, OCR’d order text, and Solr-powered search. Your app calls us. We handle the hard part.
Auth and sandbox
Create an account on eCourtsIndia. Generate an API key from the developer dashboard. Keys are scoped to an environment. Sandbox keys let you run the full surface area against a representative subset of data with no cost. Production keys run against the full live index under per-minute rate limits that scale with your tier. Keys are sent as a bearer token on every request.
The five endpoints you will use first
| Endpoint | Purpose |
|---|---|
POST /v1/cases/search |
Solr full-text search across every indexed case |
GET /v1/cases/{cnr} |
Complete record for one CNR |
GET /v1/cases/{cnr}/brief |
AI-summarised client-ready brief |
POST /v1/causelist/search |
Cause list with advocate, judge, litigant, date filters |
GET /v1/orders/{id}/markdown |
Clean Markdown of any uploaded order or judgment |
If you have been following our blog, the vocabulary is the same as our Case Type Encyclopedia and Case Status Dictionary. Codes are stable. Use the enum lookups before you hard-code a filter.

Fifteen lines of Python that replace a scraper
import requests, os
API = "https://api.ecourtsindia.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['ECI_KEY']}"}
def search_cheque_bounce_pending(court="DLHC01", year_min=2023):
body = {
"query": "cheque bounce",
"courtCodes": court,
"caseStatuses": "PENDING",
"filingDateFrom": f"{year_min}-01-01",
"pageSize": 100,
}
r = requests.post(f"{API}/cases/search", json=body, headers=HEADERS, timeout=10)
r.raise_for_status()
return r.json()["data"]["results"]
for c in search_cheque_bounce_pending():
print(c["cnr"], c["caseType"], c["petitioners"][0])
That is the replacement for a hundred lines of BeautifulSoup, retry logic, CAPTCHA solvers, and polite apologies to the DevOps lead when the scraper goes down on a Monday.
Pagination, facets, and the Solr model
Search responses paginate with page and pageSize. Max page size is 100. Facets come back on every response, telling you how your 3,566-hit result set distributes across case type, status, court, filing year, and state. That facet block is the backbone of any dashboard you are about to build. Do not ignore it.
For cause lists, the cursor is offset-based. Start at offset=0, limit=100. Increment offset by limit. Stop when the returned count is less than the limit.
The gotchas we promise to be honest about
- Court code drift. NCLT bench codes require a trailing zero (
NCLTMB0, notNCLTMB). Details in our Case Type Encyclopedia. - Act filter format. The
actsAndSectionsfilter expects the full stored text (INDIAN PENAL CODE – 302), not abbreviations (IPC 302). Use free-text query for loose matches. - Double-quoted phrase + boolean. Solr backend throws 500 on “fundamental rights” AND discrimination. Use unquoted AND/OR.
- Misc cause list status fields. Sometimes empty. Our flagship data piece breaks this down.

Webhooks, polling, and portfolio monitoring
For applications that need to react to changes, we offer a portfolio monitoring endpoint. Register a list of CNRs. We call your webhook on any change. For teams not ready for webhooks, a daily bulk_refresh_cases call with the same list returns every case that moved in the last 24 hours. Either pattern works. Pick the one that matches your on-call rotation.
Where we are honestly not the right answer
If you need to file on services.ecourts.gov.in, use the portal directly. Filing is not a read operation and we do not offer it. If you need document-level e-signing, use a purpose-built CLM. If you need billing and trust accounting, use a practice management product. We are the data layer. We are not the practice tool.
What this means for builders
You can ship a credible product on Indian court data in one sprint. The hard engineering has already been done. Your time is better spent on the user experience and the specific workflow for your audience. Read the docs at ecourtsindia.com/api. Connect the MCP for local AI workflows at ecourtsindia.com/api/mcp. See our MCP 101 post for the no-code path.
The fastest way to tell whether your legaltech MVP works is to stop fighting the data layer and start talking to customers. Our API exists so you can do exactly that.
Further reading: LLMs.txt for Indian Courts, CNR Number Decoded.