Court records, case law & litigation search for AI agents — search US court opinions and case law by keyword via CourtListener. Use to find lawsuits, legal p...
Documents
Reputation courts practice search
Try itRussian court practice (судебная практика РФ) via reputation.ru — find cases, get a synthesized analysis report, or fetch a document's full text across arbitration (арбитраж), general jurisdiction (СОЮ), and the Supreme Court (ВС РФ). Use for «найди практику по…», «как суды решают…», «обзор практики
What it does
Russian court practice (судебная практика РФ) via reputation.ru — find cases, get a synthesized analysis report, or fetch a document's full text across arbitration (арбитраж), general jurisdiction (СОЮ), and the Supreme Court (ВС РФ). Use for «найди практику по…», «как суды решают…», «обзор практики», «полный текст решения». Paid service — needs REPUTATION_API_KEY; if tools are missing or you get 401/403, do the Setup section first.
The skill document
Russian court practice (reputation.ru)
Paid service. Uses the reputation.ru court API — a paid third-party service that needs a reputation.ru account and API key (
REPUTATION_API_KEY; get one at https://reputation.ru/account/api). Calls are billed per the service tariff.
One skill covering Russian court practice, with three capabilities plus setup:
- Search — a fast, relevant list of cases (the default).
- Deep analysis — an asynchronous synthesized report across all court systems.
- Document text — the full text of one document by its id.
Work through the MCP tools when the reputation MCP is connected; otherwise use the
REST API (or the bundled court_client.py). If tools are missing or a call
returns 401/403, do Setup first.
Setup
Needed once — skip if the reputation MCP tools already work.
There are two ways to authorize. Pick by what the client supports and whether a human is available right now:
| Use when | Who authorizes | |
|---|---|---|
| Account sign-in (OAuth) | the client supports OAuth for MCP and a person is at the keyboard | the user, in a browser |
| API key | any client, headless runs, REST, CI | you, with a key the user supplies |
MCP config lives in .claude/mcp.json, ~/.cursor/mcp.json, the Claude Desktop
config, or your runtime's equivalent. Restart the client after editing it.
1a. MCP with account sign-in (OAuth)
Point the client at the server with no headers at all:
{
"mcpServers": {
"reputation-court-search": {
"url": "https://api.reputation.ru/mcp"
}
}
}
On the first call the client receives 401 with a WWW-Authenticate header naming the
protected-resource metadata, discovers the authorization server (https://reputation.ru),
registers itself, and opens a browser so the user can sign in and approve access. After
that the client stores and refreshes the token on its own — no key is ever handled by you.
You cannot complete this flow yourself. It needs a person in a browser. If you are
running non-interactively, stop and say so: ask the user to authorize the server in their
client (Claude Code: /mcp; Cursor: MCP settings), then retry. Never ask the user to
paste an authorization code, access token, or callback URL to you, and never try to
drive the consent page yourself.
Do not add headers.Authorization to an OAuth config. Most clients skip the sign-in
flow entirely when a static Authorization header is present and send its value as an API
key instead — the symptom is an auth error with no sign-in ever offered.
The name the client registers under is what the user sees at https://reputation.ru/account/api under "Подключённые AI-ассистенты", where they can revoke access.
If the client has no OAuth support for MCP, use an API key instead.
1b. MCP with an API key
The user creates a key at https://reputation.ru/account/api ("Создать API ключ") and gives
it to you. Send it in an Authorization header:
{
"mcpServers": {
"reputation-court-search": {
"url": "https://api.reputation.ru/mcp",
"headers": { "Authorization": "" }
}
}
}
Either way the MCP server exposes: search_arbitration_cases, search_general_court_cases,
search_vsrf_documents, deep_research_request / deep_research_status /
deep_research_result, get_general_court_document, get_arbitration_document.
Billing is the same for both: requests are charged to the user's account per the service tariff.
2. Use the REST API (no MCP)
Authorize with an API key — account sign-in applies to the MCP endpoint.
Base URL https://api.reputation.ru; send Authorization: on every call.
A ready client that handles requests, JSON, and the async analysis polling loop is
embedded at the end of this file under Bundled REST client — save that block as
court_client.py, then run it (Python stdlib only — no install):
export REPUTATION_API_KEY=
# optional: export REPUTATION_BASE_URL=https://api.reputation.ru
python court_client.py search general "взыскание процентов по ст. 395 ГК РФ"
python court_client.py analyze "как суды взыскивают неустойку по ДДУ"
python court_client.py doc arbitr
3. Verify
Run a cheap search — e.g. search_vsrf_documents("обзор судебной практики") or
court_client.py search vsrf "обзор судебной практики". A non-empty result confirms
the key and connection.
Route to the right court system
- Arbitration (арбитраж) — disputes between organizations/entrepreneurs: debt
between companies, bankruptcy of ООО/ИП, corporate conflicts, contracts (поставка,
подряд, аренда), tax (ФНС), IP/trademarks, state bodies (ФАС). Case no.
А40-12345/2024; document id →DocId. - General jurisdiction (СОЮ) — disputes involving individuals: family (развод,
алименты), inheritance, labour, consumer protection, insurance (ОСАГО/КАСКО),
criminal, administrative (КоАП), housing. Case no.
2-1700/2025; document id →FileId. - Supreme Court (ВС РФ) — high-court legal positions: постановления Пленума, обзоры практики, Президиум. For "what's the established position on…", not for individual cases. (No separate document-text endpoint — its search results already carry the text.)
If a question spans systems, search the two most likely — or use Deep analysis, which covers all three.
1. Search (fast — the default)
MCP — call the matching tool with query:
| System | Tool |
|---|---|
| Arbitration | search_arbitration_cases(query) |
| General jurisdiction | search_general_court_cases(query) |
| Supreme Court | search_vsrf_documents(query) |
REST — Authorization: , base https://api.reputation.ru,
body { "Query": "<вопрос на русском>" }:
| System | POST path |
|---|---|
| Arbitration | /api/v2/arbitr/ai-search |
| General jurisdiction | /api/v3/general-jurisdiction-courts/ai-search |
| Supreme Court | /api/v1/vsrf/ai-search |
Or court_client.py search {arbitr|general|vsrf} "".
Tips: write the query in Russian, describing the situation and naming the
norm when relevant (банкротство ООО по заявлению кредитора). Each search call is
billed as one request — refine deliberately, don't spam near-duplicates.
2. Deep analysis (async synthesized report)
Use when the user wants a synthesized answer across practice («сложившаяся практика по…», «как суды решают…», «обзор практики»), not just a case list. One async job searches all three systems, filters by relevance, and returns a Markdown report with embedded case links plus the ids of the cases it cites.
Start → poll → fetch — don't block on a single call:
- Start (billed once, here):
- MCP:
deep_research_request(query)→request_id - REST:
POST /api/v1/ai-analysis/request{ "Query": "…" }→{ "RequestId": "…" }
- MCP:
- Poll status (not billed) — every ~10–15s:
- MCP:
deep_research_status(request_id)→InProcess|Done|Failed - REST:
GET /api/v1/ai-analysis/status?RequestId=→{ "Status": "…" }
- MCP:
- Fetch result when
Done(not billed):- MCP:
deep_research_result(request_id) - REST:
GET /api/v1/ai-analysis/result?RequestId=→{ "Report": "…", "CaseIds": [ … ] }
- MCP:
Rules: usually Done in ~30–120s. If it exceeds a few minutes without Done/Failed,
stop and tell the user rather than polling forever. Failed → the job errored; you
may start a new request. One-shot alternative: court_client.py analyze "<тема>" runs
the whole loop and returns the report. Return the report as-is — keep its embedded
case links; you may append the cited CaseIds as a short reference list.
3. Document text
Retrieve the full plain text of a specific document. You need an id from a prior search result — this does not search for cases.
MCP:
| System | Tool |
|---|---|
| General jurisdiction | get_general_court_document(file_id=) |
| Arbitration | get_arbitration_document(doc_id=) |
REST — Authorization: , base https://api.reputation.ru, returns
text/plain:
| System | GET path | Id param | Empty-text status |
|---|---|---|---|
| General jurisdiction | /api/v3/general-jurisdiction-courts/documents/text | id = FileId | 204 |
| Arbitration | /api/v1/arbitr/document/text | docId = DocId | 404 |
Or court_client.py doc {general|arbitr} . A 204/404 (or empty text) means
the document has no indexed text — tell the user; don't fabricate content.
Presenting results
- Always cite the case number and its link (
WebsiteUrl) so the user can open the card. - An empty search result may mean "nothing found" or a timeout — if empty, note that simplifying the query may help.
- Quote or summarize only what the returned cases/text actually support — don't fabricate case numbers, parties, outcomes, or document content.
Billing (so you can warn the user)
- Each search call = one billed request.
- Deep analysis = one billed request at start (
deep_research_request); status & result are free. - Document text retrieval is billed per the service tariff.
Troubleshooting
401— missing/invalid API key. Check theAuthorizationheader /REPUTATION_API_KEY.401carrying aWWW-Authenticate: Bearer … resource_metadata=…header — the server is asking for account sign-in and the client isn't authorized yet. Have the user sign in (1a) or configure an API key (1b). Don't retry the call unchanged.invalid_token— the access token expired or was revoked. The user must sign in again; you cannot refresh it for them.insufficient_scope— the token is missing themcpscope. Re-authorize; if it repeats, fall back to an API key.- The client never offers sign-in — a static
Authorizationheader is configured, which disables the OAuth flow. Remove theheadersblock (see 1a). 403— the key lacks access to that endpoint. If requests go through a proxy, check that it isn't the proxy returning this: try the same call bypassing it (NO_PROXY).429— rate limit; back off and retry.400on document text — missing id param.- MCP tools not appearing — re-check the config path and restart the client; some clients cache the tool list.
Bundled REST client (court_client.py)
Only needed on the REST path (no MCP). Save this block verbatim as court_client.py and run it as shown in Setup → 2. Dependency-free — Python standard library only.
#!/usr/bin/env python3
"""
Minimal, dependency-free client for the reputation.ru court API.
For agents that can run code but don't have the reputation MCP connected. Uses
only the Python standard library.
Auth: set REPUTATION_API_KEY (get a key at https://reputation.ru/account/api).
Base URL overridable via REPUTATION_BASE_URL (default https://api.reputation.ru).
CLI:
python court_client.py search {arbitr|general|vsrf} "запрос на русском"
python court_client.py analyze "тема для глубокого анализа"
python court_client.py doc {arbitr|general}
"""
import json
import os
import sys
import time
import urllib.parse
import urllib.request
BASE_URL = os.environ.get("REPUTATION_BASE_URL", "https://api.reputation.ru").rstrip("/")
API_KEY = os.environ.get("REPUTATION_API_KEY", "")
SEARCH_ENDPOINTS = {
"arbitr": "/api/v2/arbitr/ai-search",
"general": "/api/v3/general-jurisdiction-courts/ai-search",
"vsrf": "/api/v1/vsrf/ai-search",
}
# (endpoint, id query-param name)
DOCUMENT_ENDPOINTS = {
"arbitr": ("/api/v1/arbitr/document/text", "docId"),
"general": ("/api/v3/general-jurisdiction-courts/documents/text", "id"),
}
ANALYSIS = {
"request": "/api/v1/ai-analysis/request",
"status": "/api/v1/ai-analysis/status",
"result": "/api/v1/ai-analysis/result",
}
class CourtApiError(Exception):
pass
def _request(method, path, *, params=None, body=None, expect="json", timeout=60):
if not API_KEY:
raise CourtApiError("REPUTATION_API_KEY is not set")
url = BASE_URL + path
if params:
url += "?" + urllib.parse.urlencode(params)
headers = {"Authorization": API_KEY}
data = None
if body is not None:
data = json.dumps(body).encode("utf-8")
headers["Content-Type"] = "application/json"
req = urllib.request.Request(url, data=data, headers=headers, method=method)
try:
with urllib.request.urlopen(req, timeout=timeout) as resp:
raw = resp.read()
if resp.status == 204:
return None
if expect == "text":
return raw.decode("utf-8", "replace")
return json.loads(raw.decode("utf-8"))
except urllib.error.HTTPError as e:
detail = e.read().decode("utf-8", "replace")[:300]
raise CourtApiError(f"HTTP {e.code} on {method} {path}: {detail}") from None
def search(system, query):
"""Fast AI search in one court system. Returns the paginated collection dict."""
if system not in SEARCH_ENDPOINTS:
raise CourtApiError(f"unknown system {system!r}; use one of {list(SEARCH_ENDPOINTS)}")
return _request("POST", SEARCH_ENDPOINTS[system], body={"Query": query})
def document_text(system, doc_id):
"""Full text of a case document by its id (FileId for general, DocId for arbitr).
Returns the text, or None if the document has no indexed text (204/404)."""
if system not in DOCUMENT_ENDPOINTS:
raise CourtApiError(f"unknown system {system!r}; use one of {list(DOCUMENT_ENDPOINTS)}")
endpoint, id_param = DOCUMENT_ENDPOINTS[system]
try:
return _request("GET", endpoint, params={id_param: doc_id}, expect="text")
except CourtApiError as e:
if "HTTP 404" in str(e):
return None
raise
def analyze(query, poll_interval=12, timeout=300):
"""Run the full async deep-research flow: request -> poll -> result.
Returns {"Report": ..., "CaseIds": [...]}. Raises on failure/timeout."""
created = _request("POST", ANALYSIS["request"], body={"Query": query})
request_id = created.get("RequestId") or created.get("requestId")
if not request_id:
raise CourtApiError("analysis request did not return a RequestId")
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
status = _request("GET", ANALYSIS["status"], params={"RequestId": request_id})
state = (status.get("Status") or status.get("status") or "").strip()
if state == "Done":
return _request("GET", ANALYSIS["result"], params={"RequestId": request_id})
if state == "Failed":
raise CourtApiError(f"analysis {request_id} failed")
time.sleep(poll_interval)
raise CourtApiError(f"analysis {request_id} did not finish within {timeout}s")
def _main(argv):
if len(argv) < 2:
print(__doc__)
return 1
cmd = argv[1]
if cmd == "search" and len(argv) >= 4:
print(json.dumps(search(argv[2], argv[3]), ensure_ascii=False, indent=2))
elif cmd == "analyze" and len(argv) >= 3:
print(json.dumps(analyze(argv[2]), ensure_ascii=False, indent=2))
elif cmd == "doc" and len(argv) >= 4:
text = document_text(argv[2], argv[3])
print(text if text is not None else "(no indexed text for this document)")
else:
print(__doc__)
return 1
return 0
if __name__ == "__main__":
sys.exit(_main(sys.argv))
Related skills
Russian text quality — typography, info-style, editorial, UX writing, business correspondence, and AI-text cleanup
China legal triage assistant. Input a contract, labor dispute facts, lawsuit-cost question, or draft legal document need; output risk checklist, cost estimat...
Case and research memory for legal work — holdings, citations, and reasoning chains that survive across sessions. Use when an agent assists with legal research and must not lose the thread of a case. Requires a BlueColumn API key (bc_live_*).
Review the quality, reproducibility, legal reasoning, and decision usefulness of an existing freedom-to-operate (FTO), patent-infringement-risk, or event IP risk report. Use for three-layer evidence review, four-dimension scoring, independent multi-route search comparison, omission analysis, fatal-defect screening, remediation planning, or HTML assessment generation. The skill audits a supplied report; it does not replace a jurisdiction-specific legal opinion.
Finds law firms and legal practices via Google Search using apidojo's Google Search Scraper on Apify. Triggers when the user asks to: find law firms for sales outreach, discover legal practices in a specific city, build a list of attorneys or law offices via Google, find personal injury or corporate law firms for vendor prospecting, search for law firms by specialty and location, identify solo practitioners or large law offices, or compile a law firm contact list from Google results. Returns firm name, website URL, and Google snippet per result. Ideal for LegalTech SaaS vendors, legal software providers, and B2B service companies targeting law firms.