> For the complete documentation index, see [llms.txt](https://developer.fraudcheck.co.za/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.fraudcheck.co.za/aml-and-watchlist/watchlist-screening.md).

# Watchlist Screening

Watchlist Screening checks an individual against curated sanctions, politically exposed persons (PEP), crime, and regulatory watchlists. Use it to satisfy AML and KYC obligations during onboarding, enhanced due diligence, and ongoing monitoring. Five product variants are available, each targeting a different combination of lists.

## Variants

| Variant        | Endpoint                 | Lists screened                                         |
| -------------- | ------------------------ | ------------------------------------------------------ |
| **Lite**       | `/watchlist/lite`        | FIC Targeted Financial Sanctions, UN Sanctions, PEPs   |
| **Crime**      | `/watchlist/most_wanted` | Crime watchlists                                       |
| **PEPs**       | `/watchlist/peps`        | Politically Exposed Persons only                       |
| **Regulatory** | `/watchlist/regulatory`  | Regulatory watchlists                                  |
| **Extensive**  | `/watchlist/extensive`   | Configurable across PEPs, FIC TFS, Crime, UN Sanctions |

Pick the variant that matches your compliance requirement. The request and response shapes are identical across variants except where noted.

## When to use this

Use this service to:

* Screen new customers during onboarding for sanctions and PEP exposure
* Run crime watchlist checks as part of fraud prevention
* Identify PEPs to apply enhanced due diligence
* Re-screen existing customers periodically against updated lists

## How it works

Submit the individual's first name, surname, and ID number in a single POST request to the variant endpoint. The service performs fuzzy name matching against the relevant lists and returns a synchronous response containing the screening outcome, the number of matches, and any matched records with their confidence scores. Results can be re-fetched later by transaction ID.

| Property              | Value                                                                             |
| --------------------- | --------------------------------------------------------------------------------- |
| Response type         | `Synchronous`                                                                     |
| Typical response time | < 5s                                                                              |
| Result retrieval      | Returned inline; also retrievable via `GET /watchlist/{variant}/{transaction_id}` |
| Consent required      | `Yes`                                                                             |
| Region                | South Africa                                                                      |

## Authentication

```http
Authorization: Bearer {your_access_token}
```

## Endpoints

```http
POST /watchlist/lite
POST /watchlist/most-wanted
POST /watchlist/extensive

GET  /watchlist/{variant}/{transaction_id}
```

## Request

### Headers

| Header          | Required | Value              |
| --------------- | -------- | ------------------ |
| `Authorization` | Yes      | `Bearer {token}`   |
| `Content-Type`  | Yes      | `application/json` |

### Body parameters

| Field                          | Type    | Required | Description                                                                                   |
| ------------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------- |
| `FirstName`                    | string  | Yes      | Individual's first name                                                                       |
| `LastName`                     | string  | Yes      | Individual's surname                                                                          |
| `IdentityNo`                   | string  | Yes      | 13-digit South African ID number                                                              |
| `ConsentObtainedByDataSubject` | boolean | Yes      | Must be `true`. Confirms POPIA consent.                                                       |
| `SecondName`                   | string  | No       | Middle name. Improves match accuracy.                                                         |
| `SelectedWatchlists`           | array   | No       | **Extensive only.** Subset of `["peps", "tfs", "crime", "un_sanctions"]`. Omit to search all. |

### Example request - standard variants

```json
{
  "FirstName": "John",
  "LastName": "Smith",
  "IdentityNo": "*************",
  "BirthDate" : "1995-09-03",
  "ConsentObtainedByDataSubject": true
}
```

### Example request - Extensive with selected lists

```json
{
  "FirstName": "John",
  "LastName": "Smith",
  "IdentityNo": "*************",
  "ConsentObtainedByDataSubject": true,
  "SelectedWatchlists": ["peps", "tfs", "un_sanctions"]
}
```

## Response

### Response fields

| Field              | Type    | Description                             |
| ------------------ | ------- | --------------------------------------- |
| `transaction_id`   | string  | Unique identifier for this screening    |
| `product`          | string  | Variant used for screening              |
| `person_name`      | string  | Full name searched                      |
| `identifier`       | string  | ID number submitted                     |
| `screening_result` | string  | `ACCEPT`, `REVIEW`, `REJECT`, or `FAIL` |
| `match_count`      | integer | Number of matched records               |
| `results`          | array   | Matched records (see below)             |

### Match record fields

| Field              | Type   | Description                                                         |
| ------------------ | ------ | ------------------------------------------------------------------- |
| `name`             | string | Matched name on the list                                            |
| `aliases`          | string | Known aliases                                                       |
| `birth_date`       | string | Date of birth on file                                               |
| `countries`        | string | Associated countries                                                |
| `addresses`        | string | Known addresses                                                     |
| `identifiers`      | string | Identity or document numbers                                        |
| `sanctions`        | string | Sanctions list membership                                           |
| `dataset_code`     | string | Dataset identifier (e.g. `FIC_TFS`, `PEP`, `UN_SANCTIONS`, `CRIME`) |
| `dataset_title`    | string | Human-readable dataset name                                         |
| `match_percentage` | number | Match confidence (0–100)                                            |
| `match_score`      | number | Raw match score                                                     |

### Screening result logic

| Condition                  | `screening_result` |
| -------------------------- | ------------------ |
| No matches found           | `ACCEPT`           |
| Top match < 75% confidence | `REVIEW`           |
| Top match ≥ 75% confidence | `REJECT`           |
| Search failed unexpectedly | `FAIL`             |

### Example response - no matches

```json
{
  "transaction_id": "d41d8cd98f00b204e9800998ecf8427e",
  "product": "lite",
  "person_name": "John Smith",
  "identifier": "8601015800086",
  "screening_result": "ACCEPT",
  "match_count": 0,
  "results": []
}
```

### Example response - high-confidence match

```json
{
  "transaction_id": "d41d8cd98f00b204e9800998ecf8427e",
  "product": "lite",
  "person_name": "John Smith",
  "identifier": "8601015800086",
  "screening_result": "REJECT",
  "match_count": 1,
  "results": [
    {
      "name": "John Smith",
      "aliases": "J. Smith",
      "birth_date": "1986-01-01",
      "countries": "ZA",
      "dataset_code": "FIC_TFS",
      "dataset_title": "FIC Targeted Financial Sanctions",
      "match_percentage": 92.5,
      "match_score": 0.925
    }
  ]
}
```

## Retrieving results later

Re-fetch a previously completed screening by transaction ID. Use the variant endpoint that matches the original request:

```http
GET /watchlist/lite/{transaction_id}
GET /watchlist/most-wanted/{transaction_id}
GET /watchlist/extensive/{transaction_id}
```

Transactions are scoped to your account - you can only retrieve results for screenings made under your own credentials.

## Errors

| HTTP | Code                  | Meaning                                                                         | Action                                            |
| ---- | --------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------- |
| 401  | `unauthorized`        | Token missing or expired                                                        | Refresh your access token                         |
| 403  | `forbidden`           | Account lacks access to this variant, or transaction belongs to another account | Contact your account manager or check credentials |
| 404  | `not_found`           | Transaction ID does not exist                                                   | Verify the transaction ID                         |
| 422  | `invalid_input`       | Required field missing or consent not `true`                                    | Provide all required fields                       |
| 503  | `service_unavailable` | Search service temporarily unavailable                                          | Retry after a short delay                         |
| 500  | `server_error`        | Unexpected error                                                                | Contact support                                   |

## Code examples

{% tabs %}
{% tab title="cURL" %}

```bash
BASE_URL="https://consumer-service-api.fraudcheckonline.co.za/consumer-service"

curl -X POST "$BASE_URL/watchlist/lite" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "FirstName": "John",
    "LastName": "Smith",
    "IdentityNo": "8601015800086",
    "ConsentObtainedByDataSubject": true
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

BASE_URL = "https://consumer-service-api.fraudcheckonline.co.za/consumer-service"

response = requests.post(
    f"{BASE_URL}/watchlist/lite",
    headers={
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json",
    },
    json={
        "FirstName": "John",
        "LastName": "Smith",
        "IdentityNo": "8601015800086",
        "ConsentObtainedByDataSubject": True,
    },
)
result = response.json()

print(f"Result: {result['screening_result']} ({result['match_count']} matches)")
for match in result["results"]:
    print(f"  - {match['name']} [{match['dataset_title']}] {match['match_percentage']}%")
```

{% endtab %}

{% tab title="JavaScript (Node.js)" %}

```javascript
const BASE_URL = "https://consumer-service-api.fraudcheckonline.co.za/consumer-service";

const response = await fetch(`${BASE_URL}/watchlist/crime`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    FirstName: "John",
    LastName: "Smith",
    IdentityNo: "8601015800086",
    ConsentObtainedByDataSubject: true,
  }),
});
const result = await response.json();

console.log(`${result.screening_result} - ${result.match_count} matches`);
result.results.forEach(m => console.log(`  ${m.name} (${m.match_percentage}%)`));
```

{% endtab %}
{% endtabs %}

## Recommended decisioning

| Outcome  | Recommended action                                                 |
| -------- | ------------------------------------------------------------------ |
| `ACCEPT` | Proceed with normal onboarding flow                                |
| `REVIEW` | Route to a compliance analyst for manual review of partial matches |
| `REJECT` | Block onboarding and escalate per your AML policy                  |
| `FAIL`   | Retry the request; if it persists, contact support                 |

## Compliance & consent

* Obtain explicit consent from the data subject before submitting a request.
* Set `ConsentObtainedByDataSubject` to `true` to confirm consent has been captured.
* Retain proof of consent and screening outcomes in line with POPIA and your AML record-keeping obligations.

## FAQ

<details>

<summary>Which variant should I use?</summary>

For standard AML onboarding, use **Lite** (FIC TFS + UN Sanctions + PEPs). For crime watchlist checks, use **Crime**. For PEP-only or regulatory-only screening, use the dedicated variants. Use **Extensive** when you want fine-grained control over which lists are searched in a single call.

</details>

<details>

<summary>How is name matching performed?</summary>

Names are compared using fuzzy matching, so minor spelling differences and word-order changes still produce a match. The confidence is reported as `match_percentage`.

</details>

<details>

<summary>What does `REVIEW` mean in practice?</summary>

A partial match was found that did not reach the auto-reject threshold. A compliance reviewer should examine the matched record(s) and decide whether the individual is the same person.

</details>

<details>

<summary>Can I re-screen the same person later?</summary>

Yes - submit a new request. The `GET` endpoint returns the result of a specific historical transaction; it is not a periodic re-screening tool.

</details>

## Changelog

| Date       | Version | Change           |
| ---------- | ------- | ---------------- |
| 2026-04-11 | v1.0    | Initial release. |
