# Litigation Watchlist API

Source: https://caseprimus.ai/docs/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.

## 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**

`POST https://api.caseprimus.ai/api/caseprimus/v1/watchlist/entities`

**Request headers**

| Type | Name | Value | Optional |
| --- | --- | --- | --- |
| String | `Content-Type` | `application/json` | Required |
| String | `X-CasePrimus-Api-Key` | Your API key | Required |

**Input parameters**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Required | The legal name of the company, or the full name of the person. 2 to 255 characters |
| `entityType` | enum | Required | Whether the entity is a company (BUSINESS) or a person (PERSON). One of: PERSON, BUSINESS |
| `fatherName` | string or null | Optional | PERSON entities only - ignored for BUSINESS. up to 256 characters |
| `birthDate` | string or null | Optional | DD-MM-YYYY. PERSON entities only - ignored for BUSINESS. |
| `location` | string or null | Optional | Free-text address. up to 4192 characters |
| `registrationNumber` | string or null | Optional | The company's registration number, if you have it. It helps matching. up to 50 characters |
| `monitoredCourts` | array 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 One of: ALL, DC, SC, HC, CC, NCLT, NCLAT, GSTAT, DRT, DRAT, CESTAT |
| `sharedWith` | array of object | Optional | Teams or users the entity is shared with. |
| `sharedWith[].type` | enum | Required | One of: team, user |
| `sharedWith[].id` | string | Required | A team ID when type is 'team', a user ID otherwise. |
| `fetchHistoricalCases` | boolean | Optional | One-time historical case lookup, fired asynchronously right after creation. BUSINESS entities only - silently a no-op for PERSON. |

**Sample request**

```bash
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
  }'
```

**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 | Type | Required | Description |
| --- | --- | --- | --- |
| `_id` | string |  | The id of the new entity. |

**Example response (200)**

```json
{
  "_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**

`POST https://api.caseprimus.ai/api/caseprimus/v1/watchlist/entities/search`

**Request headers**

| Type | Name | Value | Optional |
| --- | --- | --- | --- |
| String | `Content-Type` | `application/json` | Required |
| String | `X-CasePrimus-Api-Key` | Your API key | Required |

**Input parameters**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `$filter` | object (free-form) | Optional | Exact-match field filters, e.g. {"status": "ACTIVE"}. |
| `$like` | object (free-form) | Optional | Case-insensitive substring filters, e.g. {"name": "trip"}. |
| `$skip` | integer | Optional | minimum 0 |
| `$sort` | object (free-form) | Optional | Field to +1/-1 (ascending/descending), e.g. {"created": -1}. |
| `$limit` | integer | Optional | 0 to 100 |

**Sample request**

```bash
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
  }'
```

**Responses**

- `200`: Matching entities.
- `403`: Caller lacks the watchlist.read permission.

**Response fields (HTTP 200)**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `recordsFiltered` | integer |  | Total matching records, ignoring $skip/$limit. |
| `records` | array of object |  | The matching entities on this page. |
| `records[]._id` | string |  | The entity's id. |
| `records[].number` | integer |  |  |
| `records[].accountId` | string |  | Your account's id. |
| `records[].name` | string |  | The entity's name. |
| `records[].entityType` | enum |  | One of: PERSON, BUSINESS |
| `records[].fatherName` | string or null |  | As provided when the entity was added. People only. |
| `records[].birthDate` | string or null |  | As provided when the entity was added. People only. |
| `records[].location` | string or null |  | As provided when the entity was added. |
| `records[].registrationNumber` | string or null |  | As provided when the entity was added. |
| `records[].monitoredCourts` | array of string |  | The courts selected when the entity was added. |
| `records[].status` | enum |  | One of: ACTIVE, PAUSED, ARCHIVED |
| `records[].nameVariations` | array of string |  | AI-generated alternate spellings/forms of the company name, used to widen court-record name matching. Empty for PERSON entities. |
| `records[].lastCourtSyncAt` | integer (int64) or null |  | When the daily/on-demand court-record search last ran for this entity. |
| `records[].sharedWith` | array of object |  | Teams or users the entity is shared with. |
| `records[].created` | integer (int64) |  | When the entity was created, in milliseconds since the Unix epoch. |
| `records[].createdBy` | string |  |  |
| `records[].updated` | integer (int64) or null |  | When the entity was last updated, in milliseconds since the Unix epoch. |
| `records[].updatedBy` | string or null |  |  |

**Example response (200)**

```json
{
  "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
    }
  ]
}
```

### 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**

`POST https://api.caseprimus.ai/api/caseprimus/v1/watchlist/cases/search`

**Request headers**

| Type | Name | Value | Optional |
| --- | --- | --- | --- |
| String | `Content-Type` | `application/json` | Required |
| String | `X-CasePrimus-Api-Key` | Your API key | Required |

**Input parameters**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `$filter` | object (free-form) | Optional | Exact-match field filters, e.g. {"status": "ACTIVE"}. |
| `$like` | object (free-form) | Optional | Case-insensitive substring filters, e.g. {"name": "trip"}. |
| `$skip` | integer | Optional | minimum 0 |
| `$sort` | object (free-form) | Optional | Field to +1/-1 (ascending/descending), e.g. {"created": -1}. |
| `$limit` | integer | Optional | 0 to 100 |

**Sample request**

```bash
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
  }'
```

**Responses**

- `200`: Matching cases.
- `403`: Caller lacks the case.read permission.

**Response fields (HTTP 200)**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `recordsFiltered` | integer |  | Total matching records, ignoring $skip and $limit. |
| `records` | array of object |  | The matching cases on this page. |
| `records[]._id` | string |  | The case's id. |
| `records[].number` | integer |  |  |
| `records[].accountId` | string |  | Your account's id. |
| `records[].watchlistEntityIds` | array of string |  | Every watchlist entity this case is linked to - the same real-world case can be tracked against more than one company. |
| `records[].caseIdentifier` | object |  |  |
| `records[].snapshot` | object (free-form) or null |  |  |
| `records[].riskLevel` | enum |  | One of: VERY_HIGH, HIGH, MODERATE, LOW, UNCLASSIFIED |
| `records[].status` | enum |  | One of: ACTIVE, PENDING_BACKOFFICE_REVIEW, REJECTED, ARCHIVED |
| `records[].reviewedAt` | integer (int64) or null |  |  |
| `records[].sharedWith` | array of object |  | Teams or users the case is shared with. |
| `records[].created` | integer (int64) |  | When the case was added, in milliseconds since the Unix epoch. |
| `records[].createdBy` | string or null |  |  |
| `records[].updated` | integer (int64) or null |  | When the case was last updated, in milliseconds since the Unix epoch. |
| `records[].updatedBy` | string or null |  |  |

**Example response (200)**

```json
{
  "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
    }
  ]
}
```

## 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.** The value is recorded with the entity. At present, monitoring is not restricted by it, so `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. |

## 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.
