Look up Supreme Court of India case status by case number or diary number — straight from sci.gov.in public records.
A small, self-hostable tool for lawyers, paralegals, parties to litigation, journalists, and citizens who want fast, structured access to Supreme Court case status without clicking through the official site every time.
Ships with four ways to use it: a Python library, a CLI, a FastAPI HTTP service with a tiny web UI, and a Telegram bot.
┌─────────────────────────────────────────────┐
│ $ sci-case-tracker "CA 9999/2099" │
│ │
│ ACME INDUSTRIES PVT. LTD. vs DEMO CORP. │
│ Diary: 00000/2099 │
│ Case: C.A. No. 9999 / 2099 │
│ Status: PENDING — Part Heard │
│ Last listed: 04-05-2099 — Justice X │
│ & Justice Y │
│ Recent orders: 30-Apr-2099, 25-Feb-2099, …│
│ Latest order PDF: https://api.sci.gov.in/…│
└─────────────────────────────────────────────┘
(Sample output uses dummy data. Real lookups return live records from sci.gov.in.)
Telegram bot processing 28 case references extracted from a PDF and fetching live status for each.
This tool reads case data from the official, public Supreme Court of India website at sci.gov.in. The same data is available to any visitor of the public case-status page at https://www.sci.gov.in/case-status-case-no/ — no login, no scraping bypass, no captcha solver. The tool simply submits the same documented form fields the page itself uses (sci_auto_submit=1, es_ajax_request=1, etc., as published in SCI's own JavaScript at /wp-content/mu-plugins/sci-api/).
The tool is intended for legitimate research and tracking. Please respect SCI's infrastructure: this tool caches aggressively (see Architecture), and you should too.
- Free-text parser — accepts
CA 9999/2099,Civil Appeal No. 9999 of 2099,SLP(C) 7777/2099,MA 0001/2099,Diary 00000/2099, etc. - File uploads — drop a PDF, Word doc, Excel sheet, CSV, or screenshot; the tool extracts every case reference, looks each up in parallel, and returns CSV / Excel / JSON.
- OCR for screenshots — Tesseract reads case numbers off cause-list images, hearing slips, etc.
- Auto diary resolution — case numbers are translated to SCI's stable internal diary number once and cached forever.
- Tiered SQLite cache — diary numbers cached forever, summaries 24h, order lists 1h on court days / 6h overnight.
- HTTP/2 connection pooling — 3-way parallel fetches per case.
- Four delivery surfaces:
sci_case_tracker.lookup()/process_file()— Python librarysci-case-tracker "CA 9999/2099"— CLIuvicorn api.main:app— FastAPI + tiny web UI +/uploadendpointpython -m bot.telegram_bot— Telegram bot with/trackwatchlist + drop-a-file support
# Send a PDF/Word/Excel/screenshot → get an enriched Excel back
curl -F 'file=@morning_brief.pdf' 'http://localhost:8000/upload?format=xlsx' -o status.xlsx
# JSON response with all extracted cases + their statuses
curl -F 'file=@cause_list.png' 'http://localhost:8000/upload?format=json' | jq
# Just extract refs without looking them up
curl -F 'file=@brief.docx' 'http://localhost:8000/extract'In the Telegram bot, just send the file as an attachment — it replies with a summary plus an Excel report.
System dependency for OCR: sudo apt install tesseract-ocr (Ubuntu/Debian) or brew install tesseract (macOS).
git clone https://github.com/CyberWarrior9/sci-case-tracker.git
cd sci-case-tracker
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pip install -e .
# 1. Try the CLI
sci-case-tracker "CA 9999/2099"
# 2. Run the HTTP API + web UI
uvicorn api.main:app --host 0.0.0.0 --port 8000
# open http://localhost:8000/ui (web search box)
# open http://localhost:8000/docs (interactive API)
# 3. Run the Telegram bot
cp .env.example .env
# Edit .env, paste TELEGRAM_BOT_TOKEN from @BotFather
export $(cat .env | xargs)
python -m bot.telegram_botfrom sci_case_tracker import lookup, parse, SCIError
# Structured result (dict)
result = lookup("CA 9999/2099")
print(result["diary_no"], result["diary_year"])
print(result["text"])
# Just the formatted string
print(lookup("Diary 00000/2099", as_text=True))
# Parse only (no network call)
parse("SLP(C) 7777 of 2099")
# → {"kind": "case_no", "case_type": 1, "case_no": 7777, "year": 2099, ...}| Method | Path | Purpose |
|---|---|---|
| GET | / |
Health check |
| GET | /case?query=... |
Structured JSON |
| GET | /case/text?query=... |
Plain-text summary (curl-friendly) |
| GET | /ui |
Static web UI (search box) |
| GET | /docs |
Interactive OpenAPI explorer |
curl 'http://localhost:8000/case?query=CA+9999/2099'@BotFather → /newbot → copy token
↓
export TELEGRAM_BOT_TOKEN="123456:ABC..."
python -m bot.telegram_bot
Then in Telegram:
| Message | Bot replies with |
|---|---|
CA 9999/2099 |
full case status |
SLP(C) 7777/2099 |
full case status |
Diary 00000/2099 |
full case status |
/track CA 9999/2099 |
adds to your watchlist |
/list |
shows your watchlist |
/help |
usage guide |
To restrict the bot to specific Telegram users, set TELEGRAM_ALLOWED_USERS=111,222 in .env.
Tip: if you want the bot to read every group message (not just mentions), open
@BotFather → /setprivacy → Disable, then remove and re-add the bot to the group.
docker compose -f docker/docker-compose.yml up -d api
# API on http://localhost:8000
docker compose -f docker/docker-compose.yml --profile bot up -d
# also runs the Telegram bot if .env has TELEGRAM_BOT_TOKENdocs/ARCHITECTURE.md— system diagram, components, why each piece existsdocs/WORKFLOW.md— request lifecycle, cache tiers, parallel fetchesdocs/OBSTACLES.md— hurdles encountered building this and how each was solveddocs/DEPLOY.md— VPS, Railway, Render, Fly.io recipes
37 SCI case types are mapped (see case_types.json). Common ones:
| Display | Aliases accepted | Internal code |
|---|---|---|
| SLP(C) | SLP C, Special Leave Petition (Civil) |
1 |
| SLP(Cri) | SLP CRI, SLP CRL |
2 |
| Civil Appeal | CA, C.A., Civil Appeal |
3 |
| Crl Appeal | CRLA, Criminal Appeal |
4 |
| WP(C) | WP C, Writ Petition (Civil) |
5 |
| Misc Appl. | MA, M.A., Miscellaneous Application |
39 |
| Diary | Diary 12345/2024, D No 12345 of 2024 |
31 |
Full list: see src/sci_case_tracker/case_types.json.
| Scenario | Latency |
|---|---|
| First-ever lookup (cold) | ~2.5–4 s |
| Re-lookup (cache hit, summary) | ~50 ms |
| Re-lookup, fresh orders refetch | ~1.0 s |
| Diary lookup (skips resolution) | ~1.5 s cold, ~50 ms warm |
The cache is per-user and per-install; first hit on a case is slower because the diary number has to be resolved against SCI.
PRs welcome. The code is small (~600 LOC total) and intentionally low-magic. To get started:
pip install -e ".[dev]"
pytest
ruff check .When adding new case types, update both case_types.json and the alias patterns in parser.py.
MIT — see LICENSE.
- The Supreme Court of India for publishing case status as a public service
- The eCourts Mission Mode Project for digitising court records
- Everyone who's ever filed a one-line PIL and waited four years to find out it got listed
{ "query": "CA 9999/2099", "parsed": {"kind": "case_no", "case_type": 3, "case_no": 9999, "year": 2099, ...}, "diary_no": 9999, "diary_year": 2024, "text": "ACME INDUSTRIES PVT. LTD. vs DEMO CORPORATION PVT. LTD.\nDiary: 00000/2099\n..." }