You’ve set up Leadpipe webhooks. Data is flowing into your endpoint. Payloads are arriving as structured JSON every time a visitor gets identified on your site.
But what does each field actually mean? When is visit_duration more useful than page_url? What’s the difference between a First Match and an Every Update trigger? And which fields should your AI agent actually care about?
This is the complete field reference — every data point Leadpipe sends via webhook, what type it is, what it looks like, and how to use it in your CRM, automation pipeline, or custom AI SDR.
Bookmark this page. You’ll come back to it.
Table of Contents
- Webhook Trigger Types
- Complete Field Reference
- Example Payloads
- Intent Classification Using Fields
- ICP Qualification Using Fields
- Routing Logic
- Configuration Best Practices
- FAQ
Webhook Trigger Types
Before diving into fields, you need to understand when data arrives. Leadpipe supports two webhook trigger modes, and the one you choose determines how much data you receive and how often.
| Trigger | When It Fires | Best For |
|---|---|---|
| First Match | Once per visitor, on first identification | CRM record creation, AI SDR outreach, Clay enrichment |
| Every Update | Every page view from an identified visitor | Behavioral tracking, lead scoring, visit journey mapping |
First Match is the default and what most teams should start with. It fires a single webhook the moment Leadpipe resolves an anonymous visitor into a known person. You get one clean payload per visitor — no duplicates, no noise. This is what you want for CRM enrichment, outreach triggers, and Slack alerts.
Every Update fires on each subsequent page view from an already-identified visitor. This gives you a full session journey but generates significantly more webhook volume. Use it when you need to track multi-page behavior, build real-time lead scoring, or feed granular engagement data into your data layer.
If you’re unsure, start with First Match. You can always switch later.
Complete Field Reference
Here’s every field Leadpipe includes in a webhook payload. All fields are present in every payload, but some may be null when data isn’t available for a particular visitor.
| Field | Type | Example | Description | Use Case |
|---|---|---|---|---|
email | string | jane@acme.com | Visitor’s email address | Primary contact method, CRM lookup, enrichment key |
first_name | string | Jane | First name | Email personalization, CRM record |
last_name | string | Smith | Last name | Email personalization, CRM record |
company_name | string | Acme Corp | Company name | ICP checking, account matching |
company_domain | string | acme.com | Company website domain | Enrichment key, Clay waterfall input |
job_title | string | VP of Marketing | Job title / role | ICP qualification, seniority check, routing |
linkedin_url | string | linkedin.com/in/janesmith | LinkedIn profile URL | Research, connection requests, enrichment |
page_url | string | /pricing | Page the visitor viewed | Intent classification (pricing = high intent) |
visit_duration | number | 180 | Seconds spent on page | Engagement level (>60s = interested) |
referrer | string | google.com/search | Where the visitor came from | Attribution, source tracking |
timestamp | string | 2026-04-01T14:30:00Z | When the visit occurred (ISO 8601) | Timing outreach, freshness scoring |
pages_viewed | array | ["/", "/pricing", "/case-studies"] | All pages visited in session | Journey analysis, intent depth |
city | string | San Francisco | Visitor’s city | Geographic targeting |
state | string | California | Visitor’s state | Territory routing |
country | string | US | Visitor’s country | Compliance routing (GDPR for EU) |
phone | string | +1-415-555-0123 | Phone number (when available) | Direct outreach, CRM enrichment |
A few notes on field behavior:
emailis the most reliable field. Leadpipe uses deterministic matching — no probabilistic guessing — so when an email is present, it’s a real match, not a statistical inference.phonehas lower availability than email. Expect it on roughly 40-60% of identified visitors. Still valuable when present — it’s a direct line.pages_viewedon a First Match trigger contains all pages viewed before identification. On Every Update triggers, it contains the cumulative session journey.visit_durationis measured in seconds. A visitor who spends 240 seconds on your pricing page is telling you something very different from someone who bounced after 8 seconds.countryis critical for compliance. EU visitors should be handled differently under GDPR — Leadpipe provides company-level data only for EU traffic.
Example Payloads
Here are three realistic payloads representing different intent levels. Use these to test your webhook receiver and classification logic.
High-Intent Visitor (Pricing Page, Long Duration)
This person hit the homepage, browsed features, and spent 4 minutes on pricing. They came from a Google search. This is the payload you want your AI agent to act on immediately.
{
"email": "jane.smith@acme.com",
"first_name": "Jane",
"last_name": "Smith",
"company_name": "Acme Corp",
"company_domain": "acme.com",
"job_title": "VP of Marketing",
"linkedin_url": "https://linkedin.com/in/janesmith",
"page_url": "/pricing",
"visit_duration": 240,
"referrer": "google.com",
"timestamp": "2026-04-01T14:30:00Z",
"pages_viewed": ["/", "/features", "/pricing"],
"city": "San Francisco",
"state": "California",
"country": "US",
"phone": "+14155550123"
}
What to do: Trigger immediate outreach. This person is actively evaluating. A personalized email referencing the pricing page within minutes has a 21x higher chance of converting than waiting even an hour.
Medium-Intent Visitor (Blog Reader, Multiple Pages)
A returning visitor reading educational content. They’re researching, not buying — yet. Two blog posts and a case study, 3 minutes total.
{
"email": "mark.chen@globex.io",
"first_name": "Mark",
"last_name": "Chen",
"company_name": "Globex Solutions",
"company_domain": "globex.io",
"job_title": "Head of Growth",
"linkedin_url": "https://linkedin.com/in/markchen",
"page_url": "/blog/visitor-identification-pricing",
"visit_duration": 185,
"referrer": "linkedin.com",
"timestamp": "2026-04-01T09:15:00Z",
"pages_viewed": ["/blog/visitor-identification-pricing", "/blog/rb2b-alternatives", "/case-studies"],
"city": "Austin",
"state": "Texas",
"country": "US",
"phone": null
}
What to do: Add to a 24-hour nurture sequence. Don’t blast them with a sales email while they’re still in research mode. Send something helpful that continues the conversation they’re already having with your content.
Low-Intent Visitor (Homepage Bounce)
Single page, short duration, no phone. They landed, glanced, and left. Still identified — still worth adding to your CRM — but not worth burning outreach tokens on right now.
{
"email": "alex.rivera@startup.co",
"first_name": "Alex",
"last_name": "Rivera",
"company_name": "Startup Co",
"company_domain": "startup.co",
"job_title": "Software Engineer",
"linkedin_url": "https://linkedin.com/in/alexrivera",
"page_url": "/",
"visit_duration": 12,
"referrer": "twitter.com",
"timestamp": "2026-04-01T16:45:00Z",
"pages_viewed": ["/"],
"city": "Denver",
"state": "Colorado",
"country": "US",
"phone": null
}
What to do: Add to CRM as a passive lead. If they return and hit a high-intent page later, the Every Update trigger will catch it.
Intent Classification Using Fields
Here’s a Python function that turns raw webhook fields into an actionable intent score. This is the same pattern used in the AI SDR data stack guide.
def classify_intent(payload):
"""Classify visitor intent from webhook payload fields."""
page = payload.get('page_url', '')
duration = payload.get('visit_duration', 0)
pages = payload.get('pages_viewed', [])
# High intent: pricing/demo pages, or deep + engaged sessions
if any(p in page for p in ['/pricing', '/demo', '/contact']):
return 'high'
elif len(pages) >= 3 and duration > 120:
return 'high'
# Medium intent: evaluating content
elif any(p in page for p in ['/case-stud', '/features', '/integration']):
return 'medium'
elif any('/blog' in p for p in pages) and duration > 90:
return 'medium'
# Low intent: everything else
else:
return 'low'
The logic is simple on purpose. page_url is the strongest signal — someone on /pricing is almost always high intent regardless of duration. visit_duration is the secondary signal — 2+ minutes across 3+ pages shows genuine engagement even if they haven’t hit a conversion page yet.
You can layer in cross-site intent data for even richer classification. A visitor who’s been researching “visitor identification tools” across multiple sites and is on your pricing page? That’s a five-alarm fire.
ICP Qualification Using Fields
Intent without qualification is noise. A student spending 5 minutes on your pricing page isn’t a lead. Combine intent classification with ICP checks using the person and company fields.
# Seniority keywords that indicate decision-maker authority
SENIOR_TITLES = ['vp', 'vice president', 'director', 'head of',
'chief', 'cmo', 'cro', 'ceo', 'coo', 'founder', 'owner']
# Domains to exclude (freemail, competitors, internal)
EXCLUDED_DOMAINS = ['gmail.com', 'yahoo.com', 'hotmail.com',
'outlook.com', 'competitor.com']
def passes_icp(payload):
"""Check if a visitor matches your Ideal Customer Profile."""
title = payload.get('job_title', '').lower()
domain = payload.get('company_domain', '').lower()
country = payload.get('country', '')
# Must have a business email domain
if domain in EXCLUDED_DOMAINS or not domain:
return False
# Must be a decision maker or influencer
if not any(kw in title for kw in SENIOR_TITLES):
return False
# GDPR: company-level only for EU visitors
if country in ['DE', 'FR', 'GB', 'NL', 'ES', 'IT', 'SE', 'BE']:
return False # Route to company-level workflow instead
return True
Now combine them:
def process_webhook(payload):
intent = classify_intent(payload)
is_icp = passes_icp(payload)
if intent == 'high' and is_icp:
return 'immediate_outreach'
elif intent == 'high' and not is_icp:
return 'add_to_crm' # Good intent, wrong profile
elif intent == 'medium' and is_icp:
return 'nurture_24h' # Right profile, still researching
else:
return 'crm_only' # Log it, move on
This two-axis model — intent x qualification — is how the most effective AI SDR pipelines decide what to do with each visitor.
Routing Logic
Once you’ve classified intent and checked ICP fit, route the payload to the right destination. Here’s the decision tree:
Webhook received
└── classify_intent()
├── HIGH + ICP match
│ → Immediate AI outreach (email within minutes)
│ → Slack alert to sales team
│ → Create CRM contact (HubSpot/Salesforce/Pipedrive)
│
├── HIGH + ICP miss
│ → Add to CRM (no outreach)
│ → Tag as "high-intent, non-ICP" for review
│
├── MEDIUM + ICP match
│ → 24-hour delayed nurture sequence
│ → Enrich via Clay waterfall
│ → LinkedIn connection request (optional)
│
└── LOW (any ICP)
→ Add to CRM only
→ Monitor for return visits (Every Update trigger)
The key principle: never waste fast outreach on low-intent visitors, and never waste slow nurture on high-intent ones. A VP of Marketing on your pricing page right now does not need a drip campaign. They need a reply.
For a complete working implementation of this routing logic, see the full AI agent tutorial.
Ready to start receiving these payloads? Sign up for Leadpipe’s free trial — 500 identified leads, no credit card required. You’ll have webhooks firing in under 5 minutes.
Configuration Best Practices
Getting webhooks working is step one. Making them reliable and useful at scale takes a few more considerations.
1. Start with First Match triggers. Every Update is powerful but generates 5-10x more webhook volume. Get your pipeline working with one payload per visitor first, then upgrade when you need session-level granularity.
2. Use narrow segments during testing. Set your webhook to fire only for visitors on specific pages (e.g., /pricing, /demo) while you’re building and debugging your receiver. This keeps volume low and ensures every test payload is high-signal.
3. Return 200 immediately, process asynchronously. Your webhook endpoint should acknowledge receipt instantly and queue the payload for background processing. If your endpoint takes too long to respond, deliveries may time out. Here’s the pattern:
@app.post("/webhook/leadpipe")
async def receive_webhook(request: Request):
payload = await request.json()
# Queue for async processing -- don't block the response
background_tasks.add_task(process_webhook, payload)
return {"status": "received"} # Return 200 immediately
4. Use excluded paths. In your Leadpipe dashboard, exclude pages that will never produce useful leads: /admin, /login, /careers, /support. This reduces noise and saves your identification credits for pages that matter.
5. Monitor delivery health. Leadpipe shows webhook delivery success rates in your dashboard. If your success rate drops below 95%, check your endpoint logs — you probably have a timeout or authentication issue.
6. Implement deduplication. Even with First Match, edge cases can produce near-duplicate payloads (e.g., a visitor identified across two sessions). Keep a simple cache keyed on email with a 7-day TTL.
For the full API and webhook setup walkthrough, including authentication and pixel configuration, see the quickstart guide.
FAQ
Are all fields guaranteed to be present in every payload?
Every field is included in every payload, but some may be null. The email, page_url, timestamp, and pages_viewed fields are always populated. Fields like phone, linkedin_url, and job_title depend on what Leadpipe’s identity graph has for that visitor. Expect email on 100% of payloads, job_title on ~85%, and phone on ~40-60%.
How quickly do webhooks fire after identification?
Typically within seconds. Leadpipe identifies visitors during the active session — the person doesn’t need to leave the page. This means your automation can act while the visitor is still browsing. For AI SDR workflows, this speed is the entire advantage over batch-processed contact lists.
What happens if my endpoint is down?
Leadpipe retries failed webhook deliveries automatically. If your endpoint returns a non-2xx status code or times out, the delivery will be retried with exponential backoff. You can monitor delivery status and retry history in the dashboard. That said, build your endpoint to be resilient — use a managed hosting provider with uptime guarantees (Railway, Render, AWS Lambda) rather than running on a local machine.
Can I receive webhooks for specific pages only?
Yes. Use segments in your Leadpipe dashboard to define which pages trigger webhooks. You can include specific paths (e.g., only /pricing and /demo) or exclude paths (e.g., everything under /blog). This is especially useful during testing or when you want to route different pages to different endpoints.
How does this work with the Leadpipe API?
Webhooks and the REST API are complementary. Webhooks push data to you in real-time (event-driven). The API lets you pull data on demand — query visitor histories, manage pixels programmatically, and integrate identity resolution into your SaaS platform. Most teams use webhooks for real-time actions and the API for backfill, reporting, and platform integrations.
Start Building
This reference covers every field, every trigger type, and the classification logic to turn raw payloads into pipeline. The webhook payload is the raw material. What you build on top of it — AI agents, Clay waterfalls, custom scoring models — that’s where the leverage is.
Start your free trial — 500 identified leads, no credit card required.
Related Articles
- Visitor Identification API: Complete Developer Guide
- Feed Real-Time Visitor Data Into Your AI Agent
- Build a Custom AI SDR With Leadpipe and OpenAI
- Add Identity Resolution to Your SaaS in 10 Minutes
- Leadpipe API in 5 Minutes: Identity Data Made Simple
- How to Add Visitor Identification to Clay Waterfall
- Multi-Tenant Visitor Identification for SaaS Platforms