,

LegalCheck API: India’s Court-Record BGV API, Benchmarked Against the Whole Market

LegalCheck API for court-record BGV in India: six endpoints, the legal-check.v1 schema, a worked run and a migration map from AuthBridge, IDfy and OnGrid.

·

·

eCourtsIndia Knowledgebase

LegalCheck API by eCourtsIndia: six REST endpoints for a court-record background check in India, one metered at Rs 99 per accepted job, most reports ready in one to three minutes

API reference · Verified: 15 September 2026 · Engine: eCI-1.0 on build 7.21.2 · Index: 29,20,09,980 court records
Every count on this page was read live from the eCourtsIndia index on the date above, using the same endpoints described here. Competitor figures are quoted from each vendor’s own published page, with the date it was read. Update this page when the model, the rate card or the endpoint list changes.

Last updated: 23 September 2026. The index has since passed 32 crore+ case records, LegalCheck is now also available over MCP and at legalcheck.ecourtsindia.com, and every competitor statement below was re-read against the vendor’s own public page on 23 September 2026.

LegalCheck API by eCourtsIndia: six REST endpoints for a court-record background check in India, one metered at Rs 99 per accepted job, most reports ready in one to three minutes
The LegalCheck partner API. Submit once, read the report as many times as you like.

LegalCheck is a court-record background check you call as an API. You POST a person or a company with the same five fields every Indian BGV vendor already asks for, poll a job code, and read back a legal-check.v1 report: a risk band, an identity confidence, and every matching court record grouped into confirmed, probable, possible and excluded, each one carrying a CNR and a public link you can open and check. Most first reports land in one to three minutes. The whole family is six endpoints, and only one of them costs anything.

This post is the practical one. The product announcement explains why the engine is built the way it is, and the data engine post explains what sits underneath it. This one shows you the calls, walks a real subject end to end against the live index, puts the result next to what every other BGV API in India publishes about itself, and gives you the field map to switch.

Get an API key on eCourtsIndia →

Key takeaways

  • Six REST endpoints. One is metered, five are free. Submit costs ₹99 on Pay As You Go or ₹33 with a subscription. Status, report, list, models and the search log cost nothing, however often you read them.
  • The input is name, a parent or spouse, an address, an age or date of birth. Other Indian court-check vendors publish very similar input lists, which is why the adapter is a field rename rather than a rebuild.
  • The output is not a verdict. It is banded evidence: every match carries a match_breakdown showing which fields agreed, a risk_contribution, a role_group saying whether the matter was brought against your subject or by them, and a public URL.
  • The one value you must special-case is band_5: "UNRESOLVED". It ships with risk.score: 0 and it does not mean clean. It means records exist under the name and none could be attributed. Route it to a human, never to green.
  • On the subject we ran live for this post, a name that returns 63 court records nationally resolves to 9 records covering 8 distinct disputes once geography, mass-party cause titles and duplicate procedure are removed. A vendor that handed you all 63 rows would be attributing 54 other people’s records to your subject.
  • The electoral roll is queried before the court index. For this subject it found two men whose names differ by one letter, with the same father’s name and the same year of birth, both scoring 100. One lives in Ghatkopar. The other is 300 km away in Jalgaon. Only one of them owns the cases.
  • On the seven Indian court-check product pages we read on 15 September 2026 and re-read on 23 September 2026, we did not find a published price, a CNR on a match, a named tribunal, or a versioned matching model.

What the LegalCheck API actually is

It is a productised due diligence job, not another search filter. You are not querying an index and building your own scoring on top, which is the thing we wrote a whole engineering guide about. You are handing over a subject and getting back a report that has already done the identity resolution, already applied the precision gates, and already written down what it could not check.

Six endpoints, all under https://webapi.ecourtsindia.com, all authenticated with a bearer token.

MethodPathWhat it doesCost
POST/api/partner/legal-checkSubmit a subject. Returns 202 with a job codeMetered once
GET/api/partner/legal-check/{code}Poll status: queued, running, completed, failedFree
GET/api/partner/legal-check/{code}/reportThe legal-check.v1 reportFree
GET/api/partner/legal-checkList your jobs as summariesFree
GET/api/partner/legal-check/{code}/logEvery search the engine actually ranFree
GET/api/partner/legal-check/modelsAccepted model ids and subject typesFree
The LegalCheck family, read from the live partner API on 15 September 2026. The search log endpoint landed in the 15 September deploy and is documented in the API guide as the twenty-third partner endpoint.
The six LegalCheck REST endpoints with their prices: submit is metered at Rs 99, while status, report, list, log and models are free to read however often you call them
Submit is charged once, at the moment a job is accepted. Every read after that is free, forever.

Billing is submit-once and the figure is published, which in this market is unusual enough to be worth saying twice. A newly accepted job is charged exactly once, at the moment it is accepted. Everything after that is free forever. A replayed idempotency key returns the original resource without a second charge. A job that fails terminally is refunded once. So one subject is one charge regardless of whether the engine ends up screening eleven records or eleven hundred.

The five fields you are already collecting

The submit body takes subject_type (individual or company) and a subject object. For a person, only name is required. Everything else raises confidence and narrows false positives:

  • father_name, the usual corroborating field
  • addresses, a string array
  • date_of_birth as YYYY-MM-DD, or an age
  • aliases, gender, notes

For a company, company_name is required and directors, registered_addresses, cin, gst, pan and company_type are optional corroborators. Those identifiers are partner-supplied context. Their presence does not mean we independently verified a registry filing, and the report says so.

Look at that list next to what the rest of the market asks for. AuthBridge’s own court check page says its step one is “Enter individual’s name, address/location, DOB or age, father’s name”. OnGrid publishes an API reference for its criminal court record verification check on Stoplight, and SpringVerify says it grades possible matches “against father’s name and address”.

That is not a coincidence. Those are simply the only fields Indian court metadata gives you anything to match on, because there is no Aadhaar and no PAN in a cause title. The consequence for you is the useful part: if you are integrated with any of them today, the input half of your migration is a rename. We come back to the full field map further down.

One subject, run on 15 September 2026 against 29.2 crore records

Abstract claims about identity matching are cheap. Here is a real one, run on the live index on 15 September 2026 while writing this post, using the same public case search that sits under LegalCheck. The index held 29.2 crore records that day; it has since passed 32 crore+.

The subject: Siddharth Ashok Ahire, male. Father: Ashok Ahire. Address as submitted: Ramabai Ambedkar Nagar, Ghatkopar (East), Mumbai 400075. Age recorded as 33, which on the 2024 roll’s qualifying date puts his year of birth around 1991.

