AML Screening

This document describes the Anti-Money Laundering (AML) screening endpoints available in the Vove API. These endpoints allow you to screen individuals and entities against various watchlists, sanctions lists, and PEP (Politically Exposed Persons) databases.

Overview

The AML API provides two main workflows:

  • Case Management Workflow: Create cases that track screening results over time, allowing you to review, update status, and maintain an audit trail.

  • Direct Screening Workflow: Perform one-time screenings without creating a case, receiving results immediately in the response.


Managing AML Flows

AML Flows are configuration templates that define how screenings are performed. Each flow specifies which watchlists to search, the type of entities to screen (individuals or entities), and the matching sensitivity level. Flows allow you to standardize your screening process and reuse configurations across multiple screenings.

Understanding AML Flows

An AML Flow consists of the following components:

  • Name: A descriptive name for the flow (e.g., "High-Risk Customer Screening", "Standard Individual Check")

  • Entity Type: Whether the flow screens individuals (INDIVIDUAL) or entities/companies (ENTITY)

  • Search Sources: The specific watchlists and databases to search against

Creating a New Flow

1
  • Log in to your Vove Dashboard

  • Go to the AML Screening section

  • Click on Screening Flows in the sidebar

2

Click "Create New Flow"

  • You'll see a form to configure your new flow

3

Configure Flow Settings

  • Flow Name: Enter a descriptive name (e.g., "Enhanced PEP Screening")

  • Entity Type: Select either:

    • INDIVIDUAL - For screening natural persons

    • ENTITY - For screening companies and legal entities

  • Source type: Select the specific watchlists and databases to search against

4

Select Search Sources

  • Browse the available watchlists and databases

  • Select the sources you want to include in this flow

Available source types include:

  • Sanctions Lists: Government sanctions lists (OFAC, UN, EU, etc.)

  • PEP Lists: Politically Exposed Persons databases

  • Other Watchlists: Additional regulatory and law enforcement lists

5

Save the Flow

  • Click Save or Create Flow

  • The flow will be created and available for use immediately (if active)

Flow Management Best Practices

  • Naming Convention: Use clear, descriptive names that indicate the flow's purpose (e.g., "High-Risk Individual Screening", "Standard Entity Check", "Enhanced PEP Review")

  • Version Control: When making significant changes, consider creating a new flow — preserves historical configurations and allows A/B testing

  • Documentation: Document why specific sources or settings were chosen — helps with compliance audits and troubleshooting

  • Regular Review: Periodically review your flows to ensure they meet current requirements — regulatory changes may require source updates

  • Testing: Test new flows with sample data before deploying to production — verify expected matches and false positive rates

  • Monitoring: Track which flows are used most frequently — optimize popular flows for performance and consider deprecating unused flows


Webhook Events

Vove automatically sends webhook events to notify your system when AML case statuses change. This allows you to integrate AML screening results into your own workflows and systems in real-time.

When Webhooks Are Sent

Webhooks are triggered in the following scenarios:

  1. Case Creation: When a new AML case is created via POST /aml/case and a refId is provided

  2. Status Updates: When an AML case status is updated via PUT /aml/case/:id/status and the case has a refId

Important: Webhooks are only sent if the case has a refId. If you want to receive webhook notifications, always provide a refId when creating cases.

Webhook Event Types

The following webhook events are sent based on the AML case status:

Event Type
Description
Triggered When

user.aml.no_match

No matches found

Case is created with NO_MATCH status or status is updated to NO_MATCH

user.aml.in_review

Matches found, requires review

Case is created with IN_REVIEW status or status is updated to IN_REVIEW

user.aml.cleared

Case cleared after review

Case status is updated to CLEARED

user.aml.rejected

Case rejected after review

Case status is updated to REJECTED

Webhook Payload Structure

Each webhook event includes the following payload:

{
  "refId": "customer-12345",
  "status": "IN_REVIEW"
}

Payload Fields:

Field
Type
Description

refId

string

Your internal reference ID that was provided when creating the case

status

enum

Current status of the AML case: NO_MATCH, IN_REVIEW, CLEARED, or REJECTED

Example Webhook Payloads

Case Created - No Match:

{
  "refId": "customer-12345",
  "status": "NO_MATCH"
}

Case Created - Matches Found:

{
  "refId": "customer-12345",
  "status": "IN_REVIEW"
}

Case Status Updated - Cleared:

{
  "refId": "customer-12345",
  "status": "CLEARED"
}

Case Status Updated - Rejected:

{
  "refId": "customer-12345",
  "status": "REJECTED"
}

Setting Up Webhooks

To receive webhook events, you need to:

  1. Configure Webhook URL: Set your webhook endpoint URL in the Vove Dashboard

  2. Provide refId: Always include a refId when creating AML cases

  3. Handle Events: Implement an endpoint to receive and process webhook events

