Adverse Media Screening API

Screen individuals and companies against real-time news.

GDELT DOC 2.0 fetch + Claude Haiku 4.5 classification. Seven risk categories, per-article confidence scores, and human-readable reasoning — all in a single API call.

Endpoint

POST /v1/adverse-media/screen

Data source

GDELT DOC 2.0

LLM

Claude Haiku 4.5

Cost

~$0.009 / screening

How it works

From news article to risk category in ~2 seconds

The pipeline is four stages: query construction, article fetch, LLM classification, and response assembly.

1

Query construction

The entity name is escaped and wrapped in exact-phrase quotes. For COMPANY types, a near10 clause adds investigation-related keywords (lawsuit, fined, fraud, corruption). A tone<-3 filter ensures only negatively-toned articles are considered.

2

GDELT DOC 2.0 fetch

Up to 75 articles are fetched from GDELT with 3 retries and exponential backoff. Social media domains, press releases, and known content farms are filtered out. Results are cached in Redis for 24 hours.

3

LLM classification

Articles are truncated to 20 per screening and sent to Claude Haiku 4.5 in a single batch call. The model evaluates relevance, entity match confidence, and assigns a risk category with reasoning. LLM results are cached for 7 days.

4

Response assembly

A weighted risk score is computed from article classifications. The score maps to an overallRisk (CLEAR → CRITICAL). Per-article results, quota metadata, and caching status are returned.

Request

POST /v1/adverse-media/screen

Authenticate with a Bearer token and provide the entity name, type, and optional context.

bash
curl -X POST https://api.verifex.dev/v1/adverse-media/screen \
  -H "Authorization: Bearer vfx_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "entity": "Acme Corporation",
    "entityType": "COMPANY",
    "context": {
      "country": "US",
      "industry": "pharmaceuticals"
    }
  }'
entitystringrequired

The name of the individual or company to screen. Exact-phrase matched against article content.

entityTypeenumrequired

INDIVIDUAL or COMPANY. Affects query construction — COMPANY queries include near10 investigation keywords.

context.countrystring (ISO-3166-1 alpha-2)

Optional. Helps disambiguate entities with common names.

context.industrystring

Optional. Provides additional disambiguation context for the LLM classifier.

Response

Structured risk assessment with per-article detail

Every response includes an overall risk level, a numeric score, flagged article count, and full per-article results with confidence and reasoning.

json
{
  "overallRisk": "MEDIUM",
  "riskScore": 42,
  "riskLevel": "MEDIUM",
  "articlesFlagged": 3,
  "articlesReviewed": 20,
  "cached": false,
  "llmFailed": false,
  "llmCost": 0.009,
  "quota": {
    "used": 12,
    "limit": 50,
    "remaining": 38
  },
  "results": [
    {
      "title": "Acme Corp fined $2M for compliance violations",
      "url": "https://example.com/article/123",
      "publishedDate": "2026-05-15T10:30:00Z",
      "source": "Reuters",
      "sourceCountry": "US",
      "riskCategory": "HIGH",
      "confidence": 0.91,
      "reasoning": "Article describes a regulatory fine directly tied to the entity. High relevance, strong entity match.",
      "entityMatchConfidence": 0.95,
      "isRelevant": true
    },
    {
      "title": "Acme Corp reports record Q2 earnings",
      "url": "https://example.com/article/456",
      "publishedDate": "2026-05-10T14:00:00Z",
      "source": "Bloomberg",
      "sourceCountry": "US",
      "riskCategory": "CLEAR",
      "confidence": 0.98,
      "reasoning": "Positive earnings report. No adverse content. Entity match confirmed but no risk indicators.",
      "entityMatchConfidence": 0.92,
      "isRelevant": true
    }
  ]
}
overallRiskstring

Aggregate risk: CLEAR, LOW, MEDIUM, HIGH, or CRITICAL.

riskScorenumber (0-100)

Weighted numeric score. ≥70 = HIGH, ≥40 = MEDIUM, <40 = LOW/CLEAR.

articlesFlaggednumber

