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
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
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:
Case Creation: When a new AML case is created via
POST /aml/caseand arefIdis providedStatus Updates: When an AML case status is updated via
PUT /aml/case/:id/statusand the case has arefId
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:
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:
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:
Configure Webhook URL: Set your webhook endpoint URL in the Vove Dashboard
Provide refId: Always include a
refIdwhen creating AML casesHandle Events: Implement an endpoint to receive and process webhook events
Webhook Best Practices
Idempotency: Webhook events may be delivered multiple times. Implement idempotency checks using the
refIdandstatuscombinationRetry Logic: Implement retry logic for failed webhook deliveries
Verification: Verify webhook signatures to ensure events are from Vove
Async Processing: Process webhooks asynchronously to avoid blocking your main application flow
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
2xxstatus 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:
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 watchlistsIN_REVIEW: Matches found, requires manual review
Validation Rules:
flowIdmust be a valid flow IDscreeningData.nameis required and must be a non-empty stringdobmust match the formatDD/MM/YYYYif providedgendermust be either"male"or"female"if providedA
refIdmust be provided to track the case updatesThe 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_REVIEWIf no matches are found, the case status is set to
NO_MATCHA webhook event is triggered if
refIdis providedThe response excludes sensitive fields like
hitsfor 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:
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:
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 foundIN_REVIEW: Matches found, pending reviewCLEARED: Case reviewed and clearedREJECTED: 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:
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 providedrefIddoes 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:
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:
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:
flowIdmust be a valid flow IDnameis required and must be a non-empty stringdobmust match the formatDD/MM/YYYYif providedgendermust be either"male"or"female"if providedThe 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 active404 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
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
Call
POST /aml/casewith customer information
Check the returned
statusfield
If
statusisIN_REVIEW, manually review the case
Use
GET /aml/case/{refId}to check case status later
Update case status using the case management endpoints
Use Case 2: Quick Pre-Screening Check
Call
POST /aml/flow/screenwith basic information
Review the
found_recordsin the response
If
total_hitsis 0, proceed with onboarding
If matches are found, decide whether to proceed or create a case for review
Use Case 3: Batch Case Review
Call
GET /aml/case?status=IN_REVIEW&limit=50to get pending cases
Review each case using the case details
Update case status as needed
Use Case 4: Case Status Tracking
Use your
refIdto callGET /aml/case/{refId}
Check the
statusfield
Take appropriate action based on the status
Best Practices
Always provide
refId: Use a unique reference ID to track cases in your systemHandle webhooks: Set up webhook listeners to receive status updates automatically
Review IN_REVIEW cases: Cases with
IN_REVIEWThe status requires manual attentionUse appropriate flows: Configure flows with the right sources and settings for your use case
Date format: Always use
DD/MM/YYYYformat for dates of birthError handling: Implement proper error handling for all status codes
Last updated