Skip to Content

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

  1. 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.
  2. De-duplicate. Different addresses for one article count once: the mobile and AMP editions, www., and tracking parameters are ignored.
  3. 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.
  4. 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.

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" }
FieldNotes
subject.nameRequired, up to 120 characters, in any script.
subject.aliasesAt most one other name, typically the name in its own script.
subject.entityTypeperson (the default) or entity.
subject.countryISO 3166-1 alpha-2 or alpha-3. Chooses the search language and helps rule out namesakes.
subject.birthYearYear of birth or founding. Only the model sees it.
subject.languagesUp to two of en, cs, de, es, fr, ja, ko, instead of the language Korala would choose.
riskSubjectIdOptional: 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

statusMeaning
findingA finding about your subject is open, or a reviewer confirmed one.
possible_findingFindings are open, and for each one it is unclear whether it is about your subject.
clearNothing adverse was found, and every search and article was completed.
incompleteNothing adverse was found, but something was not searched or not judged. This is not a clear result.
errorNothing 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 nameOutcome
Findingfinding: a fraud conviction about the subject
Possiblepossible_finding: a bribery allegation, subject unclear
Namesakeclear: the adverse article is about someone else, so it is not kept
Partialincomplete: the adverse-terms search fails
Malformederror (judge_failed): the model’s answer cannot be read
Unavailableerror (retrieval_failed): every search fails
none of theseclear

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.

Last updated on