We are working at locality level on the address deliberately. The submitted form carried a chawl and a room number, and the roll carries a house code that corresponds to it. Neither is reproduced here, for the same reason the EPIC is not: a room number printed beside a criminal prosecution locates a person more precisely than anything the court register publishes about him. The argument below does not need it.

Five fields. Watch what happens to them.

A funnel from 63 name matches down to 9 records covering 8 distinct disputes for one man, measured live against the eCourtsIndia index on 15 September 2026
The funnel for one common Maharashtrian name, measured against the live index on 15 September 2026. Every subtraction is a named precision gate.

Step one: measure the population before you score anything

The engine does not begin by asking which cases contain this string. It begins by asking how much identifying power the string has at all.

Searched as a litigant on 15 September 2026, Siddharth alone returns 74,387 court records. Ahire alone returns 49,282. Put both tokens together and you get 233 records, of which 223 sit in Maharashtra, 3 in Gujarat, 2 in Madhya Pradesh and 1 in Punjab, and across all four tiers, 212 in district and taluka courts, 14 in High Courts, 4 in the Supreme Court and 1 in a tribunal. Those facet counts do not quite sum to 233, because a small share of records carry no state or court-level assignment at all. That is worth noticing rather than tidying away: it is the first hint that this data is a register and not a database.

Add the father’s given name, so that all three tokens must appear, and you are at 63.

Sixty-three is a screening result. It is not a person. Nine of those sixty-three records turn out to be his. A vendor that hands your reviewer all sixty-three with a probability score attached has handed over fifty-four other people’s court records, moved the identity problem onto your desk, and called it a report.

Step two: ask the electoral roll before you ask the courts

Court attribution rests hardest on two fields: who the subject’s relative is, and which district they belong to. The submit form gives one claim about each. A second, independent register gives another, and because electoral records are organised by household, it also describes the family around an entry.

Searched on the name alone in Maharashtra, the roll returns 446 people called Siddharth Ahire. Now widen the search to the whole country and add a father named Ashok, and even that wider search collapses to eight people.

Two of those eight score 100 out of 100 on both the name and the relative. Both are male. Both are recorded at age 33, so both were born around 1991. Both have a father recorded as Ashok Ahire. Their names differ by a single letter, Siddharth against Sidharth, which is the sort of variance that makes an exact-string search useless and a fuzzy one necessary.

They are different men, and they live three hundred kilometres apart.

Two electors whose names differ by one letter, both with a father named Ashok Ahire and both born about 1991, one in Ghatkopar East and one in Erandol three hundred kilometres away
The exact failure a similarity score cannot see. Two electors, indistinguishable on every field a form collects except the district.

This is the whole argument in one picture. A system that ranks candidates by similarity and takes the best one had roughly even odds of picking the man in Jalgaon. He has no cases. The man in Ghatkopar does. Get it backwards and you have either cleared someone you should not have, or attributed a robbery prosecution to a stranger.

The submitted address is what separates them, and only because places are compared on letters rather than on equality. “Ramabai Ambedkar Nagar” is recorded in the roll as a section called “Vasant Rao Naik East Dutagati Mahamarg Rama Bai”. Mumbai 75 is recorded as pin 400075. An equality test on either of those returns nothing, and nothing then reads as not registered, which is how you delete a man standing at his own address.

One note on what we are not printing. The elector record carries an EPIC number, a part number, a serial and a house code. Those are published by the Election Commission, they are in the API response, and they are exactly how you would confirm this yourself. We are not reproducing them in a blog post, because a voter ID or a room number printed next to a criminal case is a combination neither register publishes and neither should we. The court records below are already public on eCourtsIndia under this man’s name, and every one of them links to its own page.

Step three: the corroboration a name search cannot reach

Here is the part that turns a plausible match into a finding, and it came out of the data rather than out of the form.

The Ghatkopar elector’s polling area is recorded, in the roll’s own words, as Pant Nagar.

Now look at who brought the court matters. Of the nine genuine name matches in Mumbai, Pant Nagar Police Station is the prosecuting party in three, and is named as respondent in a fourth, the bail application. The two heaviest are a robbery prosecution and that bail application, both naming the same co-accused, Shailesh Anil Kardak, who also appears in a 2024 hurt complaint from the same police station. Three more matters carry complainant strings the register abbreviates as “Pn” or “Pn Pstn”, which may well be the same station again, so we are counting only the four we can read without guessing.

The sessions case page records the FIR itself: number 437 of 2021, Pant Nagar police station. So the register, the roll and the FIR all point at the same few hundred metres of Ghatkopar East. That is what a confirmed band is supposed to rest on, and it is a very different object from a 92% string similarity.

Step four: what the gates take away

Scoped to the two district codes that carry Mumbai’s metropolitan magistrate and city sessions courts, the 63 becomes 12. Then the precision gates start subtracting, and every one of them can only ever subtract.

Three of the twelve are mass-party cause titles. One 2014 Esplanade matter lists roughly fifty respondents; another lists about a hundred and forty; a 2024 Borivali matter lists eleven, in which “Siddharth”, “Ashok” and “Ahire” are contributed by three entirely different people (a Siddharth Sharma, an Ashok Poojari and a Pramod Ahire). All three tokens are present. No person is identified. That is score/mass-party-cannot-identify, and it removes them.

Nine survive. Two of those nine are one dispute: a bail application in the City Sessions Court and the sessions case it belongs to, substantially the same sections, same co-accused, same police station. Counting both would double the apparent criminal history of a man who was arrested once. That is score/same-dispute-is-one-source and score/one-dispute-counts-once.

Nine records. Eight distinct disputes. From sixty-three.

CourtMatterStatusParty string in the register
City Sessions Court, MumbaiSessions Case, IPC 397, 506(2), 34. FIR 437/2021, Pant Nagar PS. MHCC020153422021Pending, next hearing 16 Sep 2026Siddharth @ Sidhaya Ashok Ahire
City Sessions Court, MumbaiBail Application on the same prosecution. MHCC020076182021Disposed 8 Jul 2021Siddharth @ Sidhaya Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliCriminal Complaint, IPC 324, 34, Pant Nagar PS. MHMM160006562024Pending, next hearing 14 Dec 2026Siddharth Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliMaharashtra Prevention of Gambling Act 12a, 5, Pant Nagar PS. MHMM160010272023Pending, next hearing 12 Oct 2026Siddharth Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliCriminal Complaint, IPC 143, 144, 147, 148, 149, 324, 506. MHMM160115792010Disposed 13 Mar 2024Siddharth @ Siddhu Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliCriminal Complaint, IPC 379, 34. MHMM160000142009Disposed 21 Apr 2017Siddharth Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliBombay Police Act 142. MHMM160031392012Disposed 22 Nov 2013Siddharth @ Siddhu Ashok Ahire
Addl. Metropolitan Magistrate, VikhroliBombay Police Act 142, separate complainant. MHMM160082992011Disposed 24 Dec 2012Siddharth @ Siddhu Ashok Ahire
Addl. Metropolitan Magistrate, BandraSections 4 and 25, recorded by the register under the Indian Penal Code. MHMM180025332016Disposed 11 Aug 2022Siddharth Ashok Ahire
Nine surviving matters, which resolve to eight distinct disputes: the first two rows are one robbery prosecution, counted once. Read from the live index on 15 September 2026. Every CNR links to its public page. Being named in a matter establishes nothing: a person is presumed innocent unless convicted.