Webhook Best Practices

  1. Idempotency: Webhook events may be delivered multiple times. Implement idempotency checks using the refId and status combination

  2. Retry Logic: Implement retry logic for failed webhook deliveries

  3. Verification: Verify webhook signatures to ensure events are from Vove

  4. Async Processing: Process webhooks asynchronously to avoid blocking your main application flow

  5. Logging: Log all webhook events for audit and debugging purposes

Webhook Delivery

  • Webhooks are delivered via HTTPS POST requests to your configured endpoint

  • Events are sent asynchronously and do not block API responses

  • Failed deliveries are retried according to Vove's retry policy

  • Ensure your webhook endpoint returns a 2xx status code to acknowledge receipt


AML APIs

Create AML Case

Creates a new AML case that automatically runs screening against configured watchlists and returns the case status. This endpoint is ideal for tracking screenings over time and maintaining an audit trail.

Endpoint: POST /aml/case

Request Body:

{
  "flowId": "507f1f77bcf86cd799439011",
  "screeningData": {
    "name": "John Doe",
    "dob": "15/03/1985",
    "gender": "male"
  },
  "refId": "customer-12345"
}

Request Parameters:

Field
Type
Required
Description

flowId

string

Yes

The ID of the AML flow to use for screening

screeningData

object

Yes

The data to screen

screeningData.name

string

Yes

Full name of the individual or entity to screen

screeningData.dob

string

No

Date of birth in DD/MM/YYYY format

screeningData.gender

enum

No

Gender: "male" or "female"

refId

string

Yes

Your internal reference ID for tracking

Response:

{
  "id": "507f1f77bcf86cd799439014",
  "flowId": "507f1f77bcf86cd799439011",
  "screeningData": {
    "name": "John Doe",
    "dob": "15/03/1985",
    "gender": "male"
  },
  "status": "IN_REVIEW",
  "refId": "customer-12345",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}

Status Values:

  • NO_MATCH: No matches found in any watchlists

  • IN_REVIEW: Matches found, requires manual review

Validation Rules:

  • flowId must be a valid flow ID

  • screeningData.name is required and must be a non-empty string

  • dob must match the format DD/MM/YYYY if provided

  • gender must be either "male" or "female" if provided

  • A refId must be provided to track the case updates

  • The flow must exist and be active

Example cURL:

curl -X POST https://api.vove.com/aml/case \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowId": "507f1f77bcf86cd799439011",
    "screeningData": {
      "name": "John Doe",
      "dob": "15/03/1985",
      "gender": "male"
    },
    "refId": "customer-12345"
  }'

Notes:

  • The screening runs automatically when the case is created

  • If matches are found, the case status is set to IN_REVIEW

  • If no matches are found, the case status is set to NO_MATCH

  • A webhook event is triggered if refId is provided

  • The response excludes sensitive fields like hits for security


List AML Cases

Retrieves a paginated list of AML cases for your organization with optional filtering by status and date range.

Endpoint: GET /aml/case

Query Parameters:

Parameter
Type
Required
Default
Description

page

number

No

1

Page number (1-indexed)

limit

number

No

10

Number of items per page

status

enum

No

-

Filter by case status: NO_MATCH, IN_REVIEW, CLEARED, REJECTED

startDate

string (ISO datetime)

No

-

Filter cases created on or after this date

endDate

string (ISO datetime)

No

-

Filter cases created on or before this date

Response:

