Screen a name against the corpus with confidence scored matches, single or batched, priced by outcome rather than as a flat rate.
Litigation check: screen a person or company name against the corpus and get back a confidence-scored report of the cases that plausibly involve them. Retrieval runs against the same deterministic entity-resolution layer CourtMesh's own counterparty screening uses (server/services/entity-resolution/). A screen that finds matches is priced like an analysis call, at ₹10.00; a genuine no match is priced far lower, at ₹2.00, since it did the same retrieval work but produced no analysis. Requesting adjudicate=true asks for an LLM pass over the uncertain middle; the ₹8.00 surcharge is only added on top of either price when that pass actually ran at least once, not merely for setting the flag. The flag is also not available on the Free tier: sending adjudicate=true on Free returns HTTP 403 (API_TIER_NOT_ALLOWED).
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | Yes | The person or company name to screen. Between 2 and 200 characters. |
| aliases | string[] | No | Alternate spellings or former names to screen alongside name. At most 7 entries: name plus its aliases must fit within the 8 name screening limit. |
| entityType | "person" | "company" | Yes | Which entity-resolution rules apply. A person can never be auto-confirmed on name similarity alone; confirmation requires a matched statutory identifier. A company can be auto-confirmed once its name similarity clears the confirmed band. |
| purpose | enum | Yes | One of kyc, bgv, due_diligence, litigation, research, compliance. Required under DPDP: we will not process a searched name without a stated reason. Never logged, but recorded in the audit trail for this call. |
| identifiers | object | No | pan, gstin, cin, llpin. Each is format-validated at the edge; a malformed value is rejected with HTTP 400 rather than silently ignored, since a caller-supplied typo should surface as an error, not a false no-match. An exact identifier match on a candidate case is treated as decisive without needing the LLM pass. |
| address | object | No | city, state, stateCode. Used as a corroborating signal, never as a filter. |
| knownPersons | string[] | No | Up to 10 known associates, directors or family members. A candidate case naming one of these is a disambiguating signal, especially for a common person name. |
| court | string | string[] | No | Scope the screen to one court, as a string or a single-element array. An array with more than one entry is rejected with HTTP 400 ("one court per request for now"). |
| since | string | No | YYYY-MM-DD. Must parse as a real calendar date, or the request is rejected with HTTP 400. Drops a candidate only when it carries a decision or filing date strictly before the cutoff; a candidate with neither date is kept rather than silently dropped. |
| limit | number | No | Candidates considered, default 40, maximum 100, clamped further by your tier's maxPageSize. |
| adjudicate | boolean | No | Default false. Sends the uncertain middle (survived the name-similarity floor but not already decided by an exact identifier match or conflict) to an LLM pass, capped at 40 candidates. Adds the adjudication surcharge to the price of this call. |
| displayThreshold | number | No | 0 to 1, default 0.6. A candidate below this calibrated probability is left out of matches unless its band is confirmed, in which case it always shows regardless of the threshold. |
Each match carries a calibrated score bucketed into a band: confirmed at 0.90 and above, probable at 0.70 and above, possible at 0.45 and above, and unlikely below that. A person is never auto-confirmed on name similarity alone: confirmation for a person requires a matched statutory identifier (PAN, GSTIN, CIN or LLPIN). An address or a known associated person raises confidence but on its own caps the result at probable, no matter how close the name spelling is. A company can be auto-confirmed on name similarity alone.
summary.verdict reads no_matches_found only when the underlying retrieval was actually exhaustive (coverage.exhaustive or coverage.exhaustiveWithinFilters). A plan clamp, a strategy error, or any other non-exhaustive run reports inconclusive instead. This endpoint never reports an absolute negative it cannot back up. A since filter, or a restricted record withheld with nothing else left to report, also forces inconclusive even on an otherwise exhaustive run. Separately, coverage.someRecordsWithheld is a boolean, not a count or a list: a case can be withheld because it is marked restricted or carries a registry masking token, and this field only tells you whether that happened, never which case or why.
POST /search/cases and POST /search/cases/semantic silently drop any key their schema does not recognise. This endpoint does the opposite: the request body is parsed strictly, and an unrecognised top-level field is rejected with HTTP 400 rather than being ignored.
curl -X POST https://research.courtmesh.ai/api/v1/prod/party/screen \
-H "X-API-Key: cm-YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"name": "Northwind Traders Private Limited",
"entityType": "company",
"purpose": "due_diligence",
"identifiers": { "cin": "U74999DL2015PTC123456" },
"address": { "city": "Delhi", "state": "Delhi", "stateCode": "DL" },
"limit": 40,
"adjudicate": true
}'court sent as an array with more than one entry (one court per request for now), since that does not parse as a real calendar date, or a request body carrying an unrecognised top-level field.required, balance and shortfall, plus a topUpUrl. The pre-flight check reserves against the maximum this call could cost (match price plus the adjudication surcharge), so a balance that cannot cover the worst case is refused before any work starts.adjudicate=true on the Free tier (code API_TIER_NOT_ALLOWED), or a monthly party screen cap already reached (Free Developer allows 10 per month, code PARTY_SCREEN_LIMIT_REACHED).RATE_LIMITED, and a distinct-names-per-day cap (Free 25, Pay As You Go 500, Scale 5,000, Enterprise unlimited), code DISTINCT_NAMES_LIMIT_REACHED. Re-screening a name you already screened today does not count against the distinct names cap. Both carry a Retry-After header.purpose is mandatory on every call. DPDP requires stating why a named person is being screened before we process the name, and your stated purpose is stored in this call's audit log alongside entityType, name length and match count, purely for accountability. The searched name itself, its aliases, identifiers, address and known persons are never written to any log: only lengths and counts are, the same discipline the internal party search this endpoint is built on already follows.
Every result is drawn from public court records, which are subject to correction and removal. A party can ask for a case to be withheld from search under CourtMesh's case removal policy, and this endpoint honours that the same way every case-by-id endpoint does: a withheld case is dropped from the response and only the boolean coverage.someRecordsWithheld says so.
Screens up to 25 names in one call, for onboarding a batch of customers or counterparties in one pass rather than 25 round trips. Pricing is per item on the exact schedule as the single endpoint: a matched item costs ₹10.00, a genuine no match costs ₹2.00. There is no adjudication pass here: adjudicate must be false or omitted, so send individual POST /party/screen calls for a name that needs the LLM pass. Not available on the Free tier at all (HTTP 403, API_TIER_NOT_ALLOWED).
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
| items | array | Yes | 1 to 25 items. Each item takes the same fields as a single POST /party/screen call: name (required), and the optional clientRef, aliases, entityType, identifiers, address, knownPersons, court, since, limit and displayThreshold. |
| items[].clientRef | string | No | Your own identifier for this item, echoed back on its result so you can match responses to requests without relying on array order. |
| items[].name | string | Yes | The person or company name to screen. Same 2 to 200 character rule as the single endpoint. |
| purpose | enum | Yes | Top level, applies to every item in the batch. Same six values as the single endpoint; still mandatory under DPDP. |
| entityType | "person" | "company" | No | Top level default applied to any item that does not set its own entityType. An item may still override it. |
| adjudicate | boolean | No | Must be false, or omitted. The batch endpoint does not run the LLM adjudication pass; send single POST /party/screen calls for names that need it. |
A malformed item (a bad identifier, an unresolvable name) never fails the whole batch. Its result carries ok: false with an error object, every other item is still screened, and only the items that actually completed are counted toward meta.creditsCharged. clientRef and index are both present on every result so you can line results up with the request even when some are dropped for exceeding the distinct-names cap, reported as meta.truncated and meta.truncatedReason.
curl -X POST https://research.courtmesh.ai/api/v1/prod/party/screen/batch \
-H "X-API-Key: cm-YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: onboarding-2026-09-18-run-1" \
-d '{
"purpose": "kyc",
"entityType": "company",
"adjudicate": false,
"items": [
{ "clientRef": "cust-1042", "name": "Northwind Traders Private Limited", "identifiers": { "cin": "U74999DL2015PTC123456" } },
{ "clientRef": "cust-1043", "name": "Rambaksh Enterprises" }
]
}'API_TIER_NOT_ALLOWED on the Free tier, or PARTY_SCREEN_LIMIT_REACHED when your remaining monthly allowance is short of what the batch needs; the whole batch is refused before any item runs, never a partial charge.Idempotency-Key conflict, see the Idempotency section below.