That last row is a small lesson in reading Indian court metadata. The register files sections 4 and 25 under the Indian Penal Code, and there are no such offences in it. Sections 4 and 25 of the Arms Act are almost certainly what was meant. We print what the register wrote rather than what we think it meant, because a background check that silently corrects a source has stopped being checkable.

Notice the party strings. The register spells this man three ways across nine matters: Siddharth Ashok Ahire, Siddharth @ Siddhu Ashok Ahire, and Siddharth @ Sidhaya Ashok Ahire. Two of those carry a nickname inside the party field. An exact-string integration that searched only the name on the form would have found some of these and missed the rest, then reported the remainder as the complete picture. That is the failure mode nobody prices: not a false match, but a confidently incomplete one.

And note what the statuses do not tell you. Five of the eight disputes read “disposed”, and six of the nine rows do, because the bail application closed while the prosecution it belongs to is still running. Disposed is a register value, not a conclusion. It can mean acquittal on the merits, conviction, compromise, a restorable default dismissal, or committal upward. Reading which one requires the order text, which is why the report carries order links rather than a status word. We wrote that argument out at length in the data engine post.

No code? Two other ways to run the same check

The LegalCheck site. Compliance and HR teams that do not want to integrate anything can run the same check at legalcheck.ecourtsindia.com or from the eCourtsIndia dashboard, and download the same banded report.

The MCP server. Since version 4.46 of the eCourtsIndia MCP server (23 September 2026: 39 tools), LegalCheck is also a tool call. submit_legal_check screens a person or company and charges ₹99, or ₹33 on an active subscription, once on acceptance. get_legal_check is free: it waits for the job and returns the risk band, the summary and every matched case. A reviewer can ask Claude or ChatGPT to run the check and then read the matched orders with the case tools in the same conversation. Connecting the MCP to Claude takes a few minutes, and MCP 101 for legal teams explains what the protocol does.

If you are screening a person rather than building a product, the plain-English guide to checking court cases against any person or company walks through the manual route first.

Submit, poll, read: the integration in three calls

Call models at build time if you want to pin a version. Otherwise omit config.model entirely, because omitting it selects the current public model, and a hardcoded label will eventually be rejected. The one accepted id today is eCI-1.0, released 13 September 2026 against build 7.21.2. Earlier labels now return 400 UNKNOWN_MODEL, and that includes eCI-1.2, which the documentation carried until September. The numbering is not a typo and it does not run backwards: eCI-1.2 was an internal source-model label that the engine happened to echo, and eCI-1.0 is the first id in the public partner namespace. Which is exactly why you should read the models endpoint rather than reason about the version number.

# 1. Models. Free. Use only an id this endpoint returns.
curl "https://webapi.ecourtsindia.com/api/partner/legal-check/models" \
  -H "Authorization: Bearer eci_live_YOUR_TOKEN_HERE"

# 2. Submit. Charged once. Reuse the Idempotency-Key on a retry.
curl -X POST "https://webapi.ecourtsindia.com/api/partner/legal-check" \
  -H "Authorization: Bearer eci_live_YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: onboarding-88412-attempt-1" \
  -d '{
  "subject_type": "individual",
  "subject": {
    "name": "Siddharth Ashok Ahire",
    "father_name": "Ashok Ahire",
    "addresses": ["Ramabai Ambedkar Nagar, Ghatkopar East, Mumbai 400075"],
    "date_of_birth": "1991-01-01",
    "gender": "male"
  },
  "config": {
    "purpose": "employment",
    "client_ref_no": "ONBOARDING-88412"
  }
}'

# 3. Poll. Free. Honour Retry-After, which is 5 seconds while queued or running.
curl "https://webapi.ecourtsindia.com/api/partner/legal-check/LC-A1B2C3D" \
  -H "Authorization: Bearer eci_live_YOUR_TOKEN_HERE"

# 4. Report, only once status is completed. 409 NOT_READY means keep polling.
curl "https://webapi.ecourtsindia.com/api/partner/legal-check/LC-A1B2C3D/report?bands=confirmed,probable" \
  -H "Authorization: Bearer eci_live_YOUR_TOKEN_HERE"

# 5. What did it actually search? Free, and the question your reviewers will ask.
curl "https://webapi.ecourtsindia.com/api/partner/legal-check/LC-A1B2C3D/log" \
  -H "Authorization: Bearer eci_live_YOUR_TOKEN_HERE"

The 202 on submit carries data.code, a status_url, a report_url and an advisory estimated_seconds. Save the code. The URLs are relative paths.

Python

import time, requests

BASE = "https://webapi.ecourtsindia.com"
TOKEN = "eci_live_YOUR_TOKEN_HERE"


def legal_check(subject, client_ref, timeout_s=600):
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Accept": "application/json",
        "Content-Type": "application/json",
        # Built from your own reference, so a network retry replays
        # instead of billing you a second time.
        "Idempotency-Key": f"{client_ref}-v1",
    }

    # No config.model. Omitting it always selects the current public model.
    body = {
        "subject_type": "individual",
        "subject": subject,
        "config": {"purpose": "employment", "client_ref_no": client_ref},
    }

    submit = requests.post(f"{BASE}/api/partner/legal-check",
                           headers=headers, json=body, timeout=60)
    if submit.status_code == 429:
        raise RuntimeError("LEGAL_CHECK_QUEUE_FULL: three jobs already in flight")
    submit.raise_for_status()
    code = submit.json()["data"]["code"]

    deadline = time.time() + timeout_s
    while time.time() < deadline:
        poll = requests.get(f"{BASE}/api/partner/legal-check/{code}",
                            headers=headers, timeout=60)
        state = poll.json()["data"]
        if state["status"] in ("completed", "failed"):
            break
        time.sleep(int(poll.headers.get("Retry-After", "5")))
    else:
        raise TimeoutError(f"job {code} still running")

    if state["status"] != "completed":
        # SEARCH_UNAVAILABLE, LLM_UNAVAILABLE, MAX_RESTARTS, INTERNAL_ERROR.
        # All four are refunded once. Resubmit later under a FRESH key.
        raise RuntimeError(f"{code} failed: {state.get('error')}")

    report = requests.get(
        f"{BASE}/api/partner/legal-check/{code}/report",
        headers=headers,
        params={"bands": "confirmed,probable"},
        timeout=60,
    ).json()["data"]

    return code, report


