---
updatedAt: 2025-12-11T15:17:25.000Z
agentTools:
  projectIndex: https://docs.getfastah.com/llms.txt
---

# Detecting financial fraud with Neo4j

Building geolocation-enriched graphs using IP metadata.

Online insurance applications generate a trail of events—submissions, underwriting decisions, payments—each tagged with an IP address. By enriching these events with [Fastah IP geolocation](/reference/get-ip-geolocation) and loading them into Neo4j, you can detect fraud patterns that tabular data would hide.

This guide extends [Neo4j's fraud detection documentation](https://neo4j.com/use-cases/fraud-detection/) by adding privacy-safe geographic attributes to application events. When submission and payment originate from distant locations—or cluster with known bad actors—you can trigger a human review.

<Image align="center" alt="Neo4j fraud ring illustration" border={true} caption="Graph relationships reveal fraud rings that tabular queries miss. Source: Neo4j." src="https://dist.neo4j.com/wp-content/uploads/20250211140915/fraud-ring-v2.svg" />

### The fraud pattern

Each insurance application generates events with IP addresses:

* `applicationSubmitted` — applicant submits from IP address A
* `paymentMade` — payment arrives from IP address B

If the distance between A and B exceeds a threshold (e.g., 500 km), flag for review.

**Event schema:**

| Field                   | Description                                                |
| ----------------------- | ---------------------------------------------------------- |
| `customerApplicationId` | Unique application identifier (e.g., `INSURE-ME-1708`)     |
| `eventtype`             | Either `applicationSubmitted` or `paymentMade`             |
| `timestamp`             | Unix epoch milliseconds                                    |
| `ip`                    | Public IPv4 address                                        |
| `locationData.lat`      | Latitude from [Fastah API](/reference/get-ip-geolocation)  |
| `locationData.lng`      | Longitude from [Fastah API](/reference/get-ip-geolocation) |

### Load geolocated events into Neo4j

This Cypher query ingests Fastah API responses, creates `IPAddress` nodes with spatial points, and links them to `Application` nodes:

```cypher
// Ingest events and create graph structure
UNWIND [
  {
    ip: "15.220.176.1",
    timestamp: 1705124935277,
    eventtype: "paymentMade",
    customerApplicationId: "INSURE-ME-1708",
    locationData: { lat: 39.04, lng: -77.49 }
  },
  {
    ip: "13.107.54.1",
    timestamp: 1706199630411,
    eventtype: "applicationSubmitted",
    customerApplicationId: "INSURE-ME-1708",
    locationData: { lat: 47.61, lng: -122.33 }
  }
] AS event

// Create IP node with Neo4j spatial point (SRID 4326)
MERGE (ip:IPAddress { ip: event.ip })
SET ip.location = point({
  latitude: event.locationData.lat,
  longitude: event.locationData.lng
})

// Create application node
MERGE (app:Application { id: event.customerApplicationId })

// Link based on event type
FOREACH (_ IN CASE WHEN event.eventtype = "applicationSubmitted" THEN [1] ELSE [] END |
  MERGE (app)-[:SUBMITTED_FROM { timestamp: event.timestamp }]->(ip)
)
FOREACH (_ IN CASE WHEN event.eventtype = "paymentMade" THEN [1] ELSE [] END |
  MERGE (app)-[:PAID_FROM { timestamp: event.timestamp }]->(ip)
)
```

> In production, stream events from your application or ETL pipeline rather than hard-coding them.

### Detect suspicious applications

Find applications where submission and payment IPs sit far apart:

```cypher
// Find applications with >500 km between submission and payment locations
MATCH (app:Application)-[:SUBMITTED_FROM]->(submitIp:IPAddress),
      (app)-[:PAID_FROM]->(payIp:IPAddress)
WITH app,
     submitIp,
     payIp,
     point.distance(submitIp.location, payIp.location) / 1000.0 AS distanceKm
WHERE distanceKm > 500
RETURN app.id AS applicationId,
       round(distanceKm) AS distanceKm,
       submitIp.ip AS submittedFromIp,
       payIp.ip AS paidFromIp
ORDER BY distanceKm DESC
```

The `point.distance()` function returns meters, so we divide by 1000 for kilometers.

### Visualize with Neo4j Bloom

Use [Neo4j Bloom](https://neo4j.com/product/bloom/) to explore relationships between applications and shared IP addresses:

<Image align="center" border={false} caption="Multiple applications sharing the same IP address and/or a geographical cluster may trigger a review" src="https://files.readme.io/8673c413ef1d39e0ecf90d36e639056f22fe81ba53915cdb437ecc007825316f-visualisation.png" />

Neo4j's graph structure reveals patterns you'd miss in tabular data—such as fraud rings where multiple applications share IP addresses, or account takeovers where submission and payment originate from different continents.