Adverse media
Korala searches the news for a person or a company and reads each article it finds. For each one it decides whether the article is about your subject, whether it reports wrongdoing, what kind, and how far the matter had gone. You get the articles that may be adverse, each with its link, its date, a short quote and the reason. A reviewer then decides.
Adverse media is for enhanced due diligence. Run it when your risk policy calls for it (a PEP, a high-risk country, a large amount) or when a reviewer asks. It is not meant for every customer. A finding never declines anyone on its own: it goes to review with its citation.
How it works
- Search. Korala sends up to four searches: each name alone, and each name with words for fraud, bribery, laundering, conviction and charges in that name’s language. The language comes from the name’s script (Hangul, kana) or from the subject’s country. Terms exist in English, Czech, French, German, Japanese, Korean and Spanish; other countries get the English terms. A search returns at most ten results.
- De-duplicate. Different addresses for one article count once: the
mobile and AMP editions,
www., and tracking parameters are ignored. - Judge. Korala’s model reads at most 40 articles: each title and a short excerpt, with the name, country and birth year you gave. Nothing else about your subject is sent.
- Decide. An article judged adverse and about your subject is a
finding. An article judged adverse where it is unclear whether it is
about your subject is also a finding, marked
aboutSubject: "unclear". Articles about someone else, or with nothing adverse in them, are not kept.
Articles are not filtered by date. Each finding shows its publication date so the reviewer can weigh an old matter against a recent one.
Korala keeps the link, the title, the publication date, a quote of at most 280 characters, the model’s reason, and which search provider, model and prompt version judged it. It never keeps the article. It does not keep the name you searched either: the run holds a keyed digest of it.
Run a search
POST /api/v1/screening/adverse-media/runs
Idempotency-Key: edd-2041-media{
"subject": {
"name": "Ada Finding Testperson",
"country": "US",
"birthYear": 1971
},
"riskSubjectId": "4c6f1b2a-8f0e-4d7a-9b3c-2e5d1a0f7c88"
}| Field | Notes |
|---|---|
subject.name | Required, up to 120 characters, in any script. |
subject.aliases | At most one other name, typically the name in its own script. |
subject.entityType | person (the default) or entity. |
subject.country | ISO 3166-1 alpha-2 or alpha-3. Chooses the search language and helps rule out namesakes. |
subject.birthYear | Year of birth or founding. Only the model sees it. |
subject.languages | Up to two of en, cs, de, es, fr, ja, ko, instead of the language Korala would choose. |
riskSubjectId | Optional: a risk subject in the same environment to record the outcome on. |
Idempotency-Key is required. Retry with the same key and body to get the
same run; a different body with a used key returns 409. A run takes a few
seconds and at most 75 seconds, and the response is the finished run.
{
"id": "9a2e4c71-5b3d-4f08-a6e1-7c0d2b9f3e15",
"status": "finding",
"incomplete": false,
"incompleteReasons": [],
"errorCode": null,
"sandbox": true,
"simulated": true,
"retrieval": {
"provider": "fake",
"queries": [
{ "kind": "name", "nameIndex": 0, "language": "en", "results": 1, "failure": null },
{ "kind": "adverse", "nameIndex": 0, "language": "en", "results": 2, "failure": null }
],
"articlesRetrieved": 3,
"articlesDropped": 0,
"articlesUnique": 2
},
"judge": {
"provider": "fake",
"model": "fake-judge",
"promptVersion": "adverse-media-judge-v3",
"rulesVersion": "rules-v1",
"articlesJudged": 2,
"articlesUnjudged": 0
},
"riskFact": "screening.adverse_media",
"riskSource": "korala:screening:adverse_media:v1",
"findingCount": 1,
"findings": [
{
"id": "e1c8b0d2-7a4f-4e39-8c15-0b6d2f9a3e71",
"url": "https://news.example/adverse-media/finding/report",
"title": "Sandbox report article",
"publishedAt": "2025-06-15",
"snippet": "A simulated report for the sandbox scenario.",
"aboutSubject": "yes",
"category": "fraud",
"stage": "conviction",
"reason": "Sandbox: a simulated report of a fraud conviction.",
"foundBy": ["adverse:0:en"],
"retrievalProvider": "fake",
"judgeModel": "fake-judge",
"promptVersion": "adverse-media-judge-v3",
"decision": "pending"
}
]
}Limits
An organization may start 30 runs a minute and 300 an hour in each mode,
whichever key or dashboard user starts them, and may have 2 live runs in
progress at once. Beyond any of these the request answers 429 with a Retry-After
header in seconds. Test mode and live mode
are counted apart, so test runs never hold up live ones, and test runs
never count toward the runs in progress.
A retry with the same Idempotency-Key while the first request is still
running waits for it and returns the same run. Only one retry waits at a
time: another one answers 409 with "error": "request_in_progress" and a
Retry-After header, so retry it with the same key once the first has
finished. A 409 without that code is permanent: the key was used for a
different request.
GET /api/v1/screening/adverse-media/runs/{id} returns a run with its
findings. GET /api/v1/screening/adverse-media/runs lists runs, newest
first, filtered by status, sessionId or riskSubjectId, with page and
limit (at most 100).
Categories and stages
category is one of fraud, bribery_corruption, money_laundering,
market_abuse, tax_fraud, sanctions_evasion, terrorism_financing and
other_crime. stage is allegation, investigation, charge,
conviction or sanction, or null when the article does not say.
Outcomes
status | Meaning |
|---|---|
finding | A finding about your subject is open, or a reviewer confirmed one. |
possible_finding | Findings are open, and for each one it is unclear whether it is about your subject. |
clear | Nothing adverse was found, and every search and article was completed. |
incomplete | Nothing adverse was found, but something was not searched or not judged. This is not a clear result. |
error | Nothing could be searched or judged. See errorCode. |
incomplete is also a flag. A finding from a partial run keeps its status
and has incomplete: true. incompleteReasons says why: query_failed,
names_capped, queries_capped, articles_capped, judge_failed,
judge_output_invalid or deadline_exceeded. If the model’s answer cannot
be read, those articles count as not judged. They never count as clear.
Review a finding
An organization owner or admin, signed in to the dashboard, confirms a finding or marks it a false positive, with a reason:
POST /api/v1/screening/adverse-media/findings/{id}/decision
Idempotency-Key: edd-2041-review-1{ "decision": "false_positive", "reason": "Different person: the article names a surgeon in Denver" }The run’s status is worked out again from its findings. A false positive no
longer counts. A confirmed finding makes the run a finding. Every decision
is kept in an audit trail. API keys and members get 403.
Risk evidence
When a run names a risk subject, or runs in a session that has one, its
outcome is recorded as the fact screening.adverse_media from the source
korala:screening:adverse_media:v1. The value is finding,
possible_finding or clear. An incomplete or error run records the
fact as unavailable, so your policy treats it as missing evidence. Trust the
source in a policy input of type string for that fact only, and write
conditions on those three values. A decision records new evidence only while
that run is still the subject’s newest adverse-media result.
In a workflow
Add a check step with the korala_adverse_media provider:
{
"type": "check",
"config": {
"kind": "adverse_media",
"provider": "korala_adverse_media",
"providerConfig": { "languages": ["ko"] }
}
}Workflow steps always run: a step cannot be made conditional. To search only on request, put the step in a workflow that only your enhanced due diligence session configuration uses, and start that configuration only for the customers your policy names (a PEP, a high-risk country, a large amount). Otherwise call the API when a reviewer asks.
The step searches for the name on the session’s identity document, the
name printed in the document’s own script, the issuing country and the year
of birth. providerConfig takes only languages (optional, up to two). A
finding, a possible finding or an incomplete run sends the session to
review. An error is recorded for review. That includes concurrency_limited: when
the organization already has 2 live runs in progress, the step waits for
one to finish, asking again every few seconds for up to a minute, then
records an error rather than a result. The step is
never a match, and a
workflow with blockingMode: "block" on this step is refused when you save
it.
Test mode
Test mode never contacts a search provider or a model. Its runs are
simulated: true, with articles at news.example. A word in the subject’s
name picks what happens:
| Word in the name | Outcome |
|---|---|
Finding | finding: a fraud conviction about the subject |
Possible | possible_finding: a bribery allegation, subject unclear |
Namesake | clear: the adverse article is about someone else, so it is not kept |
Partial | incomplete: the adverse-terms search fails |
Malformed | error (judge_failed): the model’s answer cannot be read |
Unavailable | error (retrieval_failed): every search fails |
| none of these | clear |
Live mode needs adverse media to be configured on Korala’s side. Until it
is, live requests answer 503 and a live workflow step records an error.
A live run is never clear without a search.
Webhooks
screening.adverse_media.run.completed carries the run id, status,
incomplete, its reasons, the error code, trigger, simulated, the session
and risk subject ids and the finding count.
screening.adverse_media.finding.found carries each finding’s id,
category, stage and aboutSubject. Neither includes the name, a link or a
quote: read the run for those. Delivery is at least once. A decision sends
no event.
Data protection
Findings are your evidence about your customer. They are kept under your retention, in your organization and environment only. Korala keeps no list of people linked to offences and does not share findings across organizations.