code, report = legal_check(
    {
        "name": "Siddharth Ashok Ahire",
        "father_name": "Ashok Ahire",
        "addresses": ["Ramabai Ambedkar Nagar, Ghatkopar East, Mumbai 400075"],
        "date_of_birth": "1991-01-01",
    },
    "ONBOARDING-88412",
)

band5 = report["risk"]["band_5"]
verified = report["summary"]["verified_matches"]
screened = report["summary"]["records_screened"]

# The single most important branch in the whole integration.
if band5 == "UNRESOLVED":
    decision = "MANUAL_REVIEW"          # records exist, none attributable
elif verified == 0:
    decision = "CLEAR_ON_COVERAGE"      # nothing confirmed within stated coverage
else:
    decision = "REVIEW_WITH_EVIDENCE"

print(code, band5, f"{verified} verified of {screened} screened", decision)
print(report["engine"]["model"]["id"], report["engine"]["model"]["checksum"])

Node.js

const BASE = "https://webapi.ecourtsindia.com";
const H = {
  Authorization: `Bearer ${process.env.ECI_TOKEN}`,
  Accept: "application/json",
  "Content-Type": "application/json",
};

const sleep = (s) => new Promise((r) => setTimeout(r, s * 1000));

export async function legalCheck(subject, clientRef) {
  const submit = await fetch(`${BASE}/api/partner/legal-check`, {
    method: "POST",
    headers: { ...H, "Idempotency-Key": `${clientRef}-v1` },
    body: JSON.stringify({
      subject_type: "individual",
      subject,
      config: { purpose: "lending", client_ref_no: clientRef },
    }),
  });
  if (!submit.ok) throw new Error(`${submit.status} ${await submit.text()}`);
  const { code } = (await submit.json()).data;

  let state;
  for (;;) {
    const poll = await fetch(`${BASE}/api/partner/legal-check/${code}`, { headers: H });
    state = (await poll.json()).data;
    if (state.status === "completed" || state.status === "failed") break;
    await sleep(Number(poll.headers.get("Retry-After") ?? 5));
  }
  if (state.status !== "completed") throw new Error(`${code}: ${state.error}`);

  const res = await fetch(
    `${BASE}/api/partner/legal-check/${code}/report?bands=confirmed,probable`,
    { headers: H }
  );
  const report = (await res.json()).data;

  // Read band_5 and verified_matches, never a bare score.
  // A score of 0 means clean OR unresolved, and those need different handling.
  return {
    code,
    band: report.risk.band_5,
    unresolved: report.risk.band_5 === "UNRESOLVED",
    verified: report.summary.verified_matches,
    screened: report.summary.records_screened,
    model: report.engine.model.id,
    checksum: report.engine.model.checksum,
    report,
  };
}

Three things that code does deliberately. It never sends config.model, so it always gets the current model rather than a label that will be rejected in six months. It builds the idempotency key from your own reference, so a socket timeout replays instead of billing twice. And it stores engine.model.id and engine.model.checksum alongside the report, which is the only way to explain a year later why a rerun disagreed with the original.

Reading legal-check.v1 without getting it wrong

How to read a legal-check.v1 report: the six fields to wire first, the UNRESOLVED band that must never be read as clean, and the four adapter mistakes that cause real harm
The six fields to wire first, and the four mapping mistakes that do real damage. UNRESOLVED is the one that has to route to a human.

The report is bigger than most integrators expect, and the integration bugs we see almost all come from reading risk.score and ignoring the six blocks that qualify it.

The risk block publishes its own method

risk carries a numeric score, a three-way band such as AMBER, a five-way band_5 such as MEDIUM, a headline, a rationale array, a qualitative confidence and an identity_confidence out of 100. The part worth reading is the nested scoring object, because it states the method rather than asking you to trust the number.

"risk": {
  "score": 32,
  "band": "AMBER",
  "band_5": "MEDIUM",
  "headline": "MEDIUM risk. 5 verified matters.",
  "confidence": "high",
  "identity_confidence": 97,
  "scoring": {
    "method": "weighted roll-up of per-match risk_contribution, saturating, then clamped into the band window",
    "band_window": [25, 49],
    "score_uncalibrated": 32,
    "counted_matches": 2,
    "basis": "confirmed matters brought AGAINST the subject only",
    "context": { "ticket_size": null, "purpose": null }
  }
}

Read that basis line carefully, because it is a policy decision and not a technicality. Only confirmed matters brought against the subject count. Matters the subject filed do not. Procedure inside a matter already counted does not count twice. Probable and possible matches never move the rating at all. If your credit or hiring policy wants different arithmetic, you build it on matches[] and summary.by_role, not by arguing with the score.

The one band that will burn you

band_5: "UNRESOLVED" means records exist under this name and none of them could be attributed to your subject. It arrives with risk.score: 0.

It is not a clean result. If your onboarding maps a score to a traffic light, unresolved has to route to manual review. This is the single most consequential line in the schema and the one a careless adapter is most likely to flatten, because zero looks like green in every dashboard ever built. On the subject above, stripping the address from the submit is roughly how you would produce one: sixty-three records under the name, and nothing to say which of them is him.

summary.by_role, the block that changes underwriting

summary gives total_matches (which moves with your query parameters) alongside verified_matches and records_screened (which do not). It then slices the same set by by_band, by_status, by_nature, by_court_tier and by_category.

The one to wire first is by_role: against_subject, brought_by_subject, procedural and unknown. A person who has filed forty recovery suits and a person who has forty recovery suits filed against them are not the same risk, and a count-only court check hands you both as "40 cases found". Beside it sit serious_against_subject, moderate_against_subject, status_unverified, courts_covered, oldest_case_year, newest_activity, next_hearing_date and pending_matters.

Inside a match, and the field to build your reviewer screen around

Each element of matches[] is a full case record plus the engine's reasoning about it: cnr, case_number, case_type, cause_title, nature, the date series, a court object, judges, advocates, acts, sections, a parties object with per-party matched flags, and a counts object.

Use status_normalized, not status. The raw value is whatever the register wrote, and status_stale tells you when the register has not moved in a while. If a matter is load-bearing for your decision, refresh the CNR through the case API and look again.

The field to build your reviewer screen around is match_breakdown. It shows the working across name, father_name, address, dob and pan, each reading full, partial, close or not_provided. Put it next to the cause title and you have turned an argument about a name into a decision someone can defend. At verbosity=full each match also carries an engine object with a typed evidence trace, each item with a likelihood ratio, so a father's name appearing in a party string might carry lr: 400 while a locality match carries lr: 2.