Count of articles with riskCategory HIGH or CRITICAL.

articlesReviewednumber

Total articles evaluated (max 20 per screening).

cachedboolean

True if result was served from cache (Redis or PostgreSQL).

llmFailedboolean

True if Claude was unavailable. Result is CLEAR with zero quota use.

llmCostnumber

Estimated USD cost of the LLM call for this screening.

quotaobject

Used, limit, and remaining adverse media checks for the billing period.

Risk categories

Seven classification levels

Each article is classified into one of seven risk categories. The classifier considers article tone, entity relevance, and contextual keywords.

CRITICAL

Severe adverse events: criminal conviction, terrorism financing, major regulatory enforcement action.

HIGH

Significant adverse events: substantial fines, lawsuits, fraud allegations, sanctions designations.

MEDIUM

Moderate concerns: minor regulatory actions, investigations, reputational issues.

LOW

Minor adverse mentions: disputes, criticism, or negative commentary without legal consequence.

CLEAR

No adverse content detected. Article is neutral or positive.

DISMISSED

Article mentions the entity but the adverse content is about a different party (homonym or subsidiary).

UNKNOWN

Insufficient information to classify. Rare — typically for paywalled or very short articles.

Plan access

Quota-gated by plan

Adverse media screening is available on Growth, Pro, and Enterprise plans. Free and Starter plans receive a 403 response.

Growth

Quota

50 / month

Overage

$0.15 / check

Pro

Quota

200 / month

Overage

$0.10 / check

Enterprise

Quota

Unlimited

Overage

Included

Quota is enforced atomically via Redis Lua script. Cache hits (Redis or PostgreSQL) consume zero quota. LLM failures also consume zero quota. Quota resets monthly with the billing cycle.

Error handling

Expected errors and how to handle them

403plan_access_denied

Adverse media screening is not available on your plan. Upgrade to Growth or higher.

https://verifex.dev/pricing
429quota_exceeded

You've used all your adverse media checks this month. Upgrade or wait for the next billing cycle.

https://verifex.dev/pricing
429rate_limit_exceeded

You've hit the rate limit. Slow down or upgrade your plan for higher limits.

https://verifex.dev/docs
503gdelt_unavailable

The GDELT news service is temporarily unavailable. Retry after a short delay.

https://verifex.dev/docs/adverse-media
400validation_error

entity and entityType are required. entityType must be INDIVIDUAL or COMPANY.

https://verifex.dev/docs/adverse-media

SDK examples

Official SDKs for common backends

The adverse media endpoint is accessible via the same SDKs as the rest of the Verifex API.

Node.js

typescript
import { Verifex } from "verifex";

const verifex = new Verifex({ apiKey: "vfx_your_api_key" });

const result = await verifex.adverseMediaScreen({
  entity: "Acme Corporation",
  entityType: "COMPANY",
  context: { country: "US" },
});

console.log(result.overallRisk, result.articlesFlagged);

Python

python
from verifex import VerifexClient

client = VerifexClient("vfx_your_api_key")

result = client.adverse_media_screen(
    entity="Acme Corporation",
    entity_type="COMPANY",
    context={"country": "US"},
)

print(result.overall_risk, result.articles_flagged)

Go

go
import (
    "context"
    verifex "github.com/Verifex-dev/verifex-go-sdk"
)

client := verifex.New("vfx_your_api_key")

result, err := client.AdverseMediaScreen(context.Background(), verifex.AdverseMediaRequest{
    Entity:     "Acme Corporation",
    EntityType: "COMPANY",
})

fmt.Println(result.OverallRisk, result.ArticlesFlagged)

Rust

rust
use verifex::{Verifex, AdverseMediaRequest};

let client = Verifex::new("vfx_your_api_key");

let result = client
    .adverse_media_screen(AdverseMediaRequest {
        entity: "Acme Corporation".into(),
        entity_type: "COMPANY".into(),
        ..Default::default()
    })
    .await?;

println!("{} — {} flagged", result.overall_risk, result.articles_flagged);