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

# Visualize a Serial fraud cluster

<Warning>
  **Data segregation — read before sending** `clusterDocuments`

  If you are utilizing a single tenant for **multiple end customers**, it is imperative to be cognizant of the fact that a serial fraud cluster is detected throughout the entire tenant. This implies that `cluster_submission_ids_sample`may encompass submission IDs that are associated with other clients or end-customers, not solely the one currently viewing the result.

  * Only include a document if it pertains to the client who is currently viewing this analysis.
  * Enforce the same access controls that you already apply to the analyzed document.
  * Never expose one client’s document to another client.

  Documents that are not included are simply not displayed, so filtering out submissions that do not belong to the client is a safe practice.
</Warning>

When a result reports **serial fraud**, the analyzed document belongs to a cluster of related documents, which can be viewed together with the currently displayed document for comparison. To achieve this behavior, supply those documents in the `clusterDocuments` attribute.

## **1. Find the serial fraud indicator in the fraud result**

The clustered submission IDs are located within the`/fraud` response that you already retrieve. Within its `indicators`, identify the one whose `indicator_attributes.type` is `"SerialFraudIndicatorAttributes"`. <br />The `indicator_attributes.cluster_submission_ids_sample` attribute lists the submission IDs of the clustered documents.

```jsx theme={null}
// Example: read the clustered submission IDs from the fraud result
function clusterSubmissionIds(fraud) {
  return (fraud.indicators ?? [])
    .filter((i) => i.indicator_attributes?.type === "SerialFraudIndicatorAttributes")
    .flatMap((i) => i.indicator_attributes.cluster_submission_ids_sample ?? []);
}
```

## **2. Prepare the clustered documents**

| Field          | Type          | Description                                                                                   |
| -------------- | ------------- | --------------------------------------------------------------------------------------------- |
| `submissionId` | `string`      | A submission ID from `cluster_submission_ids_sample`.                                         |
| `fraud`        | `string`      | `JSON.stringify()` of that document's own `GET /v2/submission/{submissionId}/fraud` response. |
| `fileData`     | `ArrayBuffer` | That document's original file, exactly as it was submitted.                                   |

Please include only the documents that are accessible in your storage. Documents that are not included will not be displayed. The analyzed document, which is already displayed, should not be included. The parameter `?with_metadata=true` is not required for these requests.

```jsx theme={null}
// Example: collect each clustered document you hold
async function collectClusterDocuments(fraud) {
  const entries = await Promise.all(
    clusterSubmissionIds(fraud).map(async (submissionId) => {
      // Retrieved from your own storage, under your own access controls.
      const fileResp = await fetch(`/files/${submissionId}`);
      if (!fileResp.ok) return null;

      const result = await fetch(`/v2/submission/${submissionId}/fraud`).then((r) => r.json());

      return {
        submissionId,
        fraud: JSON.stringify(result),
        fileData: await fileResp.arrayBuffer(),
      };
    })
  );

  return entries.filter(Boolean);
}
```

## **3. Add the clustered documents to postMessage**

Add the array to the message you already post, and list its buffers alongside `fileData` in the transfer list:

```jsx theme={null}
// Example: bundle the cluster into the render message and transfer every buffer
const clusterDocuments = await collectClusterDocuments(fraudResult);

iframe.contentWindow.postMessage(
  { submissionId, fraud, fileData, clusterDocuments },
  "<OFFLINE_IFRAME_ORIGIN_PROVIDED_BY_RESISTANT_AI>",
  // Transfer list: fileData plus each clustered document's buffer
  [fileData, ...clusterDocuments.map((d) => d.fileData)]
);
```

Cluster documents are applicable to the current submission being displayed. Please resubmit them when you render a different submission.

<Note>
  The `clusterDocuments` function can be utilized to store the files of other documents. To ensure consistent access control, apply the same access controls as those applied to the analyzed document. Additionally, set the `targetOrigin` parameter to the precise iframe origin.
</Note>