The watchlist block says not_searched, and means it

The report carries a watchlist object with slots for sanctions, pep, adverse_media, warnings, willful_defaulter, mca_disqualified_director and an aml_total. On a court-record check every one of them returns status: "not_searched" with a note saying those sources are not part of this check.

The categories exist so an incumbent adapter maps cleanly. They are never silently reported as clear. If you are replacing a screening vendor whose payload populates these fields, do not let your mapping layer turn an empty array into a pass. Read watchlist.status first.

research_urls: the report hands your reviewer the public pages

Every match carries urls and research_urls, and you should prefer them over reconstructing links from the CNR. urls gives the case page, the latest order, the judgment, an enumerated orders[] list and a matching true_copies[] list of certified-copy PDFs. research_urls goes further: the subject's litigant page, a filtered pending-matters link, a "same subject in this court" link, directory pages for every party, advocate and judge on the matter, a court docket link, acts search links, and an upcoming-hearings cause-list search.

Every one of them is a public eCourtsIndia page that needs no API key. That is what makes the report droppable in front of a non-technical reviewer, an auditor, or the candidate themselves. It is also why every row in our worked example above is a link: you can check us.

engine.model and the search log

engine is the provenance of the decision rather than of the data. It carries the build version, an evaluation counter, coverage, stats (records found against records attributed), a limitations array, the verbosity and match_filter that produced this payload, and a search_log_url. Nested inside, engine.model publishes the frozen behaviour: id, namespace, status, release date, build range, base chain, amendments, a checksum, and a named list of gates.

Those gate names are the house rules of Indian identity matching, written down: score/mass-party-cannot-identify, score/same-dispute-is-one-source, score/one-dispute-counts-once, score/honorific-not-a-given-name, score/patronymic-stem, intake/electoral-epic-purity. You saw the first three do work in the funnel above.

And GET /api/partner/legal-check/{code}/log is a real endpoint that answers the question every due diligence team eventually asks, which is why did it not find the case I know about. It returns one entry per search actually run. Without it you are guessing at the query. With it you can see whether the name was searched at all, in which courts, and how many rows came back. It is free, it needs the job to be completed, and it wants a 120 second client timeout rather than the 60 you give everything else.

How this compares with the rest of the Indian BGV market

We read every Indian court-check product page we could find on 15 September 2026, re-read each one on 23 September 2026, and kept only statements that each vendor publishes about itself on its own site. Where we could not find something on a vendor's public pages, we say that, which is not the same as saying the vendor does not offer it. Several of these vendors sell far broader verification suites than a court check, and a sales conversation may tell you more than a product page does.

eCourtsIndia is not affiliated with, endorsed by or sponsored by any of the companies named in this section. Their names and trademarks belong to their owners and are used only to identify publicly described products. We have not tested their products, and nothing here is a statement about how any of them performs.

Summary of what seven Indian BGV court-check vendors published about themselves on their own pages in September 2026: no published prices, CNRs, named tribunals or versioned matching models found
Vendor claims are quoted from each vendor's own published page on 15 September 2026, not from our testing of their products.

What each of them says, in their own words

AuthBridge publishes the most detail of the group. Its Court Record Check page states "20 Cr+" case records drawn from "5000+ district courts, High Courts, Supreme Court, across 36 states/UTs, updated every 15 days", with "99% Verification Accuracy" and "90% Checks done in 1-5 days". Its three-step flow ends with "matched links for cases with probability score, petitioner details, IPC details, section details, manual QC to check for errors". The same page says it searches "court and tribunals databases in India". We did not find a published price, a CNR on the sample output, or a named tribunal.

IDfy's legal history checks page says it draws results from "a database of 24+ Crore court cases & 5+ Crore FIRs", so it publishes FIR coverage alongside court records, and it mentions "tribunal cases" without naming a specific tribunal. Its output is "an actionable risk score based on the number and the severity of the court cases found", with a "Crime Report" curated by its "legal/paralegal teams within 24 hours".

LegitQuest markets LIBIL as a litigation score over "500M+ Indian legal records" (its litigation check page) drawn from "over 10,000 Indian courts" (its criminal record check page), including "major tribunals" and FIR records, with the whole corpus "refreshed on an ongoing basis". It is notably transparent on one point that matters to us: it promises "source-linked reporting" that "traces every finding back to its underlying record for audit and defensibility", and it is candid about what the output is for, telling readers that "LIBIL® provides decision-support litigation intelligence based on structured public records. Findings should be reviewed by qualified legal or compliance professionals." Its criminal record check page gives a typical turnaround of "approximately 2 hours" for its detailed report, and its litigation check page says detailed reports come "typically within 2-4 hours".

OnGrid publishes an API reference for its criminal court record verification (CCRV) check on Stoplight, which is more than most vendors in this list make public. Its court record verification page states "over 20 Cr Criminal Records", "followed by audits for false positives and evidence", and "Verification in less than 4 hours".

SpringVerify publishes a clear statement of the limits of name matching, and it deserves credit for it. Its FAQ says court records do not always carry every identifying detail, that a father's name or address may be missing and spellings vary, and then: "When a possible match can't be conclusively confirmed or ruled out against the candidate, we grade it Inconclusive rather than guess, and route it through a Police Clearance Certificate to reach a definitive answer." That is the same principle our probable band rests on, with a different resolution path bolted to the end of it. It grades Clear, Flagged or Inconclusive, describes its automated check as covering "records since 2000 pan-India", and offers a separate law-firm product in which a lawyer physically visits the police station for the candidate's declared jurisdiction.

Surepass publishes a Court Record Verification API page. We did not find input fields, an output schema, a coverage number, a turnaround or a price on it. The page carries a disclaimer that "online court documents are not officially recognized as court records. They are available for educational purposes only and may contain errors or omissions."

Signzy: we could not find an India court-record check product on its public site when we looked on 23 September 2026. Its Criminal Screening API page describes "real-time background checks for US compliance", and its FAQ says the API "covers multiple jurisdictions worldwide". We include it only because it often appears in "best BGV API in India" lists; ask Signzy directly if you need an India court check from them.

Four things we could not find on any of their public pages

Set the marketing aside and four structural differences show up across the seven public pages we read.

A published price. We did not find a court-check rate card on any of these sites; pricing is quoted on request. Where a check is run jurisdiction by jurisdiction, the number of addresses searched tends to drive the cost more than the base rate does. Ours is ₹99 on Pay As You Go, ₹33 with a subscription, for a national check, published on the pricing page and repeated in the API guide.

A CNR on every match. None of the seven product pages we read mentions the Case Number Record. Without it your reviewer cannot open the matter, your auditor cannot reproduce the finding, and the candidate cannot dispute it. Every LegalCheck match carries one, plus a public link.

