---
name: moltsets-deanonymize-web-traffic
description: Use this skill when the user has a batch of IP addresses from web traffic and wants to identify the companies behind them and surface likely contacts at those companies.
---

# Deanonymize Web Traffic

Resolve a batch of IP addresses to the companies behind them, then surface likely contacts at each company.

## Triggers

"deanonymise my website visitors", "who are these IPs from my logs", "identify anonymous traffic", "what companies are visiting", "find contacts at companies hitting my site", "resolve my web traffic". Chains IP to company to contacts at that company. Resource-intensive - mandatory credit check before running.

This identifies the **company** behind an IP and **likely contacts** at that company. It does NOT identify the specific individual who visited - there is no IPtoperson resolution.

## Chain

```
IP addresses
  └── ip_to_company                  (per-IP single call to company name + firmographics)
        └── search_people (company domain to ranked contacts at that company)
              └── optional enrich    (per-URL linkedin_to_best_email / linkedin_to_mobile_phone array up to 100)
```

## Set Expectations

Before firing any calls, give the user a brief, dry heads-up. Deadpan over enthusiastic - no filler, no corporate speak. This is the most intensive skill - set realistic expectations without overdramatising.

Facts to work with:
- Sequential rounds: IP to company to contacts at that company to optional enrich
- Each round feeds the next
- Company match is the reliable number; contact volume depends on how many contacts each company returns
- This finds the company and likely contacts - NOT the confirmed visitor
- Time: 60–120+ seconds for any meaningful batch
- Not-found results at each step are free

## Step 1 - Credit check (required)

Call `MoltSets:get_billing` + `MoltSets:get_usage` in parallel (free).

Estimate:
```
N IPs × ip_to_company cost                       = company lookup (one call per IP)
~70% of N (matched companies) × search_people = contact discovery
optional: contacts to enrich × linkedin_to_best_email (one call per URL) / linkedin_to_mobile_phone (array up to 100)
```

Company match is strong; contact discovery and enrichment scale with how many companies match and how many contacts each returns. "Not found" is free.

**If estimated cost > balance:** stop. Report shortfall, how many IPs the balance covers, ask to proceed partially or top up.

## Step 2 - Parse and clean IPs

Accept: line-separated, CSV column, log format. Deduplicate.

**Skip private IPs** (10.x, 192.168.x, 172.16–31.x, 127.x) - tell user these are excluded.

Report: "Processing X unique public IPs."

## Step 3 - Fan out the calls

`ip_to_company` and the email enrich tools take a single input each - fire one call per item in parallel (chunk into manageable parallel waves for large lists). Only `linkedin_to_mobile_phone` accepts a `linkedin_urls` array (max 100).

## Step 4 - Run chain

**Round 1:**
- `MoltSets:ip_to_company` with `ip_address: "<IP>"`, one call per IP in parallel, to company name + firmographics (incl. domain)

**Round 2 - contacts at each company:**
- For each matched company, call `MoltSets:search_people` with `company_domain: "<company domain>"` (or `query: "<company name>"` if no domain). Use `limit` (max 25) and `offset` for pagination.
- `search_people` supports people-level filters: narrow by `seniority`, `department`/`functional_area`, `country`, or `industry` (exact enum values), and use `query` for free-text across name/title/company. `title` and `seniority` also come back as response fields on each record.

**Round 3 (optional enrichment):**
- Collect the `linkedin_url` of the returned contacts
- `MoltSets:linkedin_to_best_email` (or `linkedin_to_business_email`) - one call per `linkedin_url`, fired in parallel
- `MoltSets:linkedin_to_mobile_phone` with `linkedin_urls` array (up to 100) if mobile is needed

## Step 5 - Merge and output

Join contacts back to the company, and the company back to the original IP.

| IP | Company (IP lookup) | Contact Name | Title | Seniority | LinkedIn | Email |
|---|---|---|---|---|---|---|

**Summary:**
```
IPs processed:         200
Company matches:       143  (72%)
Companies w/ contacts: 121  (85% of matched)
Contacts surfaced:     ~480
Credits used:          ~XXX
```

## Edge cases

- These are likely contacts at the company, NOT the confirmed visitor - always frame output this way
- ISP/residential IPs to show under company lookup but note as "Residential/ISP - not a business"; skip contact lookup for these
- No domain returned for a matched company to fall back to `query` (company name) on `search_people`
- Stop immediately if credits run out mid-batch: output completed rows, report exact resume point
- Do not fabricate or infer identities - surface only what the API returns
