Identify website visitors with Clearbit Reveal and create HubSpot companies using a Claude Code skill
Install this skill
Download the skill archive and extract it into your .claude/skills/ directory.
identify-visitors.skill.zipPrerequisites
This skill works with any agent that supports the Claude Code skills standard, including Claude Code, Claude Cowork, OpenAI Codex, and Google Antigravity.
- One of the agents listed above
- Clearbit Reveal API key (legacy) or HubSpot Breeze Intelligence enabled
- HubSpot private app token with companies read and write scopes
- A file or directory containing visitor IP addresses (server logs, CSV export, etc.)
Why a Claude Code skill?
The other approaches in this guide are deterministic: they run the same logic every time, the same way. An Claude Code skill is different. You give Claude a log file and describe what you want, and the skill gives it enough context to do it reliably.
That means you can say:
- "Identify companies from yesterday's access log"
- "Process this CSV of IPs and only create companies with 200+ employees"
- "How many unique companies visited our pricing page this week?"
The skill contains workflow guidelines, API reference materials, and ICP filtering criteria that the agent reads on demand. When you invoke the skill, Claude reads these files, writes a script on the fly, runs it, and reports results. If you ask for something different next time — a different employee threshold, specific industries only, a read-only summary — the agent adapts without you touching any code.
How it works
The skill directory has three parts:
SKILL.md— workflow guidelines telling the agent what steps to follow, which env vars to use, and what pitfalls to avoidreferences/— Clearbit Reveal API patterns (endpoint, response format, error handling) and HubSpot API patterns (company search, creation)templates/— HubSpot field mapping so companies are created with consistent property names
When invoked, the agent reads SKILL.md, consults the reference files as needed, writes a Python script, executes it, and reports what it found and created. The reference files act as guardrails — the agent knows exactly which endpoints to hit and what the responses look like, so it doesn't have to guess.
What is a Claude Code skill?
An Claude Code skill is a reusable command you add to your project that Claude Code can run on demand. Skills live in a .claude/skills/ directory and are defined by a SKILL.md file that tells the agent what the skill does, when to run it, and what tools it's allowed to use.
In this skill, the agent doesn't run a pre-written script. Instead, SKILL.md provides workflow guidelines and points to reference files — API documentation, field mappings — that the agent reads to generate and execute code itself. This is the key difference from a traditional script: the agent can adapt its approach based on what you ask for while still using the right APIs and field names.
Once installed, you can invoke a skill as a slash command (e.g., /identify-visitors), or the agent will use it automatically when you give it a task where the skill is relevant. Skills are portable — anyone who clones your repo gets the same commands.
Step 1: Create the skill directory
mkdir -p .claude/skills/identify-visitors/{templates,references}This creates the layout:
.claude/skills/identify-visitors/
├── SKILL.md # workflow guidelines + config
├── templates/
│ └── hubspot-field-mapping.md # HubSpot property name mapping
└── references/
├── clearbit-reveal-api.md # Clearbit Reveal endpoint + response format
└── hubspot-companies-api.md # HubSpot company search + creationStep 2: Write the SKILL.md
Create .claude/skills/identify-visitors/SKILL.md:
---
name: identify-visitors
description: Resolve website visitor IPs to companies via Clearbit Reveal and create matching companies in HubSpot
disable-model-invocation: true
allowed-tools: Bash, Read
---
## Goal
Given a log file or CSV of visitor IP addresses, resolve them to companies via Clearbit Reveal, filter for ICP matches, and create new company records in HubSpot.
## Configuration
Read these environment variables:
- `CLEARBIT_API_KEY` — Clearbit Reveal API key (required)
- `HUBSPOT_ACCESS_TOKEN` — HubSpot private app token with companies read/write scopes (required)
Default ICP filter: companies with 50+ employees. The user may request a different threshold or additional filters.
## Workflow
1. Validate that all required env vars are set. If any are missing, print which ones and exit.
2. Extract unique public IPv4 addresses from the input file. Filter out private/reserved ranges (10.x, 172.16-31.x, 192.168.x, 127.x). See `references/clearbit-reveal-api.md` for IP handling notes.
3. For each unique IP, call Clearbit Reveal to resolve it to a company. See `references/clearbit-reveal-api.md` for the endpoint and response format.
4. Deduplicate resolved companies by domain (multiple IPs may resolve to the same company).
5. Filter for ICP matches (default: 50+ employees). Skip companies that don't match.
6. For each ICP-matching company, check if it already exists in HubSpot by domain. See `references/hubspot-companies-api.md`.
7. Create new HubSpot company records using the field mapping in `templates/hubspot-field-mapping.md`.
8. Print a summary: IPs processed, companies resolved, ICP matches, created, already existing.
## Important notes
- Only 20-30% of B2B visitor IPs resolve to a company. Consumer ISPs, VPNs, and mobile carriers always return null. This is expected.
- Each Clearbit Reveal lookup costs 1 credit regardless of whether it resolves. Log credit usage.
- Clearbit returns 404 for unresolvable IPs — handle this gracefully, don't treat it as an error.
- The `company.type` field must equal `"company"` — filter out ISPs and educational institutions.
- HubSpot uses `numberofemployees` (no underscore) as the property name for employee count.
- Add a 100ms delay between Clearbit API calls to respect rate limits.
- Use `urllib.request` for HTTP calls (no external dependencies required).Understanding the SKILL.md
| Section | Purpose |
|---|---|
| Goal | Tells the agent what outcome to produce |
| Configuration | Which env vars to read and what defaults to use |
| Workflow | Numbered steps with pointers to reference files |
| Important notes | Non-obvious context that prevents common mistakes |
The allowed-tools: Bash, Read setting lets the agent both read reference files and execute code. The agent writes its own script based on the workflow steps and reference materials.
Step 3: Add reference files
references/clearbit-reveal-api.md
Create .claude/skills/identify-visitors/references/clearbit-reveal-api.md:
# Clearbit Reveal API Reference
## Resolve an IP to a company
**Request:**
```
GET https://reveal.clearbit.com/v1/companies/find
Authorization: Bearer <CLEARBIT_API_KEY>
```
**Query parameter:** `ip=203.0.113.42`
**Response shape (success):**
```json
{
"ip": "203.0.113.42",
"company": {
"id": "abc123",
"name": "Acme Corp",
"domain": "acmecorp.com",
"type": "company",
"category": {
"industry": "Software",
"sector": "Technology"
},
"metrics": {
"employees": 350,
"raised": 45000000
},
"geo": {
"city": "San Francisco",
"state": "California",
"country": "United States"
},
"description": "Enterprise software company..."
}
}
```
**Response (unresolvable IP):** HTTP 404
## Notes
- Only 20-30% of B2B IPs resolve. Consumer ISPs, VPNs, and mobile carriers return 404.
- Check `company.type` equals `"company"` — ISPs and educational institutions have different types.
- Each lookup costs 1 credit regardless of whether it resolves.
- Rate limit: ~10 requests/second. Add 100ms delay between calls.
- `company.metrics.employees` may be null for very small companies.
- Private/reserved IP ranges never resolve: 10.x, 172.16-31.x, 192.168.x, 127.x — filter these before calling the API.references/hubspot-companies-api.md
Create .claude/skills/identify-visitors/references/hubspot-companies-api.md:
# HubSpot Companies API Reference
## Search companies by domain (deduplication)
```
POST https://api.hubapi.com/crm/v3/objects/companies/search
Authorization: Bearer <HUBSPOT_ACCESS_TOKEN>
Content-Type: application/json
```
Body:
```json
{
"filterGroups": [{"filters": [{
"propertyName": "domain",
"operator": "EQ",
"value": "acmecorp.com"
}]}]
}
```
Returns `results` array — if length > 0, company exists.
## Create a company
```
POST https://api.hubapi.com/crm/v3/objects/companies
Authorization: Bearer <HUBSPOT_ACCESS_TOKEN>
Content-Type: application/json
```
Body:
```json
{
"properties": {
"domain": "acmecorp.com",
"name": "Acme Corp",
"industry": "Software",
"numberofemployees": "350",
"city": "San Francisco",
"state": "California",
"country": "United States",
"description": "Enterprise software company..."
}
}
```
**Important:** `numberofemployees` must be a string, not a number. HubSpot rejects numeric values for this property.
## Notes
- HubSpot allows 150 requests per 10 seconds for general API calls and 5 per second for search.
- Company domain search is case-insensitive.
- For batch creation (100+ companies), use the batch endpoint: POST /crm/v3/objects/companies/batch/create.templates/hubspot-field-mapping.md
Create .claude/skills/identify-visitors/templates/hubspot-field-mapping.md:
# HubSpot Field Mapping
Map Clearbit Reveal fields to HubSpot company properties:
| Clearbit field | HubSpot property | Notes |
|---|---|---|
| `company.domain` | `domain` | Required — skip if null |
| `company.name` | `name` | Required |
| `company.category.industry` | `industry` | May be null |
| `company.metrics.employees` | `numberofemployees` | Must be string, not number |
| `company.geo.city` | `city` | May be null |
| `company.geo.state` | `state` | May be null |
| `company.geo.country` | `country` | May be null |
| `company.description` | `description` | May be null |
**Optional custom properties** (must be created in HubSpot first):
- `website_visitor_source` — set to "Clearbit Reveal"
- `website_visitor_date` — date of the visitor identificationStep 4: Test the skill
Invoke the skill conversationally:
/identify-visitors /var/log/nginx/access.logClaude will read the SKILL.md, check the reference files, write a script, run it, and report the results. A typical run looks like:
Found 847 unique public IPs
Resolving IPs via Clearbit Reveal...
Resolved: 203 companies (24% match rate)
Deduplicated: 156 unique companies
Filtering for ICP (50+ employees)...
ICP matches: 42 companies
Creating HubSpot records...
CREATED: Acme Corp — 350 employees
CREATED: NovaTech Industries — 2,000 employees
EXISTS: Meridian Systems (already in HubSpot)
CREATED: Apex Digital — 180 employees
...
--- Summary ---
IPs processed: 847
Companies resolved: 203 (24%)
ICP matches: 42
Created in HubSpot: 38
Already in HubSpot: 4
Clearbit credits used: 847Because the agent generates code on the fly, you can also make ad hoc requests:
- "Only show companies with 200+ employees, don't create anything" — the agent runs a read-only analysis
- "Process this CSV but only SaaS companies" — the agent adds an industry filter
- "How many unique companies visited our pricing page this week?" — the agent parses for specific page patterns
Each IP lookup costs 1 Clearbit credit. Start with a small sample (50-100 IPs) to verify the skill works correctly before processing a full day's log.
Step 5: Schedule it (optional)
Option A: Cron + Claude CLI
# Run daily at 7 AM to process yesterday's logs
0 7 * * * cd /path/to/your/project && claude -p "Run /identify-visitors /var/log/nginx/access.log.1" --allowedTools 'Bash(*)' 'Read(*)'Option B: GitHub Actions + Claude
name: Identify Website Visitors
on:
schedule:
- cron: '0 8 * * *' # Daily at 8 AM UTC
workflow_dispatch: {}
jobs:
identify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download logs
run: aws s3 cp s3://your-bucket/logs/access.log /tmp/access.log
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- uses: anthropics/claude-code-action@v1
with:
prompt: "Run /identify-visitors /tmp/access.log"
allowed_tools: "Bash(*),Read(*)"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLEARBIT_API_KEY: ${{ secrets.CLEARBIT_API_KEY }}
HUBSPOT_ACCESS_TOKEN: ${{ secrets.HUBSPOT_ACCESS_TOKEN }}Option C: Cowork Scheduled Tasks
Claude Desktop's Cowork supports built-in scheduled tasks. Open a Cowork session, type /schedule, and configure the cadence — hourly, daily, weekly, or weekdays only. Each scheduled run has full access to your connected tools, plugins, and MCP servers.
Scheduled tasks only run while your computer is awake and Claude Desktop is open. If a run is missed, Cowork executes it automatically when the app reopens. For always-on scheduling, use GitHub Actions (Option B) instead. Available on all paid plans (Pro, Max, Team, Enterprise).
Troubleshooting
When to use this approach
- You want to batch-process a log file or CSV of IPs on demand
- You're evaluating visitor identification before committing to Breeze Intelligence pricing
- You need custom ICP filtering beyond what Breeze offers natively
- You want to run tasks in the background via Claude Cowork while focusing on other work
- You want a read-only analysis before committing to creating HubSpot records
When to switch approaches
- You need real-time identification (as visitors land, not in daily batches) → use n8n or Make with webhooks
- You want native HubSpot integration without managing API keys → use Breeze Intelligence
- You have high traffic (1,000+ daily visitors) and need optimized batch processing → use Code + Cron
Common questions
Why not just use a script?
A script runs the same way every time. The Claude Code skill adapts to what you ask — different employee thresholds, industry filters, read-only mode, specific page analysis. The reference files ensure it calls the right APIs even when improvising, so you get flexibility without sacrificing reliability.
Does this use Claude API credits?
Yes. The agent reads skill files and generates code each time. Typical cost is $0.02-0.10 per invocation depending on the number of IPs processed. Clearbit credits are separate — each IP lookup costs 1 credit regardless of whether it resolves.
How many Clearbit credits does a typical run use?
Every unique IP lookup costs 1 credit, even unresolvable ones. A log with 1,000 unique IPs = 1,000 credits. Pre-filter private IPs and known consumer ISP ranges to reduce waste.
Should I use Clearbit Reveal or Breeze Intelligence?
Clearbit was acquired by HubSpot and rebranded as Breeze Intelligence. The standalone API is being sunset. New users should start with Breeze. This skill is useful for existing Clearbit customers and for batch processing historical log data.
Cost
- Claude API — $0.02-0.10 per invocation (the agent reads files and generates code)
- Clearbit Reveal (legacy) — volume-based, typically starting ~$99/mo for 2,500 lookups
- Breeze Intelligence — included with HubSpot Professional+, priced per credit
- HubSpot API — free with any plan that supports private apps
- GitHub Actions (if scheduled) — free tier includes 2,000 minutes/month
Looking to scale your AI operations?
We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.