Named tribunals. LegitQuest says "major tribunals", IDfy says "tribunal cases" and AuthBridge says "court and tribunals databases", but none of the pages we read names a specific tribunal. For corporate and promoter screening that is the gap that matters most, because the deal-breaking signal usually sits in an insolvency or recovery forum rather than a criminal court. LegalCheck covers 18 tribunal families across 21 live court types, including NCLT and NCLAT, DRT and DRAT, ITAT, CESTAT, NGT, AFT, SAT, TDSAT, APTEL, CAT, CCI, GSTAT, RCT and the consumer commissions. The same list appears in the FAQ below, and it is the list the live court type enum returns.

A versioned matching model. Several of these vendors publish a score or a grade, and none of the product pages we read publishes the frozen behaviour that produced it. Without a frozen model, an old report can usually only be re-run under current logic, and a re-run that is wider than the original is not a reproduction. Every LegalCheck report carries engine.model.id, its release date, its named gate list and a checksum, and a released model is immutable.

One fair thing to say for the other vendors: most of them describe a human reviewer, paralegal, lawyer or quality check in the loop, and that is where their longer turnaround comes from. A lawyer visiting a police station finds things no index holds. If your workflow needs that, it is a real product and you should buy it. What makes sense is not to wait on analyst-scale turnaround for the part that is a database lookup. Run the API check first, and escalate the small number of matters that actually need a human.

Switching: a drop-in adapter from a legacy court check

On the seven vendor pages we read we found no rate card, openable case number, named tribunal or versioned matching model, while input fields are similar across the market so a migration is mostly a field rename
The market converged on the same five input fields years ago, which is why the input half of a migration is a rename.

Because the input fields converged across the market years ago, the adapter is mostly a rename. Here is the map from a typical legacy court-record payload.

Legacy fieldLegalCheck pathNote
name / candidateNamesubject.nameRequired. The only required field for an individual
fatherNamesubject.father_nameCompared by the stem of the given name, not by string equality
address, address2, permanentAddress, currentAddresssubject.addresses[]One array. Send every address you hold, they are evidence, not a filter
dob or agesubject.date_of_birth (YYYY-MM-DD)An approximate year still helps. Court metadata rarely carries a DOB
aliasName / alsoKnownAssubject.aliases[]Worth sending. The register spelled our worked subject three ways
companyName / cinNumber / gstNumber / directors[]subject.company_name / cin / gst / directors[]Set subject_type: "company"
clientRefNo / referenceIdconfig.client_ref_noExact-match filter on the list endpoint. Always set it
ticketSize / purposeconfig.ticket_size / config.purposeBusiness metadata, echoed back in risk.scoring.context
requestId for dedupeIdempotency-Key header1 to 255 characters. Same key plus a different body returns 409
riskType text bandrisk.band, risk.band_5, risk.scorePlus risk.scoring, which publishes the method
caseDetails[] with prose matchSummarymatches[] with match_breakdownStructured per-field agreement instead of a sentence
opaque internal case idmatches[].cnr plus urls.caseThe verifiable one. Give it to your reviewers
caseList with reason / remarksmatches[] plus coverage and limitationsWhat was not checked is in the payload, not missing from it
crime-watch / monitoring flagmonitoring.enabled, monitoring.monitor_idSlots are present. Ongoing monitoring surfaces here when it lands
The field map. The input half is a rename. The output half is where you gain fields rather than lose them.

The four mistakes people make in the adapter

Mapping an empty watchlist array to a pass. Your old vendor populated sanctions and pep. Ours returns them as not_searched because they are not part of a court-record check. An adapter that treats empty as clear has invented a screening result. Read watchlist.status.

Flattening UNRESOLVED into the score. Covered above, and worth repeating because it is the one that causes real harm. Zero is not clean.

Hardcoding config.model. Do not. Omit it. Pinning is for integrations that genuinely need frozen behaviour, and those should read the models endpoint at build time rather than carrying a string literal that gets rejected at the worst moment.

Counting total_matches as the finding. It moves with your query parameters. verified_matches and records_screened do not. If you are reporting a number to a credit committee, report those two together: eight verified out of sixty-three screened is a fact, and "63 cases found" is close to a lie.

Six industries, six different settings

The API is the same. What changes is which bands you act on, what you do with a probable, and where the human sits.

Lending and NBFC underwriting. Set config.purpose: "lending" and config.ticket_size to the sanction amount. Read summary.by_role before anything else: a promoter with forty recovery suits filed by him is a litigious counterparty, and a promoter with forty filed against him is a credit event waiting to be booked. Pull summary.pending_matters and next_hearing_date into the file, because a pending insolvency or recovery matter with a hearing next month is a different exposure from a disposed one from 2014. Use bands=confirmed,probable at sanction and let the credit officer see probables with the match_breakdown beside them.

Employment background verification. Set purpose: "employment". Most volume runs fine on verbosity=compact, which returns confirmed matches only, with an automatic escalation to full for anyone who lands confirmed or unresolved. This is also where the presumption of innocence has to be built into the product and not just the policy document: a pending criminal matter is an allegation. SpringVerify's own FAQ says it plainly, "Does a pending case automatically disqualify a candidate? No." Route every confirmed match to a human with the CNR link and let the candidate answer it. A national check at ₹99 means you can screen everyone rather than only the senior hires, which is the actual argument for the price.

Gig, mobility and marketplace onboarding. High volume, thin margins, real safety exposure, and a workforce that moves districts constantly. Any pricing that charges per address jurisdiction is exactly wrong here, because a delivery rider who has lived in three cities would cost you three checks. One national check costs one charge. Respect the three-concurrent-job cap, queue submissions, and drive your worker off status rather than the progress counters, which stay at zero until the job finishes.

Insurance underwriting and claims. Two different jobs from one endpoint. At underwriting, summary.by_nature separates criminal from civil, consumer and regulatory. At claims, the interesting slice is the subject's own consumer commission history and any motor accident claims tribunal record, which is by_court_tier plus by_role: brought_by_subject. A claimant with a pattern of consumer complaints is not fraud, but it is context an underwriter is entitled to have.

Vendor onboarding and KYB. Submit the entity with subject_type: "company", then submit each director separately, because the corporate veil is exactly the place a namesake problem becomes a group structure problem. Take the higher of the entity risk and the highest director risk. The audit value here is the coverage block: a procurement file that says what was searched and what was not will survive a review, and one that just says "clear" will not.

M&A, private equity and IPO diligence. Use verbosity=full and include=excluded. On a deal, an excluded record with a reason attached is worth as much as a confirmed one, because it tells your counsel that a scary-looking matter was considered and rejected rather than never seen. Store engine.model.id and the checksum against the report in the data room, so that when the same subject is re-run at signing you can say whether the records moved or the logic did.

