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

# Fraud Network

> Check a submission against Heron's fraud network of early defaults, read the result, and test your integration

> [!NOTE]
>
> **Consortium members only.** Heron's fraud network is available to members of the Heron Fraud Consortium, who report their early defaults to help fight fraudsters. It is not enabled by default - contact your Heron rep to enquire about joining the Consortium.

The fraud network scan checks each submission you send against a graph of businesses and people linked to early defaults (\< 10% RTR) reported by consortium members, and to rings Heron has found moving money between businesses. It runs as the `fraud_network_scan` enricher. See the [Fraud Detection overview](https://docs.herondata.io/integrations/fraud-detection/overview.md) for how it fits with broker velocity.

## How the fraud network works

The fraud network is a graph of businesses and people. Businesses enter it in two ways: a consortium member reports an early default, or Heron finds money moving between businesses in a pattern typical of fraud rings. Businesses and people are linked by shared ownership and by money moving between businesses.

A submission is matched on the business and owner details Heron holds for it. A match is one of two kinds:

* **Lone actor** - one owner behind one or more businesses, with no links to businesses under different ownership.
* **Fraud ring** - linked businesses under different owners.

A ring is **confirmed** when it includes a reported early default or an MCA lawsuit on public record, or a Heron analyst has confirmed it. Otherwise it is **suspected**: Heron found the money movement pattern, but no default or lawsuit yet.

The result tells you what Heron concluded about **your applicant's business**. It never identifies other businesses, people, or consortium members (see [What you never see](#what-you-never-see)).

## Integrating

The scan runs inside your Heron workflow on every submission you send, so there is nothing extra to call.

### Prerequisites

* Submissions flowing into Heron, by email or over the API. See the [Quickstart](https://docs.herondata.io/get-started/quickstart.md) to send them over the API.
* The fraud network enabled for your account, with the scan added to your workflow. Contact your Heron rep. Until it is enabled, the fraud network endpoint returns `403`.

### 1. Send the submission

Send the submission with its ISO application as usual. Heron reads the business and owner details from the application and the other documents you send, then runs the scan when your workflow reaches it.

### 2. Act on it in your policy

A match can route the deal to review or decline it. Policies read the **Fraud network finding** variable (`fraud_network_finding`), which is `Fraud ring`, `Lone bad actor` or `No match`, and missing when the scan did not run or had no details to scan with. Ask your Heron rep to add the check and choose whether a match declines or goes to review.

### 3. Read the result

The `enricher.succeeded` [webhook](https://docs.herondata.io/api-reference/webhooks.md) fires when the scan finishes, with `enricher_name` `fraud_network_scan`. Then fetch the result:

```python app.py theme={null}
import requests

BASE_URL = "https://app.herondata.io"
API_KEY = "key_xxxxxxxx"
end_user_heron_id = "eus_xxxxxxxx"

response = requests.get(
    f"{BASE_URL}/api/end_users/{end_user_heron_id}/fraud_detection/fraud_network",
    headers={"x-api-key": API_KEY},
)
response.raise_for_status()
scan = response.json()

finding = scan["features"][0]  # always the fraud_ring_association feature
print(scan["status"], scan["classification"], finding["value"], finding["confidence"])
```

The endpoint returns `404` until a scan has run for the submission, and `403` if the fraud network is not enabled for your account.

## What a flag looks like

The Heron dashboard shows the result on each submission. These are the outcomes you can see.

![Confirmed fraud ring, this business has a reported early default](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/ring-this-business.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=828c84c22e032fb36a2a963663c3d990)

Confirmed ring: this business has a reported early default

![Confirmed fraud ring, directly linked to a business with a reported early default](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/ring-direct.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=a0fc57e0fc0378ba3a5ab240a6f9ebfc)

Confirmed ring: directly linked to a reported early default

![Confirmed fraud ring, linked to a business with a reported early default 4 links away](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/ring-indirect.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=55dea07ef735713900551377cb3baea6)

Confirmed ring: linked to a reported early default several links away

![Suspected fraud ring](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/ring-suspected.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=9938f5e3b0603613bf38a3d23b913078)

Suspected ring: money movement pattern, no default yet

![Lone actor with a reported early default](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/lone-actor.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=d4e3192b72cacc387f1817960e9863f0)

Lone actor: a reported early default, not part of a ring

![No fraud network match](https://mintcdn.com/herondata/sn6ahUSDvt7ns31l/images/fraud-detection/no-match.png?fit=max\&auto=format\&n=sn6ahUSDvt7ns31l\&q=85\&s=c1bdc4ea807557a9bc8fefa3fd64bec3)

No match

## Understanding the fraud network result

| Field | Meaning |
| - | - |
| `status` | `match`, `no_match`, or `insufficient_input` (not enough identity data to scan). |
| `classification` | `fraud_network` or `lone_actor` on a match; `null` otherwise. |
| `ring_status` | `confirmed_fraud` or `suspected` on a match (see [How the fraud network works](#how-the-fraud-network-works)); `null` otherwise. |
| `scanned_at` | When this scan ran. |
| `input_coverage` | Which identity fields were available to match on. |
| `summary` | A `headline` and a plain-English `this_business` line. |
| `not_run_reason` | Why the scan did not run, e.g. sole proprietors are not scanned. `null` when it ran. |
| `ring_evidence` | On a fraud ring match, Heron analysts' decisions on the ring (`kind: reviewer_decision`). Empty otherwise. |
| `features` | Heron's conclusions about your applicant's business. See below. |

`network`, `match_meta` and `matched_node_heron_id` are always `null`, and `businesses`, `people` and `edges` are always empty.

### Features

Each feature is one conclusion about the applicant's business. `subject` is the end user's Heron ID.

| `type` | `value` | Meaning |
| - | - | - |
| `fraud_ring_association` | `in_ring`, `lone_actor`, `none`, `unknown` | Always present, always first. `unknown` when there was not enough identity to scan. |
| `corporate_affiliation` | `linked` | The business shares ownership with a business in the ring. |
| `money_movement` | `linked` | The business moves money with a business in the ring. |

`confidence` is `confirmed_fraud` or `suspected` on a match and `null` otherwise. `evidence` explains the conclusion:

| Field | Meaning |
| - | - |
| `conclusion` | The headline of the scan. |
| `matched_on` | The submitted business fields that matched: `legal_name`, `dba`, `ein`, `address`. Owner fields are never listed. |
| `evidence_kinds` | What the flag rests on: `reported_default`, `mca_lawsuit`, `money_movement`, `heron_review`. |
| `connects_to` | What the ring traces back to: `reported_default` or `mca_lawsuit`. |
| `distance`, `links_away` | How close the business is to it: `this_business` (0 links), `direct` (1) or `indirect` (2+). |
| `link_type`, `business_heron_ids` | On `corporate_affiliation` and `money_movement` features, the kind of link. |
| `money_link_in_your_statements` | `true` when bank statements you submitted show the business's money link to the ring. |

### A fraud ring match

This is the result for the sample ring identity in [Testing your integration](#testing-your-integration). A real match also fills `connects_to`, `distance` and `links_away`.

```json theme={null}
{
  "status": "match",
  "classification": "fraud_network",
  "ring_status": "confirmed_fraud",
  "scanned_at": "2026-11-05T20:36:08+00:00",
  "monitoring_until": null,
  "input_coverage": {
    "legal_name": true, "dba": false, "ein": false, "address": false,
    "owner_name": true, "owner_ssn": false
  },
  "summary": {
    "headline": "Fraud Network Sighting",
    "network": null,
    "this_business": "Submitted identity matched Heron's fraud network.",
    "why_listed": null,
    "seen_elsewhere": null,
    "matched_on": null
  },
  "network": null,
  "matched_node_heron_id": null,
  "match_meta": null,
  "businesses": [],
  "people": [],
  "edges": [],
  "ring_evidence": [],
  "not_run_reason": null,
  "features": [
    {
      "type": "fraud_ring_association",
      "subject": "eus_xxxxxxxx",
      "value": "in_ring",
      "confidence": "confirmed_fraud",
      "evidence": {
        "conclusion": "Fraud Network Sighting",
        "link_type": null,
        "business_heron_ids": [],
        "connects_to": null,
        "distance": null,
        "links_away": null,
        "matched_on": ["legal_name"],
        "evidence_kinds": ["reported_default", "money_movement"],
        "money_link_in_your_statements": false
      },
      "visibility": "member"
    },
    {
      "type": "money_movement",
      "subject": "eus_xxxxxxxx",
      "value": "linked",
      "confidence": "confirmed_fraud",
      "evidence": {
        "conclusion": "Fraud Network Sighting",
        "link_type": "money_movement",
        "business_heron_ids": [],
        "connects_to": null,
        "distance": null,
        "links_away": null,
        "matched_on": [],
        "evidence_kinds": [],
        "money_link_in_your_statements": false
      },
      "visibility": "member"
    }
  ]
}
```

### A lone actor match

This is the result for the sample lone actor identity. Only the fields that differ from a ring match are shown.

```json theme={null}
{
  "status": "match",
  "classification": "lone_actor",
  "ring_status": "confirmed_fraud",
  "summary": {
    "headline": "Lone Actor Sighting",
    "this_business": "Submitted identity matched Heron's fraud network."
  },
  "features": [
    {
      "type": "fraud_ring_association",
      "subject": "eus_xxxxxxxx",
      "value": "lone_actor",
      "confidence": "confirmed_fraud",
      "evidence": {
        "conclusion": "Lone Actor Sighting",
        "link_type": null,
        "business_heron_ids": [],
        "connects_to": "reported_default",
        "distance": "this_business",
        "links_away": 0,
        "matched_on": ["legal_name"],
        "evidence_kinds": ["reported_default"],
        "money_link_in_your_statements": false
      },
      "visibility": "member"
    }
  ]
}
```

### No match

```json theme={null}
{
  "status": "no_match",
  "classification": null,
  "ring_status": null,
  "summary": {
    "headline": "No fraud network match",
    "this_business": "Legal name and owner name checked against Heron's fraud network. No match."
  },
  "features": [
    {
      "type": "fraud_ring_association",
      "subject": "eus_xxxxxxxx",
      "value": "none",
      "confidence": null,
      "evidence": {
        "conclusion": "No fraud network match",
        "link_type": null,
        "business_heron_ids": [],
        "connects_to": null,
        "distance": null,
        "links_away": null,
        "matched_on": [],
        "evidence_kinds": [],
        "money_link_in_your_statements": false
      },
      "visibility": "member"
    }
  ]
}
```

A scan reflects the fraud network at the moment it runs. To check a submission again later, trigger the enricher again.

## Testing your integration

You can test every outcome without real data. Two reserved identities return a sample match, and any other made-up identity runs live matching and returns `no_match`. Sample matches create no records in the fraud network.

| Outcome | Business legal name | Owner first name | Owner last name | Result |
| - | - | - | - | - |
| Fraud ring | `HERON SANDBOX FRAUD RING LLC` | `HERON SANDBOX` | `FRAUD RING` | `status=match`, `classification=fraud_network` |
| Lone actor | `HERON SANDBOX LONE ACTOR LLC` | `HERON SANDBOX` | `LONE ACTOR` | `status=match`, `classification=lone_actor` |
| No fraud | Any other made-up name | Any | Any | `status=no_match` |

**1. Create the end user**

```json theme={null}
POST /api/end_users
{"end_user": {"end_user_id": "sandbox-fraud-test-001", "name": "HERON SANDBOX FRAUD RING LLC"}}
```

Use an `end_user_id` you have not used before. Copy `end_user.heron_id` from the response.

**2. Set the business and owner names**

Upload an ISO application with these names, or send them over the API:

```json theme={null}
PATCH /api/end_users/{heron_id}/end_user_information
{
  "company_legal_business_name": "HERON SANDBOX FRAUD RING LLC",
  "owner_1": {"first_name": "HERON SANDBOX", "last_name": "FRAUD RING"}
}
```

Send only the names.

**3. Start the workflow and read the result**

Start the workflow (`POST /api/end_users/{heron_id}/start_workflow`), then [read the result](#3-read-the-result).

If the endpoint returns `403`, the fraud network is not enabled for your account yet. Contact your Heron rep.

## What you never see

The Consortium exists to fight fraud while preserving privacy. Every response is limited to Heron's conclusions about your own applicant's business:

* **No other businesses or people.** Names, identifiers, addresses and owners of anyone else in the network are never returned. A `corporate_affiliation` feature lists linked businesses by Heron ID only.
* **No other members.** Consortium members are never named or counted, and nothing a member wrote when reporting a default is returned.
* **No ring details.** Ring size and amounts are not returned.
* **Owner matches stay private.** `matched_on` lists only business fields, even when an owner matched.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.