curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe"
}'
{
"final_risk_score": 75,
"decision": "HIGH_RISK",
"summary": "Multiple adverse media findings identified including fraud allegations and regulatory violations.",
"sources": [
{
"id": 1,
"title": "Tech Executive Charged with Fraud",
"url": "https://example.com/news/article1",
"summary": "John Doe, CEO of Tech Corp, faces fraud charges related to investor funds..."
},
{
"id": 3,
"title": "SEC Investigation into Tech Corp",
"url": "https://example.com/news/article2",
"summary": "SEC investigating Tech Corp for securities violations involving executive..."
}
],
"entity_name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"analysis_timestamp": "2024-11-22T10:30:00Z",
"processing_time_ms": 6000
}
Compliance Screening
Adverse Media Check
POST
/
kyc
/
adverse-media
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe"
}'
{
"final_risk_score": 75,
"decision": "HIGH_RISK",
"summary": "Multiple adverse media findings identified including fraud allegations and regulatory violations.",
"sources": [
{
"id": 1,
"title": "Tech Executive Charged with Fraud",
"url": "https://example.com/news/article1",
"summary": "John Doe, CEO of Tech Corp, faces fraud charges related to investor funds..."
},
{
"id": 3,
"title": "SEC Investigation into Tech Corp",
"url": "https://example.com/news/article2",
"summary": "SEC investigating Tech Corp for securities violations involving executive..."
}
],
"entity_name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"analysis_timestamp": "2024-11-22T10:30:00Z",
"processing_time_ms": 6000
}
Perform adverse media analysis on entities to identify negative news, sanctions, criminal records, and other risk factors beyond traditional watchlist checks. Supports analysis of persons, companies, and websites/domains.
Endpoint
POST /kyc/adverse-media
Authentication
Requireskyc:create permission. Include your Bearer token in the Authorization header.
Description
The adverse media check uses AI-powered analysis to search and evaluate publicly available information about an entity. It performs:- Parallel web searches across multiple sources
- LLM analysis to filter and evaluate findings
- Risk scoring based on identified adverse media
- Structured reporting with source citations
Entity Types
The endpoint supports three entity types:| Type | Description | Search Focus |
|---|---|---|
person | Individual analysis (default) | Fraud, sanctions, criminal records, professional profiles |
company | Company/organization analysis | Corporate fraud, regulatory violations, sanctions |
website | Website/domain reputation | Fraud reports, security issues, blacklists, consumer complaints |
Request Body Parameters
Zero Data Retention (ephemeral mode)
You can request ephemeral processing with either theX-Data-Retention: ephemeral header or "data_retention": "ephemeral" in the JSON body. Per-request ephemeral must be enabled for your account first: the endpoint identifier adverse-media.check (or the wildcard *) has to appear in your tenant’s data_processing_config.allowed_ephemeral_endpoints, otherwise the request is rejected with a 400. Tenants can also opt in account-wide by setting data_processing_config.mode to ephemeral — the tenant-level setting always wins over per-request flags and does not require the allowlist. Contact support to enable either option on your account.
When ephemeral mode is active, the API returns the normal analysis response but does not store a validation record (nothing appears in the dashboard history), does not emit the detailed audit event, and never writes the analysis report to disk. The platform retains only an aggregate billing metric (one counted adverse-media check, with no subject or outcome references); tenants with retain_billing_metrics: false suppress that too.
An invalid data_retention value returns 400 before any quota is consumed.
Adverse media analysis queries third-party providers: the entity name is sent to the Tavily search API and to the configured LLM (AWS Bedrock or OpenAI), which process it under their own no-retention / non-training policies. Ephemeral mode guarantees zero retention in Legaltalent’s own stores.
Request Example
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe"
}'
Additional Request Examples
Person with Context
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"additional_info": "CEO of Tech Corp, based in New York"
}'
Company Analysis
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Tech Corp Inc",
"entity_type": "company",
"country": "US",
"additional_info": "Technology company founded in 2010"
}'
Website/Domain Analysis
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "example-shop.com",
"entity_type": "website",
"additional_info": "E-commerce platform"
}'
Using OpenAI Provider
curl -X POST https://stg.kyc.legaltalent.ai/kyc/adverse-media \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"country": "US",
"provider": "openai",
"model": "gpt-4o-mini"
}'
Response Format
Success Response
{
"final_risk_score": 75,
"decision": "HIGH_RISK",
"summary": "Multiple adverse media findings identified including fraud allegations and regulatory violations.",
"sources": [
{
"id": 1,
"title": "Tech Executive Charged with Fraud",
"url": "https://example.com/news/article1",
"summary": "John Doe, CEO of Tech Corp, faces fraud charges related to investor funds..."
},
{
"id": 3,
"title": "SEC Investigation into Tech Corp",
"url": "https://example.com/news/article2",
"summary": "SEC investigating Tech Corp for securities violations involving executive..."
}
],
"entity_name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"analysis_timestamp": "2024-11-22T10:30:00Z",
"processing_time_ms": 6000
}
Response Fields
| Field | Type | Description |
|---|---|---|
final_risk_score | integer | Risk score from 0-100 (higher = higher risk) |
decision | string | Risk decision: CLEAR, LOW_RISK, MEDIUM_RISK, or HIGH_RISK |
summary | string | Summary of findings and risk assessment (max 300 chars) |
sources | array | List of adverse media sources found (empty if CLEAR) |
entity_name | string | Name of the analyzed entity |
entity_type | string | Type of entity analyzed: person, company, or website |
country | string | Country (if provided) |
age | integer | Age (if provided, 0 otherwise) |
analysis_timestamp | string | ISO 8601 timestamp of the analysis |
processing_time_ms | integer | Total processing time in milliseconds |
Source Fields
Each source includes:| Field | Type | Description |
|---|---|---|
id | integer | Unique source identifier (1-indexed) |
title | string | Title of the source/article (max 100 chars) |
url | string | URL to the source |
summary | string | Summary explaining why this source is adverse (max 200 chars) |
Decision Values
| Decision | Score Range | Description |
|---|---|---|
CLEAR | 0-20 | No significant adverse media found |
LOW_RISK | 21-40 | Minor adverse findings |
MEDIUM_RISK | 41-70 | Moderate adverse findings requiring review |
HIGH_RISK | 71-100 | Significant adverse findings, strong risk indicators |
Clear Response (No Adverse Media)
{
"final_risk_score": 5,
"decision": "CLEAR",
"summary": "No significant adverse media findings identified for this entity.",
"sources": [],
"entity_name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"analysis_timestamp": "2024-11-22T10:30:00Z",
"processing_time_ms": 5600
}
Website Analysis Response
{
"final_risk_score": 65,
"decision": "MEDIUM_RISK",
"summary": "Multiple fraud reports and consumer complaints found for this website. Users report non-delivery of orders and poor customer service.",
"sources": [
{
"id": 2,
"title": "Scam Alert: example-shop.com Reviews",
"url": "https://trustpilot.com/review/example-shop.com",
"summary": "Multiple users report fraudulent charges and non-delivery of products..."
},
{
"id": 5,
"title": "BBB Complaints for Example Shop",
"url": "https://bbb.org/example-shop",
"summary": "37 complaints filed in the last 12 months regarding refund issues..."
}
],
"entity_name": "example-shop.com",
"entity_type": "website",
"country": "",
"age": 0,
"analysis_timestamp": "2024-11-22T10:30:00Z",
"processing_time_ms": 5200
}
Error Responses
400 Bad Request - Missing Name
{
"error": "Validation error: 'name' parameter is required"
}
400 Bad Request - Invalid Entity Type
{
"error": "Validation error: 'entity_type' must be one of ['person', 'company', 'website']"
}
500 Internal Server Error - Configuration Error
{
"error": "Configuration error: TAVILY_API_KEY not set"
}
500 Internal Server Error - Analysis Failed
{
"error": "Internal error: Failed to analyze adverse media: LLM analysis timed out after 10 seconds"
}
Status Codes
| Code | Description |
|---|---|
| 200 | Success - Analysis completed |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Missing or invalid token |
| 403 | Forbidden - Insufficient permissions |
| 500 | Internal Server Error |
Usage Examples
Python Example
import requests
token = "YOUR_TOKEN"
# Analyze a person
response = requests.post(
"https://stg.kyc.legaltalent.ai/kyc/adverse-media",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"name": "John Doe",
"entity_type": "person",
"country": "US",
"age": 45,
"additional_info": "CEO of Tech Corp"
}
)
if response.status_code == 200:
data = response.json()
print(f"Risk Score: {data['final_risk_score']}")
print(f"Decision: {data['decision']}")
print(f"Summary: {data['summary']}")
if data['sources']:
print(f"\nFound {len(data['sources'])} adverse sources:")
for source in data['sources']:
print(f"- [{source['id']}] {source['title']}: {source['url']}")
else:
print(f"Error: {response.json()}")
Python - Website Analysis
import requests
token = "YOUR_TOKEN"
# Analyze a website
response = requests.post(
"https://stg.kyc.legaltalent.ai/kyc/adverse-media",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
},
json={
"name": "suspicious-shop.com",
"entity_type": "website",
"additional_info": "E-commerce site selling electronics"
}
)
if response.status_code == 200:
data = response.json()
print(f"Website: {data['entity_name']}")
print(f"Risk Score: {data['final_risk_score']}")
print(f"Decision: {data['decision']}")
print(f"Summary: {data['summary']}")
else:
print(f"Error: {response.json()}")
JavaScript Example
const token = "YOUR_TOKEN";
async function checkAdverseMedia(name, entityType = "person", options = {}) {
const response = await fetch(
"https://stg.kyc.legaltalent.ai/kyc/adverse-media",
{
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
name: name,
entity_type: entityType,
country: options.country,
age: options.age,
additional_info: options.additionalInfo
})
}
);
const data = await response.json();
if (response.ok) {
console.log(`Entity: ${data.entity_name} (${data.entity_type})`);
console.log(`Risk Score: ${data.final_risk_score}`);
console.log(`Decision: ${data.decision}`);
console.log(`Summary: ${data.summary}`);
if (data.sources.length > 0) {
console.log(`\nFound ${data.sources.length} adverse sources`);
data.sources.forEach(source => {
console.log(`- [${source.id}] ${source.title}: ${source.url}`);
});
}
return data;
} else {
console.error("Error:", data.error);
throw new Error(data.error);
}
}
// Usage examples
await checkAdverseMedia("John Doe", "person", { country: "US", age: 45 });
await checkAdverseMedia("Tech Corp Inc", "company", { country: "US" });
await checkAdverseMedia("example-shop.com", "website");
Search Process
Person/Company Analysis
The adverse media check for persons and companies performs parallel searches across:- Fraud/Corruption/Sanctions: Financial crimes, corruption, sanctions, laundering
- Criminal Records: Arrests, investigations, charges, convictions
- Sanction Lists: OFAC, UN, designated persons, blacklists
- Professional Validation: LinkedIn, professional profiles, company associations
- General News: Recent news articles and media coverage
Website/Domain Analysis
For website analysis, specialized searches are performed:- Reputation & Reviews: User reviews, complaints, ratings
- Fraud Reports: Scam reports, phishing alerts, fake site warnings
- Security Issues: Data breaches, vulnerabilities, malware reports
- Blacklists: Domain blacklists, spam lists, unsafe site flags
- Consumer Complaints: Trustpilot, BBB, consumer complaint databases
- Filter false positives
- Evaluate relevance to the specific entity
- Assess risk factors
- Generate concise summaries
Provider Options
AWS Bedrock (Default)
- Provider:
"bedrock" - Model: Claude 3.5 Haiku (with fallback to Claude 3 Haiku)
- Use Case: Production deployments on AWS, no API key required (uses IAM role)
OpenAI
- Provider:
"openai" - Model: Specify model (default:
"gpt-4o-mini") - Use Case: High-precision analysis, specific model requirements
Performance
- Typical Response Time: 5-10 seconds
- Timeout: 10 seconds per LLM call
- Retries: Automatic retries on timeout (up to 3 attempts)
- Search Sources: Up to 15 sources analyzed per request
- LLM Analysis: Includes timeout protection and error handling
Integration Tips
- Combine with Watchlist Checks: Use adverse media as a supplement to traditional watchlist checks
- Use Context: Provide country, age, and additional info to improve accuracy
- Choose the Right Entity Type: Use
websitefor domain reputation checks,companyfor organizational analysis - Handle Timeouts: Implement retry logic for production use
- Review Scores: Risk scores should be reviewed by compliance teams, not automated
- Source Verification: Always verify adverse sources before making decisions
Best Practices
-
Use adverse media checks for:
- Enhanced due diligence on individuals
- Company/organization risk assessment
- Website reputation verification before partnerships
- Ongoing monitoring
- Risk assessment for high-value relationships
- Compliance investigations
-
Entity Type Selection:
- Use
personfor individual background checks - Use
companyfor corporate due diligence - Use
websitefor merchant/partner website verification
- Use
- Combine with traditional watchlist checks for comprehensive risk screening
-
Review
summaryfor human-readable assessment -
Check
sourcesURLs to verify findings - Use risk scores as indicators, not definitive decisions