What it costs

Every plan runs on one rate card with a multiplier. Pay As You Go is billed at about three times base. Enterprise pays base. New accounts get ₹200 in free credits and no card is required.

EndpointPay As You GoEnterprise
LegalCheck, per accepted job₹99₹33
LegalCheck status, report, list, models, logFreeFree
Case Search₹0.60₹0.20
Case Detail₹1.50₹0.50
Case Refresh₹0.15₹0.05
Order Download (PDF)₹3.75₹1.25
Order plus AI Summary₹7.50₹2.50
Electoral Roll Search / EPIC Lookup₹1.00₹0.35
Published rates before 18% GST, read from the eCourtsIndia rate card and API documentation on 15 September 2026. Some accounts run on negotiated rates, and the dashboard shows what actually applies to you.

The ratio worth internalising: a LegalCheck costs about what 165 case searches cost on the same plan. That is the whole decision about when to run a scored check and when to query the index yourself. If you are screening one subject properly, the scored check is cheap. If you are running a portfolio sweep across ten thousand known CNRs, you want case search and refresh, not ten thousand LegalChecks.

Compare the shape of it with the market. The vendors above quote prices on request, and AuthBridge's own page says "90% Checks done in 1-5 days". One national check, one charge, one to three minutes, free re-reads forever. The gap is not a discount, it is a different cost structure: much of a human-reviewed check's turnaround goes to analyst time, and ours runs on an index we already operate.

Limits, timeouts and the errors you will actually hit

Default ceilings are 100 requests a minute, 3,000 an hour, 50,000 a day, and 10 concurrent. Each returns its own code, so branch on RATE_LIMIT_CONCURRENT, RATE_LIMIT_MINUTE, RATE_LIMIT_HOUR and RATE_LIMIT_DAY rather than on a generic 429. A concurrency rejection clears in milliseconds. A daily rejection means stop until tomorrow. None of the four carries a Retry-After, so use your own backoff clock.

LegalCheck adds a cap of its own: at most three jobs queued or running per partner. A fourth submit returns 429 LEGAL_CHECK_QUEUE_FULL. Wait for one to finish. Do not rotate idempotency keys to get around it.

StatusCodeWhat to do
400VALIDATION_ERRORSend subject_type plus subject.name or subject.company_name
400UNKNOWN_MODELStop sending config.model, or send an id the models endpoint returns today
409NOT_READYThe job is still running. Keep polling and honour Retry-After
409IDEMPOTENCY_CONFLICTYou reused a key with a different body. Reuse only with identical JSON
409SEARCH_UNAVAILABLE, LLM_UNAVAILABLE, MAX_RESTARTS, INTERNAL_ERRORTerminal job failures, refunded once. You will usually meet these as the error field on a failed status rather than as an HTTP code. Record it and resubmit later under a fresh key
429LEGAL_CHECK_QUEUE_FULLThree jobs already in flight. Queue, do not retry harder
503LEGAL_CHECK_UNAVAILABLENew submits paused. Existing reads still work
404empty bodyThe code is not yours, or it is a typo. Those are deliberately indistinguishable. Do not probe
Handle these at the client layer, not in your business logic.

MAX_RESTARTS deserves a sentence of its own, because it is the honest one. It means the job could not complete within the retry limit, and in practice that usually means a very common name with nothing to separate it. It is the engine declining to guess rather than returning a plausible stranger. That is the behaviour you are buying.

On timeouts: give the LegalCheck reads 60 seconds and the search log 120. If you are also calling order endpoints elsewhere in your stack, give those 300, because any of them may be fetching and converting a scanned PDF from a government server on demand. A 30 second global default will time out on orders that would have succeeded and you will conclude the order is missing when it was merely slow.

What LegalCheck is not

  • Not a police clearance certificate, and not FIR clearance. It reads public court and tribunal records. FIR PDFs are a separate product: Crime Reports holds 12 lakh+ FIR PDFs from 13 states and union territories at ₹1 per PDF, and is not part of a LegalCheck report.
  • Not an identity certificate. Aadhaar, PAN and DigiLocker checks stay in your KYC stack. The electoral layer corroborates identity, it does not certify it.
  • Not AML, sanctions or PEP screening. The watchlist slots exist for adapter compatibility and always return not_searched.
  • Not proof of wrongdoing. Being named in a case establishes nothing. A person is presumed innocent unless convicted, and a human belongs in the loop before any adverse action.
  • Not a guarantee of completeness. Clear means nothing we could confirm from the available coverage and evidence. Every report carries a coverage statement naming what was searched and what was not, because a clean result is only as good as the boundary that was disclosed.

Data is processed on the basis of legitimate interest under the Digital Personal Data Protection Act, 2023. Correction and removal requests can be raised through the eCourtsIndia FAQs. This post is technical documentation and market comparison, not legal advice.

A name is not an identity, a case status is not a conclusion, a similarity score is not proof, and a background check should show you why it believes what it believes
Built to be checked, not trusted.

Run one

A name, a parent or spouse, a city or district, an age or year of birth. One POST, one job code, and a report you can hand to a reviewer with every finding linked to the public record it came from.

Get an API key → · Run a LegalCheck in the dashboard → · Full endpoint reference →

A name is not an identity. A case status is not a legal conclusion. A similarity score is not proof. And a background check API should not just tell you what it found. It should show you why it believes it, and where it refused to guess.

Frequently asked questions

What is the LegalCheck API?

LegalCheck is eCourtsIndia's court-record background check API for India. You submit a person or a company, poll an asynchronous job, and read a legal-check.v1 report with a risk band, an identity confidence and every matching court record with its CNR and a public link. It runs on a live index of 32 crore+ case records covering the Supreme Court, all 25 High Courts, district and taluka courts, and 18 tribunal and commission types.

How much does a court record check API cost in India?

None of the Indian court-check vendors we reviewed publishes a rate card; prices are quoted on request. LegalCheck publishes its price: Rs 99 per accepted job on Pay As You Go, or Rs 33 with an active subscription, for a national check, before GST. Status, report, list, models and search-log reads are free, however often you call them. New API accounts get Rs 200 in free credits. See the eCourtsIndia API page.

How long does a LegalCheck API call take?

Most first reports are ready in one to three minutes. Submit returns 202 immediately with an advisory estimated_seconds value, then you poll a free status endpoint, honouring a Retry-After of 5 seconds. A difficult common name takes longer, because a single check can score several hundred candidate records individually and run dozens of separate register searches before anything is printed.

Can I switch from another BGV vendor without rewriting my integration?