{
  "data": [
    {
      "id": "507f1f77bcf86cd799439014",
      "flowId": "507f1f77bcf86cd799439011",
      "screeningData": {
        "name": "John Doe",
        "dob": "15/03/1985",
        "gender": "male"
      },
      "status": "IN_REVIEW",
      "refId": "customer-12345",
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 10
}

Response Fields:

Field
Type
Description

data

array

Array of AML case objects

total

number

Total number of cases matching the filter

page

number

Current page number

limit

number

Number of items per page

Example cURL:

curl -X GET "https://api.vove.com/aml/case?page=1&limit=20&status=IN_REVIEW" \
  -H "x-api-key: YOUR_API_KEY"

Example with Date Range:

curl -X GET "https://api.vove.com/aml/case?startDate=2024-01-01T00:00:00.000Z&endDate=2024-01-31T23:59:59.999Z" \
  -H "x-api-key: YOUR_API_KEY"

Status Filter Values:

  • NO_MATCH: No matches found

  • IN_REVIEW: Matches found, pending review

  • CLEARED: Case reviewed and cleared

  • REJECTED: Case reviewed and rejected


Get AML Case by Reference ID

Retrieves a specific AML case using your internal reference ID. This is useful when you need to check the status of a case using your own tracking identifier.

Endpoint: GET /aml/case/{refId}

Path Parameters:

Parameter
Type
Required
Description

refId

string

Yes

Your internal reference ID

Response:

{
  "id": "507f1f77bcf86cd799439014",
  "flowId": "507f1f77bcf86cd799439011",
  "screeningData": {
    "name": "John Doe",
    "dob": "15/03/1985",
    "gender": "male"
  },
  "status": "IN_REVIEW",
  "refId": "customer-12345",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}

Example cURL:

curl -X GET https://api.vove.com/aml/case/customer-12345 \
  -H "x-api-key: YOUR_API_KEY"

Error Responses:

  • 404 Not Found: Case with the provided refId does not exist or belongs to another organization


Screen Without Case Management

Performs a one-time screening against watchlists without creating a case. Results are returned immediately in the response. This endpoint is ideal for quick checks or when you don't need to track the screening over time.

Endpoint: POST /aml/flow/screen

Request Body:

{
  "flowId": "507f1f77bcf86cd799439011",
  "name": "John Doe",
  "dob": "15/03/1985",
  "gender": "male"
}

Request Parameters:

Field
Type
Required
Description

flowId

string

Yes

The ID of the AML flow to use for screening

name

string

Yes

Full name of the individual or entity to screen

dob

string

No

Date of birth in DD/MM/YYYY format

gender

enum

No

Gender: "male" or "female"

Response:

{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "total_hits": 2,
  "found_records": [
    {
      "id": "record-123",
      "entity_type": "natural",
      "name": "John Doe",
      "date_of_birth": ["15/03/1985"],
      "citizenship": ["US"],
      "source_type": "sanctions",
      "description": ["Sanctioned individual"],
      "alias_names": ["Johnny Doe"],
      "occupations": ["Businessman"]
    },
    {
      "id": "record-456",
      "entity_type": "natural",
      "name": "John Doe",
      "source_type": "pep",
      "pep_type": "domestic",
      "description": ["Politically exposed person"],
      "positions": ["Mayor"]
    }
  ]
}

Response Fields:

Field
Type
Description

timestamp

string (ISO datetime)

Timestamp of the screening

total_hits

number

Total number of matches found

found_records

array

Array of matching records from watchlists

Validation Rules:

  • flowId must be a valid flow ID

  • name is required and must be a non-empty string

  • dob must match the format DD/MM/YYYY if provided

  • gender must be either "male" or "female" if provided

  • The flow must exist and be active

Example cURL:

curl -X POST https://api.vove.com/aml/flow/screen \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowId": "507f1f77bcf86cd799439011",
    "name": "John Doe",
    "dob": "15/03/1985",
    "gender": "male"
  }'

Error Responses:

  • 400 Bad Request: Invalid request parameters or the flow is not active

  • 404 Not Found: Flow not found or does not belong to your organization

Notes:

  • This endpoint does not create a case - results are only returned in the response

  • Use this endpoint for quick screenings when you don't need case tracking

  • The flow's search configuration (sources, fuzzy search, entity type) is automatically applied

  • Results are cached for performance optimization


Error Handling

Standard HTTP Status Codes

Status Code
Description

200 OK

Request successful

400 Bad Request

Invalid request parameters or validation error

401 Unauthorized

Missing or invalid API key

404 Not Found

Resource not found

429 Too Many Requests

Rate limit exceeded

500 Internal Server Error

Server error

Error Response Format

{
  "statusCode": 400,
  "message": "Validation error message",
  "error": "Bad Request"
}

Common Error Scenarios

Invalid Date Format:

{
  "statusCode": 400,
  "message": "Date of birth must be in DD/MM/YYYY format",
  "error": "Bad Request"
}

Missing Required Field:

{
  "statusCode": 400,
  "message": "Either names or search_all must be provided",
  "error": "Bad Request"
}

Flow Not Found:

{
  "statusCode": 404,
  "message": "Flow not found",
  "error": "Not Found"
}

Case Not Found:

{
  "statusCode": 404,
  "message": "AML case not found",
  "error": "Not Found"
}

Flow Not Active:

{
  "statusCode": 400,
  "message": "Flow is not active",
  "error": "Bad Request"
}

Use Cases

Use Case 1: Customer Onboarding with Case Tracking

1
  • Call POST /aml/case with customer information

2
  • Check the returned status field

3
  • If status is IN_REVIEW, manually review the case

4
  • Use GET /aml/case/{refId} to check case status later

5
  • Update case status using the case management endpoints

Use Case 2: Quick Pre-Screening Check

1
  • Call POST /aml/flow/screen with basic information

2
  • Review the found_records in the response

3
  • If total_hits is 0, proceed with onboarding

4
  • If matches are found, decide whether to proceed or create a case for review

Use Case 3: Batch Case Review

1
  • Call GET /aml/case?status=IN_REVIEW&limit=50 to get pending cases

2
  • Review each case using the case details

3
  • Update case status as needed

Use Case 4: Case Status Tracking

1
  • Use your refId to call GET /aml/case/{refId}

2
  • Check the status field

3
  • Take appropriate action based on the status


Best Practices

  • Always provide refId: Use a unique reference ID to track cases in your system

  • Handle webhooks: Set up webhook listeners to receive status updates automatically

  • Review IN_REVIEW cases: Cases with IN_REVIEW The status requires manual attention

  • Use appropriate flows: Configure flows with the right sources and settings for your use case

  • Date format: Always use DD/MM/YYYY format for dates of birth

  • Error handling: Implement proper error handling for all status codes

Last updated