DevelopersDocsGuides

Litigation check for lenders

Check a borrower or guarantor for court cases before you lend. Order the report, wait for the webhook, read the matches and keep the PDF.

A lender wants to know, before sanctioning a loan, whether the borrower or a guarantor is a party in a court case: a cheque-bounce complaint, a recovery suit, an insolvency petition. This guide builds that check with the reports API. It takes one call to order, and one webhook to learn it is ready.

You will:

  1. Get the person's consent and the details you need.
  2. Order a litigation_check.
  3. Receive report.completed on a webhook.
  4. Read the matches, and keep the PDF as your record.

Build and test with a test key. The sandbox party Sandbox Lender Finance Ltd always returns the same fixed set of cases, so your tests are stable. See sandbox.

#1. Before you call

  • Take the person's consent. A name check is personal data under the Digital Personal Data Protection Act, 2023. Record that the borrower agreed to the check, and what it is for.
  • Collect the name as it is in the loan form, and the father's name for a person, or the CIN for a company. These are the strongest ways to tell two parties of the same name apart. A State and district narrow it further.
  • Paid accounts only for live name checks. Searching a person by name needs an account that has paid at least once. See errors.
  • It is public court records only. The report is not a police verification and not a credit score.

#2. Order the report

curl -X POST https://adv.heliosynctech.com/api/v1/reports \
  -H "Authorization: Bearer $AOS_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "type": "litigation_check",
    "subject": { "kind": "company", "name": "Sandbox Lender Finance Ltd", "state": "Delhi" }
  }'
import { randomUUID } from "node:crypto";

export async function orderCheck(subject: Record<string, string>) {
  const res = await fetch(`${process.env.AOS_API_BASE}/reports`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AOS_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": randomUUID(),
    },
    body: JSON.stringify({ type: "litigation_check", subject: { kind: "person", ...subject } }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.error.doc_url})`);
  return body as { id: string; status: string };
}
import os, uuid, requests

def order_check(**subject):
    res = requests.post(
        f"{os.environ['AOS_API_BASE']}/reports",
        headers={"Authorization": f"Bearer {os.environ['AOS_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
        json={"type": "litigation_check", "subject": {"kind": "person", **subject}},
        timeout=30,
    )
    body = res.json()
    if not res.ok:
        e = body["error"]
        raise RuntimeError(f"{e['code']}: {e['message']} ({e['doc_url']})")
    return body  # {"id": "rpt_…", "status": "queued", …}

Save the report id against the loan application. The report is not ready yet: its status is queued. The price is charged when it completes, ₹79, then ₹59 from 1,000 a month, ₹45 from 10,000 a month; a failed report is free.

#3. Wait for the webhook

Do not poll in a loop. Register a webhook endpoint once, for report.completed:

curl -X POST https://adv.heliosynctech.com/api/v1/webhook-endpoints \
  -H "Authorization: Bearer $AOS_KEY" -H "Content-Type: application/json" \
  -d '{ "url": "https://lender.example.com/hooks/aos", "events": ["report.completed"] }'

Your handler verifies the signature, then loads the report:

app.post("/hooks/aos", express.raw({ type: "application/json" }), async (req, res) => {
  const event = verify(req.body.toString("utf8"), req.header("AOS-Signature") ?? "", process.env.AOS_WEBHOOK_SECRET!);
  res.sendStatus(200); // reply first; do the work after
  if (event.type !== "report.completed") return;
  await handleReport(event.data.report.id); // report.failed carries the same report; it was free, so order again
});

The verify function is on the webhooks page. Run it in the sandbox first: with a test key the report runs on sandbox parties, and report.completed goes to your test endpoint. Use aos listen to receive it on localhost.

#4. Read the matches

curl https://adv.heliosynctech.com/api/v1/reports/rpt_3cJ8vNd5Qw2TzXa7Uf4LbYh9 -H "Authorization: Bearer $AOS_KEY"
{
  "status": "completed",
  "summary": {
    "cases_found": 5, "possible_matches": 0,
    "by_risk": { "protected": 0, "ibc": 0, "sarfaesi": 0, "drt": 0, "cheque_bounce": 0, "criminal": 0, "consumer": 0, "recovery": 5, "other": 0 },
    "by_confidence": { "high": 5, "medium": 0, "low": 0 }
  },
  "hits": [
    {
      "forum": "sandbox_high_court", "court": "Sandbox High Court, North Bench", "case_number": "CS(COMM) 5131/2026", "cnr": "SBXX010001012026",
      "role": "petitioner", "status": "pending", "next_date": "2026-12-18", "risk": "recovery", "protected": false,
      "match": { "confidence": "high", "score": 95, "reasons": ["exact name"], "corroborated": false }
    }
  ]
}

(Shortened. The whole report is in reports.)

  • match.confidence is high from a score of 90, medium from 70 and low from 50. match.corroborated is true when the father's name, CIN, state or district also agrees. A high match that is corroborated is strong; a low one is a lead: confirm it before you act. summary.possible_matches counts the low ones.
  • risk sorts the hits, most serious first: protected, ibc, sarfaesi, drt, cheque_bounce, criminal, consumer, recovery, other. A pending recovery suit in which the borrower is the respondent matters more to a credit officer than a disposed one (role and status tell you). Your credit policy decides what to do; the report only tells you what exists.
  • A report with cases_found: 0 is a finished check that found nothing. It is still charged, because the search was done.
  • If summary.truncated is true, the name is very common: add the father's name, CIN, state or district and order again.
  • For any case you need to look at, read it: GET /cases/{cnr}. Its next date and orders are there.
  • Cases in protected categories are masked, so some names will be hidden.

#5. Keep the record

Download the PDF and store it with the loan file:

curl https://adv.heliosynctech.com/api/v1/reports/rpt_3cJ8vNd5Qw2TzXa7Uf4LbYh9/pdf -H "Authorization: Bearer $AOS_KEY" -o litigation-check.pdf

The PDF carries a QR code. Anyone you show it to (an auditor, a regulator) can scan it to confirm it is genuine and unchanged.

#Things to get right

  • Do not refuse a loan on a name match alone. Tell the applicant what you found and let them answer.
  • Send an Idempotency-Key, so a retry does not order, and pay for, a second report.
  • Re-check before disbursal for large loans: cases are filed every day. For a long-running exposure, watch the party and get party.new_case.
  • Every name you search is logged in the audit trail of the platform.

For checking a borrower you already have as a case, see court data.