The input half is usually a field rename, because Indian court checks all rely on the same few fields: name, father's name, address, age or date of birth, and aliases. On the output side, do not map an empty watchlist array to a pass, do not flatten band_5 UNRESOLVED into a clean score, and read verified_matches rather than total_matches. The full field map is in the migration table above.

What does UNRESOLVED mean in a LegalCheck report?

It means records exist under that name and none of them could be attributed to your subject. It ships with risk.score 0, and that zero must not be read as clean. Route UNRESOLVED to manual review, never to an automatic pass. The unresolved rows carry the fields that would settle them, such as parent or spouse names in the party strings, age, court district, co-parties and counsel.

Does a LegalCheck match prove the person did something wrong?

No. A match is a public court record plus a probabilistic identity judgement. Being named in a case establishes nothing, a person is presumed innocent unless convicted, and a human reviewer belongs in the loop before any adverse action. The report says this in its own words, and the disclaimer is part of the result rather than boilerplate to strip on ingest.

Why did a name search return 63 records but only 9 belong to the subject?

Because 63 was a string match and 9 is a person, whose nine records cover eight distinct disputes. In the worked example, three Mumbai rows were mass-party cause titles where the search words came from different people, two were one prosecution counted twice, and the rest failed on geography. Each subtraction is a named precision gate published in engine.model.gates, and none of them can raise a score.

Does LegalCheck cover tribunals like NCLT, DRT or ITAT?

Yes. It covers 18 tribunal and commission types, including NCLT, NCLAT, ITAT, CESTAT, DRT, DRAT, NGT, AFT, SAT, TDSAT, APTEL, CAT, CCI, GSTAT, RCT and the consumer commissions. For promoter, director and counterparty screening this is usually where the deal-breaking signal sits. You can also search them yourself, as in the NCLT and NCLAT guide.

Does the LegalCheck API cover FIRs, sanctions or PEP lists?

Not today. It is a court-record check. The report carries a watchlist block with slots for sanctions, PEP, adverse media, wilful defaulter and MCA disqualified director so an existing adapter maps cleanly, but those return not_searched and are never reported as clear. FIR PDFs are a separate eCourtsIndia product, Crime Reports, covering 13 states and union territories.

Can an old LegalCheck report be reproduced later?

Yes, and that is why you should store engine.model.id and engine.model.checksum with every report you keep. A released model is frozen, and a threshold change creates a new model rather than silently changing an old one. When two reports on the same subject disagree, compare engine.model.id first. If the model is the same, the court records moved. If it is not, the logic did.

How do I find out what the engine actually searched?

Call GET /api/partner/legal-check/{code}/log. It is free, it returns one entry per search actually run, and it is how you answer why the check did not find a case you know about, without guessing. It needs the job to be completed, a failed job returns its terminal error code instead of a log, and it wants a 120 second client timeout.

Is LegalCheck available over MCP for AI agents?

Yes, since version 4.46 of the eCourtsIndia MCP server. submit_legal_check runs the check on a person or company and costs Rs 99, or Rs 33 on an active subscription, once on acceptance. get_legal_check is free and returns the risk band, summary and matched cases. The Claude connection guide shows the setup in a few minutes.

Sources and method

  • Index and worked example. Every court and elector count on this page was read live from the eCourtsIndia index on 15 September 2026 through the partner case search and electoral search endpoints. Total records 29,20,09,980. Litigant searches: Siddharth 74,387; Ahire 49,282; Siddharth Ahire 233, of which the state facet assigns 223 to Maharashtra, 3 to Gujarat, 2 to Madhya Pradesh and 1 to Punjab, and the tier facet assigns 212 to district and taluka courts, 14 to High Courts, 4 to the Supreme Court and 1 to a tribunal; Siddharth Ashok Ahire 63, of which the state facet assigns 58 to Maharashtra and 1 to Gujarat; the same query scoped to Mumbai's two court district codes, 12. Facet counts do not sum to their totals because a share of records carry no state or court-level assignment; we report the facets as the index returns them rather than closing the gap. Electoral roll: Siddharth Ahire in Maharashtra 446 persons; the same name with a father named Ashok, searched nationally with fuzzy matching, 8 persons, of which 2 scored 100 and are recorded at age 33 on the 2024 roll. These are live figures and they drift: the two large litigant counts had already moved by low double digits within hours of being read.
  • Court matters. The eight disputes listed are public records on eCourtsIndia, each linked by CNR. Statuses and next hearing dates are as at 15 September 2026 and move. Party spellings are reproduced exactly as the register wrote them. No conviction is asserted against any person named.
  • What we did not publish. EPIC numbers, roll part numbers and serial numbers for the individual concerned are in the API response and are not reproduced here.
  • Engine and API facts. Endpoint list, model id eCI-1.0 on build 7.21.2, the legal-check.v1 schema, the rate card, rate limits, timeouts and error codes were verified against the deployed build and the published API documentation on 15 September 2026, and are set out in full in the eCourtsIndia API guide.
  • Competitor claims. Every vendor statement is quoted from that vendor's own public product page, read on 15 September 2026 and re-read on 23 September 2026: AuthBridge Court Record Check, IDfy background verification and legal history checks, LegitQuest LIBIL litigation check and criminal record check, OnGrid court record verification and its published Stoplight API reference, SpringVerify India court record check, Surepass court record verification, Signzy criminal screening. We have not tested any competitor product and make no claim about how any of them performs. Statements we could not find again on 23 September 2026 (an IDfy "23 Cr+" figure, specific OnGrid field names and a Signzy data-source list) were removed. Gridlines is excluded because its court product page no longer resolves. eCourtsIndia is not affiliated with any vendor named. Vendors who believe a statement here is out of date can write to us through the eCourtsIndia FAQs page and we will correct it.
  • Market pricing. No Indian court-check vendor we found publishes a price. An unsourced third-party price range quoted in the first version of this post has been removed.
  • MCP. The LegalCheck MCP tools, their prices and the 39-tool count were read from mcp.ecourtsindia.com (health endpoint and llms.txt, server version 4.46) on 23 September 2026. The current index size, 32 crore+, was read on the same date.
  • Figures are a dated snapshot of a live system, not a service level commitment. Where a source states a limitation, this post preserves it rather than turning it into a stronger claim.

Read next

eCourtsIndia is a private legal-technology platform. It is not affiliated with, associated with, or endorsed by the Government of India, the Supreme Court of India or its e-Committee, or any court. Official case information is published on ecourts.gov.in. Always verify details against official court records or certified copies. This article is general information, not legal advice. Spotted an error? Write to support@ecourtsindia.com.

Search 32 crore+ Indian court case records, free

One search across the Supreme Court, all 25 High Courts, district courts and 18 tribunal and commission types. Hearing alerts, AI summaries and an API for developers.