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

# IP Enrichment

> Every transaction is enriched with IP context: country, ASN, VPN/Tor, data center, carrier. Real-time and rule-ready. Pay-per-call $0.02 per transaction.

Every transaction that includes a device IP address is enriched server-side in real time before rules evaluate it. Enrichment adds country, city, VPN/Tor/data-center flags, ASN, and carrier — all available as rule conditions.

## When enrichment runs

Inline during transaction creation:

1. You submit `POST /v3/transactions/` with `applicant.device.ip` (or any party's device IP).
2. Didit looks up the IP in an in-memory cache (24-hour TTL).
3. If not cached, checks the shared IP-enrichment table (\~30-day freshness).
4. If stale or missing, resolves the IP through Didit's enrichment pipeline with multi-provider failover.
5. Enriched fields are written back to the transaction record and made available to rules.

Enrichment is **inline** — it completes before rules run — but **non-blocking on failure**. If enrichment cannot complete, the transaction still goes through; the IP simply appears without enrichment data.

## Enriched fields

| Field                   | Description                                             |
| ----------------------- | ------------------------------------------------------- |
| `ip_country`            | Country name                                            |
| `ip_country_code`       | ISO 3166-1 alpha-3                                      |
| `ip_state`              | Subdivision (state, region)                             |
| `ip_city`               | City name                                               |
| `latitude`, `longitude` | Geographic coordinates                                  |
| `isp`                   | Internet service provider name                          |
| `organization`          | Registering organization name                           |
| `is_vpn_or_tor`         | Boolean — the IP is a known VPN or Tor exit             |
| `is_data_center`        | Boolean — the IP belongs to a hosting/data-center range |
| `time_zone`             | IANA time zone (e.g. `America/New_York`)                |
| `time_zone_offset`      | Offset from UTC                                         |
| `asn_number`            | Autonomous System Number                                |
| `asn_organization`      | ASN's registered organization                           |
| `connection_type`       | `mobile`, `broadband`, `dialup`, `corporate`, ...       |
| `carrier`               | Mobile carrier (for mobile IPs)                         |
| `proxy_type`            | `VPN`, `TOR`, `PUBLIC_PROXY`, or null                   |

## Using enriched fields in rules

Any of the enriched fields can be a [rule condition](/transaction-monitoring/rules). Common patterns:

**High-risk jurisdiction by IP**

```
condition: applicant.ip_country_code IN ['IRN', 'PRK', 'SYR']
action: add_score(35), add_tags(['high_risk_ip_country'])
```

**VPN / Tor usage**

```
condition: applicant.is_vpn_or_tor == true
action: change_status('IN_REVIEW'), add_tags(['anonymization'])
```

**Data center / non-residential origin**

```
condition: applicant.is_data_center == true AND amount > 10000
action: add_score(30)
```

**IP country ≠ KYC country**

```
condition: applicant.ip_country_code != applicant.country_code
action: add_score(15), add_tags(['geo_mismatch'])
```

## Cache layers

| Layer                      | TTL       | Purpose                                            |
| -------------------------- | --------- | -------------------------------------------------- |
| In-memory cache            | 24 hours  | Sub-millisecond lookup for hot IPs                 |
| Shared IP-enrichment table | \~30 days | Shared across instances; cheaper than re-resolving |
| Enrichment pipeline        | n/a       | Fresh data when nothing else has it                |

Hits on the first two layers don't cost you anything extra. Fresh resolutions may be metered — see your billing console.

## Failure behavior

* Transaction creation **never fails** because enrichment failed.
* Missing enrichment fields simply don't match any rule conditions that reference them.
* Alerts about stuck enrichment are surfaced to your ops team via internal monitoring; no customer-facing impact.

## Validity filtering

Non-routable IPs are skipped before enrichment:

* Private (10/8, 172.16/12, 192.168/16)
* Loopback (127/8)
* Link-local (169.254/16)
* Multicast, unspecified

These save provider quota and avoid nonsense enrichment data.

## Inspecting enrichment for a transaction

**Via API.** The transaction response includes an `ip_enrichment` block:

```json theme={null}
"applicant": {
  "vendor_data": "user-42",
  "device": { "ip": "203.0.113.5" },
  "ip_enrichment": {
    "ip_country": "United States",
    "ip_country_code": "USA",
    "ip_state": "California",
    "ip_city": "San Francisco",
    "is_vpn_or_tor": false,
    "is_data_center": false,
    "asn_number": 15169,
    "asn_organization": "Google LLC",
    "proxy_type": null
  }
}
```

**In the console.** The transaction detail page shows IP enrichment in the **IP & Device** tab with a geo-map pin.

## Privacy considerations

* Raw IPs are stored with the transaction.
* Enrichment data lives on a shared IP-keyed table — not per user.
* Right-to-be-forgotten deletion removes IPs from the transaction; the shared cache entry remains (it's not personally identifying).

## Next steps

<CardGroup cols={3}>
  <Card title="Rules" icon="scale-balanced" href="/transaction-monitoring/rules">
    Use enriched fields in conditions.
  </Card>

  <Card title="Rule library" icon="books" href="/transaction-monitoring/rules-library">
    Preset IP-based rules.
  </Card>

  <Card title="Response schema" icon="file-lines" href="/transaction-monitoring/response-schema">
    Where IP enrichment appears.
  </Card>
</CardGroup>
