Litigation Watchlist API
API For Continuous Litigation Monitoring Of Companies And Individuals In India
The Litigation Watchlist API lets you add companies and individuals to a watchlist and have CasePrimus.ai check Indian courts and tribunals for new cases against them every day. Built for procurement, vendor-risk, lending, compliance and M&A teams, and for the systems that serve them, it replaces manual searches of court portals with continuous, automated monitoring.
Each new case is found, its orders are read and summarized by AI, and the entity's risk and reputation score is updated. You can search the entities and cases on your watchlist through the API, and receive alerts at your own endpoint through signed webhooks the moment something changes.
Built on certified infrastructure
CasePrimus.ai is operated by Pegadroid IQ Solutions Private Limited, the legal entity behind Attestr's products, which holds ISO/IEC 27001:2022 certification. Data is hosted in India (AWS Mumbai, ap-south-1) and every connection is encrypted in transit. See Trust & Compliance.
Key capabilities
Daily court monitoring
Every hearing, order and new case is checked daily against your whole watchlist, including weekends and Indian public holidays.
Companies and individuals
Monitor BUSINESS and PERSON entities. Add a registration number and address, or a father's name and date of birth, to sharpen matching.
Coverage across Indian courts
The Supreme Court, High Courts, District Courts, Consumer Commissions and tribunals including NCLT, NCLAT, DRT, DRAT, GSTAT and CESTAT.
AI name variations
For companies, AI generates likely spellings of the name to search for, so a case filed under a variant spelling is not missed.
Historical lookup on add
Optionally run a one-time historical lookup when you add a company, so cases filed before you started monitoring are found from day one.
AI summaries and risk scoring
Every order is read and summarized by AI, and the entity's reputation score updates as its cases change.
Webhooks for every change
Push new cases, hearing changes, refreshed summaries and risk-level moves to your own endpoint, signed and retried automatically.
How it works
- 1
Add an entity
Send a company or a person to
POST /watchlist/entities. You do this once. - 2
We search Indian courts every day
CasePrimus.ai checks courts and tribunals across India for new cases, hearings and orders.
- 3
AI reads and scores
Each order is read and summarized, and the entity's risk and reputation score is updated.
- 4
You get alerted
Alerts appear in your dashboard, and are pushed to your endpoint by webhook.
API definition
Add entity to watchlist
Adds a company or person to the account's watchlist. For a BUSINESS entity, this also generates AI name variations to search for (best-effort, it never blocks the response) and, if fetchHistoricalCases is true, starts a one-time historical court-case lookup across our verification data partners. The lookup runs in the background: results arrive later as candidates on the entity, and the entity.historical_scan_completed webhook tells you when it has finished. Requires watchlist.write.
Request URL
https://api.caseprimus.ai/api/caseprimus/v1/watchlist/entitiesRequest headers
| Type | Name | Value / description | Optional |
|---|---|---|---|
| String | Content-Type | application/json | Required |
| String | X-CasePrimus-Api-Key | Your API key: {apiKey} | Required |
No API key yet? See Authentication.
Input parameters
| Field | Description |
|---|---|
namestring Required | The legal name of the company, or the full name of the person. 2 to 255 characters |
entityTypeenum Required | Whether the entity is a company (BUSINESS) or a person (PERSON). PERSONBUSINESS |
fatherNamestring or null Optional | PERSON entities only - ignored for BUSINESS. up to 256 characters |
birthDatestring or null Optional | DD-MM-YYYY. PERSON entities only - ignored for BUSINESS. |
locationstring or null Optional | Free-text address. up to 4192 characters |
registrationNumberstring or null Optional | The company's registration number, if you have it. It helps matching. up to 50 characters |
monitoredCourtsarray of enum Optional | 'ALL' must be the sole entry if used - cannot combine with specific court codes. Recorded with the entity. Monitoring is not currently restricted by this value. at least 1 item ALLDCSCHCCCNCLTNCLATGSTATDRTDRATCESTAT |
sharedWitharray of object Optional | Teams or users the entity is shared with. |
typeenum Required | teamuser |
idstring Required | A team ID when type is 'team', a user ID otherwise. |
fetchHistoricalCasesboolean Optional | One-time historical case lookup, fired asynchronously right after creation. BUSINESS entities only - silently a no-op for PERSON. |
Sample request
BASE="https://api.caseprimus.ai/api/caseprimus/v1" curl -X POST "$BASE/watchlist/entities" \ -H "X-CasePrimus-Api-Key: $CASEPRIMUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Traders Pvt Ltd", "entityType": "BUSINESS", "monitoredCourts": [ "ALL" ], "fetchHistoricalCases": false }'
const BASE = "https://api.caseprimus.ai/api/caseprimus/v1"; const res = await fetch(BASE + "/watchlist/entities", { method: "POST", headers: { "Content-Type": "application/json", "X-CasePrimus-Api-Key": process.env.CASEPRIMUS_API_KEY, }, body: JSON.stringify({ "name": "Acme Traders Pvt Ltd", "entityType": "BUSINESS", "monitoredCourts": [ "ALL" ], "fetchHistoricalCases": false }), }); const data = await res.json();
import os import requests BASE = "https://api.caseprimus.ai/api/caseprimus/v1" res = requests.request( "POST", BASE + "/watchlist/entities", headers={"X-CasePrimus-Api-Key": os.environ["CASEPRIMUS_API_KEY"]}, json={ "name": "Acme Traders Pvt Ltd", "entityType": "BUSINESS", "monitoredCourts": ["ALL"], "fetchHistoricalCases": False, }, ) data = res.json()
Responses
| 200 | Entity created. |
| 400 | Malformed input. |
| 401 | Missing/invalid/expired access token. |
| 403 | Caller lacks the watchlist.write permission. |
Response fields (HTTP 200)
| Field | Description |
|---|---|
_idstring | The id of the new entity. |
{
"_id": "CPWLE0exampledemo0001"
}Search watchlist entities
Searches the watchlist entities you can see: those in your account and those shared with you. Archived entities are not returned. Use $filter for exact matches (for example status), $like for case-insensitive substring matches on a field such as name, $sort to order the results, and $skip with $limit (up to 100) to page through them. Requires watchlist.read.
Request URL
https://api.caseprimus.ai/api/caseprimus/v1/watchlist/entities/searchRequest headers
| Type | Name | Value / description | Optional |
|---|---|---|---|
| String | Content-Type | application/json | Required |
| String | X-CasePrimus-Api-Key | Your API key: {apiKey} | Required |
No API key yet? See Authentication.
Input parameters
| Field | Description |
|---|---|
$filterobject (free-form) Optional | Exact-match field filters, e.g. {"status": "ACTIVE"}. |
$likeobject (free-form) Optional | Case-insensitive substring filters, e.g. {"name": "trip"}. |
$skipinteger Optional | minimum 0 |
$sortobject (free-form) Optional | Field to +1/-1 (ascending/descending), e.g. {"created": -1}. |
$limitinteger Optional | 0 to 100 |
Sample request
BASE="https://api.caseprimus.ai/api/caseprimus/v1" curl -X POST "$BASE/watchlist/entities/search" \ -H "X-CasePrimus-Api-Key: $CASEPRIMUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "$filter": {}, "$skip": 0, "$limit": 10 }'
const BASE = "https://api.caseprimus.ai/api/caseprimus/v1"; const res = await fetch(BASE + "/watchlist/entities/search", { method: "POST", headers: { "Content-Type": "application/json", "X-CasePrimus-Api-Key": process.env.CASEPRIMUS_API_KEY, }, body: JSON.stringify({ "$filter": {}, "$skip": 0, "$limit": 10 }), }); const data = await res.json();
import os import requests BASE = "https://api.caseprimus.ai/api/caseprimus/v1" res = requests.request( "POST", BASE + "/watchlist/entities/search", headers={"X-CasePrimus-Api-Key": os.environ["CASEPRIMUS_API_KEY"]}, json={ "$filter": {}, "$skip": 0, "$limit": 10, }, ) data = res.json()
Responses
| 200 | Matching entities. |
| 403 | Caller lacks the watchlist.read permission. |
Response fields (HTTP 200)
| Field | Description |
|---|---|
recordsFilteredinteger | Total matching records, ignoring $skip/$limit. |
recordsarray of object | The matching entities on this page. |
_idstring | The entity's id. |
numberinteger | |
accountIdstring | Your account's id. |
namestring | The entity's name. |
entityTypeenum | PERSONBUSINESS |
fatherNamestring or null | As provided when the entity was added. People only. |
birthDatestring or null | As provided when the entity was added. People only. |
locationstring or null | As provided when the entity was added. |
registrationNumberstring or null | As provided when the entity was added. |
monitoredCourtsarray of string | The courts selected when the entity was added. |
statusenum | ACTIVEPAUSEDARCHIVED |
nameVariationsarray of string | AI-generated alternate spellings/forms of the company name, used to widen court-record name matching. Empty for PERSON entities. |
lastCourtSyncAtinteger (int64) or null | When the daily/on-demand court-record search last ran for this entity. |
sharedWitharray of object | Teams or users the entity is shared with. |
createdinteger (int64) | When the entity was created, in milliseconds since the Unix epoch. |
createdBystring | |
updatedinteger (int64) or null | When the entity was last updated, in milliseconds since the Unix epoch. |
updatedBystring or null |
{
"recordsFiltered": 1,
"records": [
{
"_id": "CPWLE0exampledemo0001",
"number": 100001,
"accountId": "CPA0exampledemo0001",
"name": "Acme Traders Pvt Ltd",
"entityType": "BUSINESS",
"fatherName": null,
"birthDate": null,
"location": "Mumbai, Maharashtra",
"registrationNumber": "U12345MH2015PTC100001",
"monitoredCourts": [
"ALL"
],
"status": "ACTIVE",
"nameVariations": [],
"lastCourtSyncAt": 1757500000000,
"sharedWith": [],
"created": 1757000000000,
"createdBy": "CPU0exampledemo0001",
"updated": null,
"updatedBy": null
}
]
}{
"recordsFiltered": 0,
"records": []
}Search watchlist cases
Searches the cases you can see: those in your account and those shared with you. Archived cases are not returned. It uses the same search envelope as the other search endpoints: $filter for exact matches, $like for case-insensitive substring matches, $sort to order the results, and $skip with $limit (up to 100) to page through them. Filter by watchlistEntityIds to list the cases monitored for one entity. Requires case.read.
Request URL
https://api.caseprimus.ai/api/caseprimus/v1/watchlist/cases/searchRequest headers
| Type | Name | Value / description | Optional |
|---|---|---|---|
| String | Content-Type | application/json | Required |
| String | X-CasePrimus-Api-Key | Your API key: {apiKey} | Required |
No API key yet? See Authentication.
Input parameters
| Field | Description |
|---|---|
$filterobject (free-form) Optional | Exact-match field filters, e.g. {"status": "ACTIVE"}. |
$likeobject (free-form) Optional | Case-insensitive substring filters, e.g. {"name": "trip"}. |
$skipinteger Optional | minimum 0 |
$sortobject (free-form) Optional | Field to +1/-1 (ascending/descending), e.g. {"created": -1}. |
$limitinteger Optional | 0 to 100 |
Sample request
BASE="https://api.caseprimus.ai/api/caseprimus/v1" curl -X POST "$BASE/watchlist/cases/search" \ -H "X-CasePrimus-Api-Key: $CASEPRIMUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "$filter": { "watchlistEntityIds": "CPWLE0exampledemo0001" }, "$skip": 0, "$limit": 10 }'
const BASE = "https://api.caseprimus.ai/api/caseprimus/v1"; const res = await fetch(BASE + "/watchlist/cases/search", { method: "POST", headers: { "Content-Type": "application/json", "X-CasePrimus-Api-Key": process.env.CASEPRIMUS_API_KEY, }, body: JSON.stringify({ "$filter": { "watchlistEntityIds": "CPWLE0exampledemo0001" }, "$skip": 0, "$limit": 10 }), }); const data = await res.json();
import os import requests BASE = "https://api.caseprimus.ai/api/caseprimus/v1" res = requests.request( "POST", BASE + "/watchlist/cases/search", headers={"X-CasePrimus-Api-Key": os.environ["CASEPRIMUS_API_KEY"]}, json={ "$filter": { "watchlistEntityIds": "CPWLE0exampledemo0001", }, "$skip": 0, "$limit": 10, }, ) data = res.json()
Responses
| 200 | Matching cases. |
| 403 | Caller lacks the case.read permission. |
Response fields (HTTP 200)
| Field | Description |
|---|---|
recordsFilteredinteger | Total matching records, ignoring $skip and $limit. |
recordsarray of object | The matching cases on this page. |
_idstring | The case's id. |
numberinteger | |
accountIdstring | Your account's id. |
watchlistEntityIdsarray of string | Every watchlist entity this case is linked to - the same real-world case can be tracked against more than one company. |
caseIdentifierobject | |
snapshotobject (free-form) or null | |
riskLevelenum | VERY_HIGHHIGHMODERATELOWUNCLASSIFIED |
statusenum | ACTIVEPENDING_BACKOFFICE_REVIEWREJECTEDARCHIVED |
reviewedAtinteger (int64) or null | |
sharedWitharray of object | Teams or users the case is shared with. |
createdinteger (int64) | When the case was added, in milliseconds since the Unix epoch. |
createdBystring or null | |
updatedinteger (int64) or null | When the case was last updated, in milliseconds since the Unix epoch. |
updatedBystring or null |
{
"recordsFiltered": 1,
"records": [
{
"_id": "CPWLC0exampledemo0001",
"number": 200001,
"accountId": "CPA0exampledemo0001",
"watchlistEntityIds": [
"CPWLE0exampledemo0001"
],
"caseIdentifier": {
"courtType": "DC",
"cnr": "DLCT010012342020"
},
"snapshot": {
"parties": {
"petitioner": "Acme Traders Pvt Ltd",
"respondent": "Jane Doe"
},
"court": "District Court, Delhi",
"stage": "Arguments"
},
"riskLevel": "MODERATE",
"status": "ACTIVE",
"reviewedAt": null,
"sharedWith": [],
"created": 1757000000000,
"createdBy": "CPU0exampledemo0001",
"updated": null,
"updatedBy": null
}
]
}{
"recordsFiltered": 0,
"records": []
}Courts covered
CasePrimus.ai covers India's court system through the eCourts network and our verification data partners. When you add an entity you pass monitoredCourts: either ALL, or a list of the codes below.
| Code | Court or tribunal |
|---|---|
| ALL | Every court and tribunal below. Recommended. If used it must be the only value. |
| SC | Supreme Court of India |
| HC | High Courts |
| DC | District Courts |
| CC | Consumer Commissions |
| NCLT | National Company Law Tribunal |
| NCLAT | National Company Law Appellate Tribunal |
| DRT | Debts Recovery Tribunals |
| DRAT | Debts Recovery Appellate Tribunals |
| GSTAT | Goods and Services Tax Appellate Tribunal |
| CESTAT | Customs, Excise and Service Tax Appellate Tribunal |
Use ALL
ALL is the recommended choice.Help us match the right entity
Many Indian companies and people share similar names. The more you tell us, the fewer false matches you will see.
For a company
Give the legal name, and add registrationNumber and the registered location if you have them. AI also searches likely spelling variations of the name.
For a person
Give the full name, plus fatherName and birthDate (in DD-MM-YYYY format, for example 15-08-1990), and a location. These fields apply to people only and are ignored for companies.
What happens after you add an entity
Immediately
Name variations are generated
For a company, AI creates likely spelling variants of the name to search for. This never delays the response.
Optional
One-time historical lookup
If you set fetchHistoricalCases, we look back for cases already filed. It runs in the background and applies to companies only. Results appear on the entity as candidates, and the entity.historical_scan_completed event tells you when it has finished.
Every day
New cases are found
A new case is either added to the watchlist automatically (case.added) or held for your review first (case.pending_review).
Every case
We keep tracking it
New orders and hearing dates, status changes, refreshed AI summaries and changes in risk level all raise an alert. The entity's reputation score updates as its cases change.
Alerts and webhooks
Alerts appear in your dashboard. To have the data flow into a system you already run, subscribe a webhook to the events you care about. These are the ones most teams start with.
| Event | What it tells you |
|---|---|
| case.added | A new case was detected and added to the watchlist without needing manual review. |
| case.pending_review | A newly discovered case is waiting for your review before monitoring begins. |
| case.new_order_or_hearing | A new order was uploaded, or a hearing date was added/changed, on a monitored case. |
| case.risk_level_changed | A monitored case's computed risk level moved to a different band (e.g. Medium to High). |
| case.summary_refreshed | A new AI-generated summary was produced for a monitored case after a data refresh. |
| entity.reputation_changed | A watched entity's reputation score moved into a different band. |
| entity.historical_scan_completed | The one-time historical case scan for a newly added entity finished running. |
See all 13 webhook events and their payloads, or read how deliveries are signed and retried.
Errors
Errors use the HTTP status and a JSON body with a stable numeric code. These are the errors documented for the Litigation Watchlist API. The full format, and the limits that apply to every call, are on Rate limits & errors.
| Status | Code | Message |
|---|---|---|
| 400 | 60001 | Malformed data or missing required parameter values |
Frequently asked questions
Which courts does the Litigation Watchlist API monitor?
The Supreme Court, High Courts, District Courts, Consumer Commissions, and tribunals including NCLT, NCLAT, DRT, DRAT, GSTAT and CESTAT. When you add an entity, the recommended value for monitoredCourts is ALL.
How often are cases checked?
Every day. Every hearing, order and new case is checked against your whole watchlist daily, including weekends and Indian public holidays.
Can I monitor an individual, not just a company?
Yes. Set entityType to PERSON. Adding a father's name and date of birth helps avoid matching someone with a similar name.
Will I see cases that were filed before I added the entity?
Yes, if you set fetchHistoricalCases. It is a one-time search that runs in the background and applies to companies only. You will get an entity.historical_scan_completed event when it finishes.
How do I get alerted when a new case appears?
Subscribe a webhook to events such as case.added and case.new_order_or_hearing. CasePrimus.ai then sends each event to your HTTPS endpoint as a signed JSON request, so you do not need to poll the API.
How do I get an API key?
Create one from the Developer console in your CasePrimus.ai dashboard. Don't have an account yet? Request a demo and we will set you up.