> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankieone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Interpreting AML Screening Results

> A detailed guide to understanding the results of an AML check, from the high-level summary down to the details of each watchlist match.

## How to Read an AML Result

When you execute a workflow containing an AML step, the API response provides a rich set of data to help you understand the outcome. This guide provides a structured, "top-down" walkthrough of how to parse the `workflowResult` object.

<Accordion title="View Full API Response Example">
  The examples in this guide refer to a workflow execution response where Adverse Media matches were found. Click to expand and see the full structure.

  ```json theme={null}
  {
    "requestId": "01HN9XHZN6MGXM9JXG50K59Q85",
    "workflowResult": {
      "workflowExecutionId": "01K55F466SQBT41KMQ7PWGEEN3",
      "workflowExecutionState": "COMPLETED",
      "status": "REVIEW",
      "result": "REVIEW",
      "riskAssessment": {
          "riskLevel": "HIGH",
          "riskScore": 100,
          "riskFactors": [
              {
                "createdAt": "2025-09-15T01:16:45.849033Z",
                "description": "Has adverse media hits",
                "factor": "has_adverse_media",
                "riskFactorId": "b26d1a21-57f9-46ed-afc9-f7025980ad9c",
                "score": 10,
                "status": "VALID",
                "updatedAt": "2025-09-15T01:16:45.849033Z",
                "updatedRequestId": "01HN9XHZN6MGXM9JXG50K59Q85"
              }
          ]
      },
      "issues": [
        {
          "category": "AML",
          "createdAt": "2025-09-15T01:16:45.949556Z",
          "issue": "MEDIA",
          "issueId": "9e3b73c3-5050-4f42-bc4b-aa6c05a711b8",
          "severity": "WARNING",
          "workflowExecutionId": "01K55F466SQBT41KMQ7PWGEEN3"
        }
      ],
      "workflowStepResults": [
        {
          "stepName": "AML",
          "result": "HIT",
          "summary": {
            "numUnresolvedAdverseMedia": 2,
            "numUnresolvedPEP": 0,
            "numUnresolvedSanction": 0,
            "numUnresolvedWatchlist": 0,
            "providerSummaries": [
                ...
            ],
            "stepName": "AML",
            "totalFalsePositives": 0,
            "totalHits": 2,
            "totalTruePositives": 0,
            "totalUnknown": 0,
            "totalUnresolved": 2
          },
          "processResults": [
            { 
              "processResultId": "pro_01J...",
              "result": "HIT",
              "class": "AML",
              "supplementaryData": {
                "type": "AML",
                "matchData": { "name": "Test Org" },
                "mediaData": [
                  {
                    "additionalData": [
                      {
                        "key": "aml.case_id",
                        "value": "..."
                      },
                      {
                        "key": "aml.search_entity_id",
                        "value": "..."
                      }
                    ],
                    "isCurrent": true,
                    "snippet": "...",
                    "source": "...",
                    "sourceDate": "...",
                    "title": "...",
                    "url": "..."
                  }
                ],
                "manualStatus": "UNRESOLVED"
              }
            }
          ]
        }
      ]
    }
  }
  ```
</Accordion>

***

## Part 1: The Overall Outcome (Final Verdict)

Always start by checking the top-level fields of the `workflowResult` object. These give you the final, authoritative outcome.

| Field                        | Importance | Description                                                                                                             |
| :--------------------------- | :--------- | :---------------------------------------------------------------------------------------------------------------------- |
| **`status`**                 | ‼️         | The conclusive recommendation (e.g., `PASS`, `FAIL`, `REVIEW`). **Base your primary business logic on this value.**     |
| **`workflowExecutionState`** | ‼️         | Confirms the workflow's technical status. **Must be `COMPLETED`**.                                                      |
| **`issues`**                 | ⚠️         | An array of problems that require manual review. If `status` is `REVIEW`, this array contains the specific reasons why. |
| **`riskAssessment`**         | ⚠️         | The final risk profile of the entity, including the `riskLevel` and `riskScore`.                                        |

In the example, the `status` is `REVIEW`, which is directly caused by the `issues` array containing a `MEDIA` issue.

### Understanding AML Issues

When the AML step finds a potential match, it generates an `issue` object. This is what typically drives the overall workflow `status` to `REVIEW`.

| Category | Issue       | Severity  | Trigger Condition                                           |
| :------- | :---------- | :-------- | :---------------------------------------------------------- |
| `AML`    | `PEP`       | `WARNING` | At least one valid Process Result contains `pepData`.       |
| `AML`    | `SANCTIONS` | `WARNING` | At least one valid Process Result contains `sanctionData`.  |
| `AML`    | `MEDIA`     | `WARNING` | At least one valid Process Result contains `mediaData`.     |
| `AML`    | `WATCHLIST` | `WARNING` | At least one valid Process Result contains `watchlistData`. |

***

## Part 2: The AML Step Result (`workflowStepResults`)

Next, drill down into the `workflowStepResults` array and find the object where `stepName` is **`AML`**. This object contains the specific results of the screening.

| Key Field            | Description                                                                                                                                                                             |
| :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`result`**         | The most important field for the step. A `result` of **`HIT`** means at least one potential match was found and requires review. A `result` of **`CLEAR`** means no matches were found. |
| **`summary`**        | An aggregated summary of the screening results, broken down by match type.                                                                                                              |
| **`processResults`** | An array containing the detailed evidence for each individual watchlist match.                                                                                                          |

### The AML Summary Object

The `summary` object gives you a quick, quantitative overview of the screening results.

```json theme={null}
"summary": {
  "numUnresolvedAdverseMedia": 2,
  "numUnresolvedPEP": 0,
  "numUnresolvedSanction": 0,
  "numUnresolvedWatchlist": 0,
  "providerSummaries": [
      {
          ...
      }
  ],
  "stepName": "AML",
  "totalFalsePositives": 0,
  "totalHits": 2,
  "totalTruePositives": 0,
  "totalUnknown": 0,
  "totalUnresolved": 2
  }
```

This summary immediately tells you the scale and severity of the results. For example, `numUnresolvedSanction` highlights if a high-risk sanctions match is present and needs immediate attention.

***

## Part 3: The Process Results (The Raw Evidence)

When an AML step returns a `HIT`, the `processResults` array will contain one or more Process Result Objects (PROs), each with `class: "AML"`. Each PRO represents a single potential match from a watchlist and contains all the data you need for your investigation.

### Anatomy of an AML PRO

The most critical part of an AML PRO is the **`supplementaryData`** object. This is where you will find the details of the matched entity.

| `supplementaryData` Field | Description                                                                                                         |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------ |
| **`matchData`**           | Core information about the matched profile (name, date of birth, countries of association).                         |
| **`pepData`**             | If the match is a Politically Exposed Person, this array contains details about their position, level, and country. |
| **`sanctionData`**        | If the match is on a Sanctions list, this array contains details about the sanction, its source, and the reason.    |
| **`watchlistData`**       | This array contains details for matches on other regulatory or law enforcement watchlists.                          |
| **`mediaData`**           | If the match is from Adverse Media, this array provides snippets and links to relevant news articles.               |
| **`referenceDocs`**       | An array of URLs to source documents for further evidence.                                                          |

<AccordionGroup>
  <Accordion title="Example: A Adverse Media Match PRO">
    This example shows a `processResult` for a `HIT` where the organization has adverse media hits. The `mediaData` array is populated with the specific details of the adverse media matches.

    ```json theme={null}
    { 
      "processResultId": "pro_01J...",
      "result": "HIT",
      "class": "AML",
      "supplementaryData": {
        "type": "AML",
        "matchData": { "name": "Test Org" },
        "mediaData": [
          {
            "additionalData": [
              {
                "key": "aml.case_id",
                "value": "..."
              },
              {
                "key": "aml.search_entity_id",
                "value": "..."
              }
            ],
            "isCurrent": true,
            "snippet": "...",
            "source": "...",
            "sourceDate": "...",
            "title": "...",
            "url": "..."
          }
        ],
        "manualStatus": "UNRESOLVED"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Part 4: Next Steps - Classifying Hits and Re-evaluating

After your compliance team reviews the evidence in the `processResults`, they must classify each hit (e.g., as a `FALSE_POSITIVE`). This is done by updating the `manualStatus` of each PRO.

> **For a detailed guide on how to perform this action via the API, please see our **[AML Screening & Monitoring Documentation](/docs/kyb/anti-money-laundering)**.**

### Updating the Workflow Result

Once all hits have been classified, the workflow needs to be reevaluated so the entity's risk and workflow status reflect the classifications. This is critical for two reasons:

1. **To Update the `status`**: The overall `workflowResult.status` will only change from `REVIEW` to `PASS` or `CLEAR` after the workflow is re-evaluated or re-run and the AML step confirms that no unresolved hits remain.
2. **To Clear `issues`**: The AML step will reassess the issues. If all PROs that previously caused a `MEDIA` issue are now classified as `FALSE_POSITIVE`, the issue will be cleared from the workflow result.

There are two ways to trigger this update:

#### Re-evaluate the Workflow

Call the **evaluate** endpoint. This re-runs the decision and risk assessment steps using existing check results, without triggering new calls to external providers. This ensures the entity's risk and workflow status are updated and the audit trail is accurate.

```http theme={null}
POST /v2/organizations/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/evaluate
```

#### Re-run the Workflow

Call the **execute** endpoint to re-run the full workflow. Unless existing results are within the aging window, this will contact external providers again (e.g., run a new AML search), which incurs additional cost and resets the aging window.

```http theme={null}
POST /v2/organizations/{entityId}/serviceprofiles/{serviceName}/workflows/{workflowName}/execute
```

<Callout icon="triangle-exclamation" color="#FFCA16" iconType="regular">
  Use `/evaluate` when only the decision needs updating based on changed classifications — it is faster, cheaper, and does not call external providers. It re-assesses risk using the entity's existing check results, but does not refresh them. Use `/execute` when the entity's underlying data has changed, or when you need fresh provider results because existing checks have expired beyond the aging window.
</Callout>

### Error Handling

| Scenario                           | Response                                    | Recommended Action                                       |
| :--------------------------------- | :------------------------------------------ | :------------------------------------------------------- |
| No prior workflow execution exists | `400` - "No prior workflow execution found" | Call `/execute` first to run the initial workflow        |
| Entity state is `DUPLICATE`        | `400`                                       | Call evaluate on the surviving entity, not the duplicate |
| Entity state is `BLOCKLISTED`      | `403`                                       | Resolve the blocklist status first                       |
