LinkedIn Ads is the most expensive traffic source in B2B — and most teams running it are paying to reach people who will never buy. The CPM is high, the match rates are inconsistent, and the audience targeting that LinkedIn offers natively is broad enough to include everyone adjacent to your ICP but not precise enough to exclude the 60 percent of impressions that have zero commercial relevance. The teams winning on LinkedIn are not the ones with bigger budgets. They are the ones who have solved the audience quality problem — who have built a pipeline from behavioral signals to verified decision-maker contact data to matched audience creation that runs automatically, updates continuously, and wastes zero ad spend on contacts outside the ICP. That pipeline is built in Clay.
This post documents the complete end-to-end architecture: from social engagement signal capture through enrichment waterfall, ICP filtering, LinkedIn Matched Audience sync, engagement tracking, automated follow-up sequencing, and the retargeting layer that converts website visitors into identified, enriched contacts in matched audiences before they have finished reading your pricing page. Every step is specific — the Clay table structures, the enrichment provider logic, the conditional filter formulas, the LinkedIn Campaign Manager field mappings, and the webhook architecture that closes the loop from ad engagement back into the CRM and outbound sequences.
This is not a Clay tutorial. It is an ABM system architecture document — written for the operator who needs to understand why each component is built the way it is, not just what to click. The decisions matter as much as the steps. Get the architecture right, and the system compounds. Get it wrong, and you have an expensive enrichment workflow that produces a low-match-rate audience and a LinkedIn rep asking why your CTRs are below benchmark.
Before building anything in Clay, the full system architecture must be clear. Clay is a powerful tool for operators who know what they are building and a very expensive confusion machine for operators who start building before they have mapped the data flow. The architecture has three distinct loops: the social signal loop (engagement on LinkedIn content → enriched contact → matched audience), the retargeting loop (website visit → visitor identification → enriched contact → matched audience → personalized ad), and the activation loop (ad engagement → CRM notification → outbound sequence → retargeting audience). Each loop feeds the next. The contacts who engage with ads in Loop 1 become the retargeting subjects in Loop 2. The retargeting subjects who convert in Loop 2 become the high-intent signals that trigger outreach in Loop 3.
FULL ABM SYSTEM ARCHITECTURE — THREE CONNECTED LOOPS
──────────────────────────────────────────────────────────────────
LOOP 1: SOCIAL SIGNAL → ENRICHED AUDIENCE → LINKEDIN AD
LinkedIn Content Engagement
(own posts, competitor posts, thought leader content)
│
▼
Clay Social Listening Table
(profile URLs extracted from engagements)
│
▼
Enrichment Waterfall
(LinkedIn profile → contact data → email → ICP validation)
│
▼
ICP Filter Layer
(conditional formulas: title, company size, industry, seniority)
│
▼
LinkedIn Matched Audience Sync
(Clay native export → Campaign Manager Matched Audience)
│
▼
LinkedIn Ads Served to Verified Decision-Makers
│
▼
Ad Engagement Signals → LOOP 3
──────────────────────────────────────────────────────────────────
LOOP 2: WEBSITE VISIT → IDENTIFIED VISITOR → RETARGETING AD
Website Visitor (anonymous session)
│
▼
Visitor Identification Layer
(Clearbit Reveal / RB2B / 6sense snippet on site)
│
▼
Clay Webhook Receiver
(visitor company + IP + page visited → Clay table row)
│
▼
Enrichment + Contact Identification
(company → find decision-makers → enrich contact data)
│
▼
Page-Intent Segmentation
(pricing page visitor ≠ blog visitor → different ad creative)
│
▼
LinkedIn Matched Audience Sync
(page-specific audiences: Pricing Visitors, Demo Visitors, etc.)
│
▼
Personalized LinkedIn Retargeting Ads Served
│
▼
Ad Engagement Signals → LOOP 3
──────────────────────────────────────────────────────────────────
LOOP 3: AD ENGAGEMENT → CRM ALERT → OUTREACH SEQUENCE
LinkedIn Ad Click / Video View / Form Fill
│
▼
LinkedIn Insight Tag + Conversion Event
(fires to Clay webhook via Zapier/Make bridge)
│
▼
Clay Engagement Enrichment Table
(match engagement signal to existing enriched contact record)
│
▼
Intent Score Update
(ad click +20pts, form fill +50pts, pricing page visit +35pts)
│
▼
Threshold Trigger (score ≥ 70)
│
├── CRM Notification (Slack alert to AE: "High-intent account")
│
├── Sequence Enrollment (Clay → Instantly/Smartlead HTTP action)
│
└── Retargeting Audience Update (add to "Hot Accounts" segment)
The first Clay table in the workflow is the signal capture layer. Its job is to convert engagement activity on LinkedIn — reactions, comments, reposts on your content, competitor content, and industry thought leader posts — into a structured list of LinkedIn profile URLs that can be enriched in the next step. The data quality at this layer determines everything downstream: garbage signals in produce an enrichment waterfall that burns Clay credits on non-ICP contacts and a matched audience with poor signal-to-noise ratio.
Not all engagement signals are equal. A reaction to a thought leader post in a broad industry category tells you the person is interested in the topic. A comment on a competitor's product announcement tells you the person is actively evaluating that category right now. A reaction to your own post tells you they are already aware of your brand. The signal hierarchy matters because it determines the sequence type and ad creative that the contact receives downstream — and because over-capturing signals (pulling everyone who ever reacted to any tangentially relevant content) dilutes the ICP match rate at enrichment and costs Clay credits on contacts who are definitively outside the ICP before any enrichment runs.
signal_source = "own_content". These contacts get the shortest follow-up delay in Loop 3.signal_source = "competitor_content". These contacts enter the "competitive displacement" sequence track in Loop 3.signal_source = "thought_leader". Apply tighter ICP title filter before enrichment runs.The signal capture table in Clay has one job: ingest profile URLs from all three signal tiers, deduplicate against existing records, tag the source tier, and pass clean rows to the enrichment table. The deduplication is critical — the same person may react to your content in week one and a competitor's content in week two. Without deduplication logic, you enrich the same contact twice, waste Clay credits, and potentially enroll them in two different sequences from the same company, which is operationally embarrassing at scale.
CLAY SIGNAL CAPTURE TABLE — STRUCTURE
──────────────────────────────────────────────────────────────────
TABLE NAME: 01_Signal_Capture
COLUMNS:
linkedin_profile_url (text) — primary dedup key
signal_source (text) — own_content / competitor / thought_leader
signal_type (text) — react / comment / repost
source_post_url (text) — which post triggered the signal
engagement_date (date) — when the engagement occurred
extraction_batch_id (text) — which weekly extraction run added this row
dedup_status (formula) — see dedup logic below
enrichment_status (text) — pending / complete / failed / skipped_non_icp
days_since_engagement (formula) — TODAY() - engagement_date
DEDUP FORMULA (dedup_status column):
IF(
COUNTIF(linkedin_profile_url_column, [linkedin_profile_url]) > 1,
"DUPLICATE — skip enrichment",
"UNIQUE — proceed"
)
Implementation in Clay: use Clay's native deduplication on
linkedin_profile_url column — set to "Skip if URL already exists
in table" on the Phantombuster import action.
STALENESS FILTER:
IF(days_since_engagement > 21, "STALE — skip", "ACTIVE")
Contacts who engaged more than 21 days ago are deprioritized —
LinkedIn ad matching for content engagement drops significantly
after 3 weeks. Skip enrichment credits on stale signals.
ROW VOLUME MANAGEMENT:
Expected weekly ingestion: 50–300 rows per active signal source
Clay credits per enrichment run: varies by provider (see Step 2)
Budget control: set a weekly enrichment credit cap in Clay settings
→ If cap reached before all rows enriched: prioritize Tier 01 > Tier 02 > Tier 03
The enrichment waterfall is the most credit-intensive step in the workflow and the one with the most consequential design decisions. Every enrichment provider has a different coverage rate for different contact profiles. Running them in the wrong order wastes credits on expensive providers for contacts that a cheap provider would have resolved, or — worse — exhausts the cheap providers on contacts that require the expensive one. The waterfall sequence is an optimization problem: maximize data coverage while minimizing credit spend, filtered by ICP validation logic that stops enrichment the moment a contact is confirmed to be outside the ICP.
ENRICHMENT WATERFALL — CLAY TABLE 02_Enrichment
──────────────────────────────────────────────────────────────────
INPUT: linkedin_profile_url from 01_Signal_Capture (status = UNIQUE + ACTIVE)
PASS 1 — LINKEDIN PROFILE SCRAPE (Clay native: LinkedIn Lookup)
Cost: ~1 Clay credit per row
Data retrieved: Full Name, Current Title, Current Company,
Company LinkedIn URL, Location, Connections count
Immediate ICP pre-filter (before any further enrichment runs):
→ Title NOT IN [ICP_title_exclusion_list]:
"Intern", "Student", "Coordinator", "Assistant",
"Junior", "Entry Level", "Freelance"
→ Company size signals: if available, confirm not below minimum
→ IF pre-filter FAILS: set enrichment_status = "skipped_non_icp"
STOP enrichment — no further credits spent
→ IF pre-filter PASSES: proceed to Pass 2
PASS 2 — COMPANY ENRICHMENT (Clay native: Company Lookup via LinkedIn URL)
Cost: ~1 Clay credit per row
Data retrieved: Company Name, Industry, Employee Count (range),
HQ Country, Company Website, Funding Stage,
LinkedIn Company ID, Tech Stack (if available)
ICP company filter:
→ industry IN [ICP_industry_list]: required
→ employee_count between [min_headcount] and [max_headcount]: required
→ funding_stage IN [acceptable_stages] (if funding is an ICP signal): optional
→ IF company filter FAILS: enrichment_status = "skipped_non_icp" — STOP
→ IF company filter PASSES: proceed to Pass 3
PASS 3 — EMAIL ENRICHMENT (waterfall across providers)
Provider 1: Apollo.io (Clay integration)
Cost: ~2–3 Clay credits per row
Coverage: strong for US/EU B2B, SaaS, tech
Attempt: find work email by name + company domain
→ IF email found AND deliverability = "valid": set primary_email, STOP pass
→ IF email found AND deliverability = "risky": flag for manual review
→ IF email not found: proceed to Provider 2
Provider 2: Hunter.io (Clay integration)
Cost: ~2 Clay credits per row
Coverage: strong for companies with discoverable email patterns
→ IF email found AND Hunter confidence ≥ 85: set primary_email, STOP
→ IF not found or low confidence: proceed to Provider 3
Provider 3: Findymail (Clay HTTP action)
Cost: ~3–4 credits per row
Coverage: best for hard-to-find contacts, strong EU coverage
→ IF email found: set primary_email, email_source = "findymail"
→ IF not found: set primary_email = null, flag for LinkedIn URL match only
Note on LinkedIn URL-only contacts:
LinkedIn Matched Audiences accepts LinkedIn Profile URLs as a
match input — contacts without email can still enter the ad audience
via profile URL matching. Email is required for sequence enrollment
in Loop 3, not for LinkedIn audience matching in Loop 1.
PASS 4 — PHONE NUMBER ENRICHMENT (conditional — only for high-intent accounts)
Trigger: signal_source = "own_content" AND company_employee_count ≥ 500
Provider: Datagma or Lusha (Clay integration)
Cost: 5–8 Clay credits per row — only run on highest-value targets
→ Phone stored in E.164 format on contact record
→ Used for SDR outreach in Loop 3, not for LinkedIn matching
──────────────────────────────────────────────────────────────────
OUTPUT PER ROW (post-waterfall):
full_name → "Sarah Chen"
current_title → "VP of Revenue Operations"
current_company → "Meridian SaaS Inc."
company_domain → "meridiansaas.com"
company_industry → "Software & Technology"
company_size_range → "201-500"
primary_email → "sarah.chen@meridiansaas.com"
email_deliverable → "valid"
linkedin_url → "linkedin.com/in/sarahchen-revops"
icp_match_score → 87
signal_source → "competitor_content"
enrichment_source → "apollo"
enrichment_date → "2025-10-14"
The ICP match score is a calculated column in the Clay enrichment table that assigns a numerical confidence value to each contact's fit against the ICP definition. It is not a binary pass/fail — it is a score from 0 to 100 that drives downstream logic: contacts scoring above 80 go directly to LinkedIn audience sync and Loop 3 trigger; contacts scoring 60–80 go to LinkedIn audience but not to immediate sequence enrollment; contacts scoring below 60 are excluded from both. The score formula is implemented as a Clay formula column that references the enriched data fields.
| ICP Criterion | Points if Met | Clay Column Referenced | Typical ICP Values (customize per account) |
|---|---|---|---|
| Seniority Level | +30 | current_title |
VP, Director, Head of, C-Suite, SVP, EVP. Exclude: Manager, Specialist, Analyst (unless explicitly in ICP). Formula: IF(CONTAINS(title, ["VP","Director","Head of","Chief","SVP","EVP"]), 30, IF(CONTAINS(title, ["Manager","Lead"]), 15, 0)) |
| Company Size | +25 | company_size_range |
201–500, 501–1000, 1001–5000. Full points for core ICP range. Partial points for adjacent ranges. Zero for SMB or Enterprise if outside ICP. |
| Industry Match | +20 | company_industry |
Target industries defined per account. Full points for primary ICP industry. Half points for adjacent industry. Zero for out-of-ICP industry. |
| Signal Source Tier | +15 | signal_source |
own_content = 15pts, competitor_content = 12pts, thought_leader = 8pts. Higher signal source indicates warmer awareness. |
| Email Deliverability | +10 | email_deliverable |
valid = 10pts, risky = 5pts, null (LinkedIn URL only) = 0pts. Not an ICP filter — a data quality signal that affects sequence enrollment eligibility. |
LinkedIn Matched Audiences accepts three match inputs: email address, LinkedIn Profile URL, and first name + last name + company name combination. The match rate varies significantly by input type — LinkedIn Profile URL matching achieves the highest match rate (typically 85–95% when the URL is current) because it is a direct identifier within LinkedIn's own system. Email matching typically achieves 50–70% match rates for B2B emails because LinkedIn's member profiles may use personal emails rather than work emails, creating a mismatch between the enriched work email and the LinkedIn account email. First/last/company matching achieves the lowest rates (30–50%) due to name variations and company naming inconsistencies.
The practical implication for this build: always prioritize LinkedIn Profile URL as the primary match field in the LinkedIn Matched Audience configuration, with email as the fallback. The enrichment waterfall above captures the LinkedIn URL from the signal capture step — it already exists on every row because the signal capture starts with profile URLs. The email enrichment in Pass 3 enriches the contact for sequence enrollment in Loop 3, not as the primary LinkedIn matching field.
DATA CLEANING PIPELINE — BEFORE LINKEDIN AUDIENCE EXPORT
──────────────────────────────────────────────────────────────────
TABLE: 03_LinkedIn_Export_Ready
INPUT: Rows from 02_Enrichment where icp_match_score ≥ 60
CLEANING STEPS (Clay formula columns):
1. LINKEDIN URL NORMALIZATION
Input variations:
"https://www.linkedin.com/in/sarahchen-revops/"
"linkedin.com/in/sarahchen-revops"
"https://linkedin.com/in/sarahchen-revops?utm_source=..."
Normalized formula:
→ Strip https:// prefix
→ Strip www. prefix
→ Strip trailing slash
→ Strip all URL parameters (everything after ?)
→ Final format: "linkedin.com/in/sarahchen-revops"
LinkedIn requires this exact format for profile URL matching.
A URL with trailing slash or UTM parameters fails the match.
2. EMAIL CLEANING
→ Convert to lowercase (LOWER() function)
→ Trim whitespace (TRIM() function)
→ Validate format: contains @ AND contains . after @
→ Remove if domain = company's own domain (internal contacts)
→ Remove role-based emails: info@, sales@, hello@, admin@, support@
(these are not personal contacts — LinkedIn match will fail)
3. NAME NORMALIZATION (for first/last/company fallback matching)
→ PROPER() on first_name and last_name (capitalize correctly)
→ Trim any middle initials or suffixes from last_name
(LinkedIn matching on "Chen MBA" fails; "Chen" matches)
→ company_name: use official LinkedIn company name
NOT the website URL, NOT the BC Customer name variant
4. CONDITIONAL EXPORT FILTER (formula column: export_ready)
IF(
linkedin_profile_url is not empty
AND icp_match_score >= 60
AND enrichment_status = "complete"
AND (email_deliverable = "valid" OR linkedin_profile_url is not empty)
AND signal_staleness = "ACTIVE",
"EXPORT",
"HOLD"
)
OUTPUT METRICS (review before each export run):
Total rows in table: [N]
Rows marked EXPORT: [N] (target: ≥ 80% of enriched rows)
Rows held — low ICP score: [N]
Rows held — stale signal: [N]
Rows held — missing URL+email: [N] (these cannot match on LinkedIn)
The LinkedIn Matched Audience sync is where the enriched data becomes active ad targeting. Clay's native LinkedIn integration allows direct export to a LinkedIn Matched Audience — the contacts in the Clay table are pushed to LinkedIn Campaign Manager, LinkedIn matches them against its member database, and the matched subset becomes the targeting audience for your ad campaign. The architecture of this step determines not just which contacts see the ads but how quickly the audience updates as new contacts pass through the enrichment waterfall.
The most common mistake in LinkedIn Matched Audience setup is creating a single "ABM Target" audience and pushing all enriched contacts into it. A single audience means every contact gets the same ad creative regardless of their signal source tier, their intent score, or the stage in the buying journey that their behavior suggests they are at. The competitor-content engager who is actively evaluating alternatives needs a different message than the thought-leader engager who is still in category awareness. Serving them the same ad is a creative and conversion waste.
The correct architecture is four distinct matched audiences, each receiving different ad creative and bidding strategy:
| Audience Name in LinkedIn | Filter in Clay | Expected Size | Ad Creative Approach | Bidding Strategy |
|---|---|---|---|---|
| ABM — Own Content Engagers | signal_source = "own_content" AND icp_match_score ≥ 70 | Typically 200–500 contacts | Product-specific. These contacts already know the brand. Move them toward demo or trial — not category education. Case studies, specific capability highlights. | Max CPC — highest value audience. Pay for clicks from known brand-aware decision-makers. |
| ABM — Competitor Engagers | signal_source = "competitor_content" AND icp_match_score ≥ 70 | Typically 300–800 contacts | Competitive displacement. Lead with differentiation against the competitor they just engaged with — not generic positioning. Direct comparison content, switching cost reduction. | Max CPC — second-highest value. These contacts are in active evaluation. |
| ABM — Category Aware | signal_source = "thought_leader" AND icp_match_score ≥ 70 | Typically 500–1500 contacts | Category-level thought leadership. These contacts are forming opinions on the problem — serve them content that positions your POV on the category, not your product features. | Max CPM — awareness stage. Optimize for impressions and brand recall, not immediate clicks. |
| ABM — High ICP Score | icp_match_score ≥ 85 (any signal source) | Typically 100–300 contacts | Highest-touch creative. These are the tightest ICP matches — invest in more personalized creative (company-specific or persona-specific ads if volume supports dynamic creative). Direct offer: strategy session, product demo, ROI calculator. | Max CPC with bid cap. Highest budget allocation. Monitor frequency — these are small audiences and frequency fatigue sets in faster. |
CLAY NATIVE LINKEDIN INTEGRATION — EXPORT CONFIGURATION
──────────────────────────────────────────────────────────────────
SETUP: Clay Table → Integrations → LinkedIn Matched Audiences
AUTHENTICATION:
→ Connect Clay to LinkedIn Campaign Manager via OAuth
→ Select Ad Account: [your Campaign Manager account ID]
→ Audience creation permissions required: Matched Audiences admin
AUDIENCE CREATION SETTINGS:
Audience Name: populated from a Clay formula column
Formula: "ABM — " + signal_source_label + " — " +
MONTH(TODAY()) + " " + YEAR(TODAY())
Example output: "ABM — Own Content Engagers — Oct 2025"
(Include date to track which monthly batch is in each audience)
Match Method: LinkedIn Profile URL (PRIMARY)
→ Map Clay column: linkedin_profile_url (normalized)
→ This is the highest match-rate input — prioritize always
Match Method: Email (FALLBACK for rows without LinkedIn URL)
→ Map Clay column: primary_email (cleaned, lowercase)
→ Only included for rows where linkedin_url is empty
EXPORT FILTER (within Clay integration action):
→ Only export rows where export_ready = "EXPORT"
→ Segment by audience_segment column to push to correct audience
→ Maximum batch size: 10,000 rows per export (LinkedIn limit)
For larger lists: use Clay's pagination or split by export_date
SYNC FREQUENCY:
→ Initial build: manual export after enrichment completes
→ Ongoing: weekly scheduled Clay scenario refresh
(new enriched rows from past week pushed to existing audiences)
→ LinkedIn requires minimum 300 matched contacts per audience
to activate the audience for campaign targeting —
confirm minimum size before launching campaign
POST-EXPORT VALIDATION:
→ LinkedIn Campaign Manager → Matched Audiences → check match rate
→ Target match rate: ≥ 70% (LinkedIn Profile URL matching)
→ If match rate < 50%: URL normalization issue — recheck format
→ LinkedIn takes 24–48 hours to process and activate new audience
Plan campaign launch timing accordingly
LinkedIn Ads provides impression and click data at the aggregate campaign level natively. What it does not provide natively — and what ABM requires — is contact-level visibility: which specific people from which specific accounts are clicking your ads, watching your videos, or filling your lead gen forms. Without contact-level engagement data, the ad campaign is a black box that tells you an ad performed well but not which accounts it moved. The engagement tracking architecture closes that gap using LinkedIn's Insight Tag combined with a webhook bridge that passes click and conversion events back into the Clay workflow.
The LinkedIn Insight Tag is a JavaScript snippet placed on every page of your website. It enables LinkedIn to match website visitors against the LinkedIn member database and report back at the segment level — which LinkedIn audience segment drove traffic to which pages. For ABM purposes, the critical configuration is the Conversion Event setup: specific page visits (pricing page, demo request page, case study pages) configured as conversion events that fire back to LinkedIn Campaign Manager and, via the webhook bridge described below, into Clay's engagement tracking table.
<head> of every page on the website — not just landing pages. The tag must fire on every page visit to capture the full visitor journey. For GTM-managed sites: add as a Custom HTML tag with All Pages trigger. For HubSpot CMS: add to the global header template. Verify firing via LinkedIn Tag Helper browser extension before going live with any campaign./pricing), Demo Request Page Visit (/demo), Demo Form Submission (thank you page URL), Case Study View (any /case-study/* URL), Contact Page Visit. Each event fires when the Insight Tag detects a member visit to that URL pattern. These events are used for LinkedIn optimization (tell LinkedIn's algorithm which clicks converted) and for the Clay webhook bridge below.ENGAGEMENT TRACKING TABLE — CLAY TABLE 04_Engagement_Tracking
──────────────────────────────────────────────────────────────────
PURPOSE: Map LinkedIn ad engagement signals back to enriched
contact records and account-level intent scores
DATA SOURCES:
Source 1: LinkedIn Campaign Manager API
→ Pulled daily via Make.com scenario
→ Data available: campaign_id, ad_id, impressions, clicks,
video_views (75%), lead_gen_form_opens,
lead_gen_form_submissions
→ Segmented by: Matched Audience segment (maps to signal_source tier)
→ Limitation: LinkedIn does not expose WHICH contacts clicked —
only aggregate counts per audience per campaign
Source 2: LinkedIn Lead Gen Form Submissions
→ When a contact fills a LinkedIn Lead Gen Form, LinkedIn provides
their name, email, and LinkedIn URL in the form submission data
→ These ARE contact-level — pull via LinkedIn API or Zapier bridge
→ These are the highest-value engagement signals in the pipeline
Source 3: Website Visit Attribution (from Insight Tag + RB2B/Clearbit)
→ Visitor identification layer (see Loop 2 architecture)
→ Passes: visitor company, visitor email (where identifiable),
page URL, visit timestamp
→ This IS contact-level when visitor identification succeeds
ACCOUNT-LEVEL INTENT SCORING:
For each Company record in the system, maintain a running intent score
updated by engagement events:
Event Type → Score Addition
──────────────────────────────────────────────────
Ad impression (own content) → +5 pts
Ad click (any campaign) → +20 pts
Lead gen form open → +30 pts
Lead gen form submit → +50 pts
Pricing page visit → +35 pts
Demo page visit → +30 pts
Case study page visit → +15 pts
Website visit (any page) → +10 pts
Score decay: -2 pts per day of no activity (prevents score
inflation from old signals dominating current-state view)
ALERT THRESHOLD:
Account intent_score ≥ 70: trigger CRM notification (Step 6)
Account intent_score ≥ 90: trigger SDR outreach task (Step 6)
The follow-up layer is where the enriched, engaged, intent-scored contacts convert from an advertising audience into an active outbound pipeline. The three outputs of this layer — personalized email sequences, sales team alerts, and retargeting audience updates — must be triggered by the same intent score threshold so that the timing across all three channels is coordinated. A contact who just clicked your pricing page ad should receive an email sequence, have their AE notified, and enter a "Hot Accounts" retargeting audience simultaneously — not on a 24-hour lag from separate systems that do not share state.
LOOP 3 TRIGGER LOGIC — COORDINATED MULTI-CHANNEL ACTIVATION
──────────────────────────────────────────────────────────────────
TRIGGER: Clay row in 04_Engagement_Tracking where
account_intent_score crosses threshold (daily evaluation)
THRESHOLD 1: score ≥ 50 (warm — LinkedIn retargeting only)
Action A: Add contact to "ABM — Warm Accounts" LinkedIn audience
Action B: No sequence enrollment yet — too early for direct outreach
Action C: No CRM alert — not high enough priority for SDR time
THRESHOLD 2: score ≥ 70 (hot — retargeting + sequence enrollment)
Action A: Add contact to "ABM — Hot Accounts" LinkedIn audience
(different creative: direct offer, not awareness content)
Action B: Enroll in email sequence (see sequence logic below)
→ Clay HTTP action → Instantly.ai or Smartlead API
→ POST /campaigns/{campaign_id}/prospects
→ Payload: email, first_name, company_name,
signal_source (for personalization variable),
last_engagement_type (for opening line context)
Action C: No SDR alert yet — let sequence run first
THRESHOLD 3: score ≥ 90 (high-intent — all channels fire)
Action A: Add to "ABM — High Intent" LinkedIn audience
(direct response creative: demo booking, free trial)
Action B: Enroll in priority email sequence (shorter delays,
more direct asks than warm sequence)
Action C: CRM Alert — Slack notification to assigned AE:
Make.com → Slack webhook:
"🔥 HIGH INTENT ACCOUNT: [Company Name]
Contact: [First Name Last Name], [Title]
Score: [intent_score] points
Last signal: [last_engagement_type] on [date]
LinkedIn: [linkedin_url]
Action: Review and call today"
Action D: CRM Task Creation — create task in HubSpot/Attio/GHL:
"High-intent outreach — [Contact Name] at [Company]"
Due: today
Priority: high
──────────────────────────────────────────────────────────────────
GUARD RAILS (prevent over-sequencing and duplicate enrollment):
→ Check: is contact already enrolled in any active sequence?
Clay lookup: sequence_enrolled column on contact record
IF enrolled AND sequence_active = true → SKIP re-enrollment
→ Check: has contact been emailed in last 14 days?
Clay lookup: last_email_sent_date
IF < 14 days ago → SKIP (prevent spam flagging)
→ Check: is contact on opt-out list?
Cross-reference against suppression list before any email action
The email sequences triggered from this workflow have one structural advantage over standard outbound sequences: every contact in the sequence has a documented behavioral signal that can be referenced in the opening line. The contact who engaged with a competitor's product announcement is not receiving a generic cold email — they are receiving a message that references the category they are actively evaluating. The contact who visited the pricing page after clicking an ad is not receiving a blind outreach — they are receiving a message that acknowledges they are clearly evaluating options. This signal-informed personalization is the difference between a sequence that achieves 8% reply rates and one that achieves 22%.
| Signal Source | Sequence Track | Opening Line Approach | Primary CTA |
|---|---|---|---|
| own_content engagement | "Brand Aware — Direct" | Reference the content piece they engaged with: "Saw you [liked/commented on] our post about [topic] last week — figured a direct note made more sense than an ad." Acknowledge they already know the brand. Move quickly to value prop specifics. | 15-minute discovery call. No demo yet — these contacts need to qualify themselves. Short CTA, direct scheduling link. |
| competitor_content engagement | "Competitive Displacement" | Reference the category, not the competitor directly: "Teams in [industry] evaluating [category] tools are asking us the same question right now — [the question]. Thought you'd find our take useful." Never name the competitor in email — LinkedIn knows, they know, naming it looks like surveillance. | Relevant case study or comparison guide download. Lower friction first touch — build credibility before asking for time. |
| pricing_page_visit (Loop 2) | "High Intent — Fast Follow" | Acknowledge intent signals without being creepy about website tracking: "Researching [category] solutions for [company]? Happy to share how other [company_size] teams in [industry] structured their evaluation." Do not say "I saw you visited our pricing page" — reference the category, not the surveillance. | Offer to send a custom pricing breakdown for their company size/use case. Removes the friction of reading a public pricing page without guidance. |
| thought_leader engagement | "Category Education — Slow Burn" | Lead with the topic they engaged with, not the product: "Your comment on [topic] post caught my attention — [specific observation about what they said or reacted to]. We've been seeing [pattern] with teams thinking about this problem." Establish perspective before mentioning the product. | Send a relevant piece of content (original research, framework, or case study) that extends the topic they engaged with. No meeting ask in email 1. |
The retargeting loop is architecturally separate from the social signal loop but shares the same enrichment waterfall and LinkedIn audience sync infrastructure. The difference is the data source at the top of the funnel: instead of a LinkedIn engagement signal, the trigger is a website visit by an anonymous or semi-identified visitor. The goal is to identify which accounts are visiting the website, enrich the most likely decision-maker contacts at those accounts, and push them into page-specific LinkedIn matched audiences — so the ad creative they see next is directly relevant to the page they just visited.
Website visitor identification is the capability that determines how much of the retargeting loop fires on real contact data versus company-level data. Three tools occupy this space at different price and accuracy points: RB2B identifies individual visitors by name and LinkedIn URL for US-based traffic using its person-level identification technology; Clearbit Reveal identifies the company of the visitor based on IP address (company-level, not person-level); 6sense provides company identification plus intent data but at enterprise pricing. For this build, the recommended approach depends on the primary visitor geography and budget: RB2B for person-level US identification, Clearbit Reveal as the company-level fallback for non-US traffic.
RETARGETING LOOP ARCHITECTURE — VISITOR TO MATCHED AUDIENCE
──────────────────────────────────────────────────────────────────
TRIGGER: Website visitor session
RB2B / Clearbit Reveal JavaScript snippet fires on page load
Identification data sent to webhook endpoint
VISITOR IDENTIFICATION OUTPUTS:
RB2B (person-level, US):
→ Sends webhook to Make.com:
{ "name": "Sarah Chen",
"email": "sarah.chen@meridiansaas.com",
"linkedin_url": "linkedin.com/in/sarahchen-revops",
"company": "Meridian SaaS Inc.",
"page_visited": "/pricing",
"visit_timestamp": "2025-10-14T15:32:00Z",
"session_id": "rb2b_sess_abc123" }
Clearbit Reveal (company-level fallback):
→ Webhook to Make.com:
{ "company_name": "Meridian SaaS Inc.",
"company_domain": "meridiansaas.com",
"employee_count": "201-500",
"industry": "Software",
"page_visited": "/pricing",
"visit_timestamp": "2025-10-14T15:32:00Z" }
MAKE.COM ROUTING LOGIC:
IF person-level data available (RB2B):
→ Check Clay enrichment table: is this contact already enriched?
YES: update last_website_visit and page_visited → run Step 6 scoring
NO: add to Clay 02_Enrichment table → run enrichment waterfall
(LinkedIn URL already known — skip Pass 1, start at Pass 2)
IF company-level only (Clearbit):
→ Check Clay: does a Company record exist for this domain?
YES: update company intent score → find associated contacts
→ add associated contacts to retargeting audience
NO: add Company to enrichment queue
→ Clay finds decision-maker contacts at this company
(Apollo company people search by domain + ICP title filter)
→ Enrich found contacts → add to retargeting audience
PAGE-INTENT AUDIENCE SEGMENTATION:
page_visited = "/pricing" →
Audience: "Retargeting — Pricing Visitors"
Ad creative: pricing-specific, comparison guide, custom quote offer
page_visited = "/demo" OR page_visited = "/get-started" →
Audience: "Retargeting — Demo Intent"
Ad creative: social proof, "X companies booked demos this month"
page_visited contains "/case-study/" →
Audience: "Retargeting — Case Study Readers"
Ad creative: related case study, ROI calculator
page_visited = "/" (homepage) or blog pages →
Audience: "Retargeting — Brand Aware"
Ad creative: thought leadership, category education —
NOT product push (these visitors are in early research)
An ABM Clay workflow is not a set-and-forget system. It is a living data pipeline that requires weekly hygiene on three dimensions: enrichment credit management (Clay credits are a real cost that compounds with audience size), audience freshness (LinkedIn's matched audiences degrade in match rate as contacts change jobs, update profiles, or leave the platform), and ICP definition updates (the ICP scoring formula should be revisited quarterly as the sales team's closed-won data reveals which criteria actually predicted revenue, not just engagement).
| Maintenance Task | Frequency | What to Check | Action if Issue Found |
|---|---|---|---|
| Signal capture volume | Weekly | How many new rows are entering 01_Signal_Capture from each Phantombuster run? If volume drops sharply, the post URLs may have changed or the Phantombuster account may have hit rate limits. | Update post URLs in extraction list. Check Phantombuster account status. Refresh signal source list with new competitor posts or thought leader content. |
| Enrichment waterfall coverage rate | Weekly | What % of rows are completing enrichment with a valid email or LinkedIn URL? Target: ≥ 65%. If coverage rate drops, a provider may be experiencing API issues or the contact database is changing faster than expected. | Check individual provider coverage rates — identify which pass in the waterfall is failing most frequently. Consider adding or swapping a provider for the specific failure pattern. |
| LinkedIn match rate | After every audience push | Campaign Manager → Matched Audiences → match rate column. Target: ≥ 70%. Drop below 50% indicates URL normalization issue or audience staleness. | Re-export with re-normalized URLs. For audiences older than 90 days, refresh with new enrichment run to update LinkedIn URLs for job-changed contacts. |
| Clay credit burn rate | Weekly | Track credits consumed per week against budget. If burn rate is accelerating without proportional increase in qualified contacts, the ICP pre-filter is not catching non-ICP contacts early enough. | Tighten ICP pre-filter criteria — move the title exclusion list earlier in the waterfall (before email enrichment passes run) to stop spending credits on non-ICP contacts sooner. |
| Sequence reply rates | Monthly | What are the reply rates by signal source track? If one track is underperforming relative to others, the opening line approach or CTA for that signal type needs revision. | A/B test opening line variations within the underperforming track. Update the Clay signal_source personalization variable to reflect revised sequence copy. |
| ICP scoring formula calibration | Quarterly | Of the contacts that entered sequences, what is the meeting booking rate by icp_match_score range? If contacts scoring 60–70 are booking meetings at the same rate as 85+, the score thresholds need recalibration. | Adjust score threshold for sequence enrollment based on actual conversion data. The ICP formula is a hypothesis — closed-won data is the truth. Let revenue data, not assumptions, define the ICP criteria weights. |
"The Clay ABM workflow is not a campaign. It is a data machine that runs continuously, compounds behavioral signals across every touchpoint, and converts LinkedIn's expensive ad inventory into an audience that actually resembles your best customers. The teams that win are the ones who maintain the machine, not just launch it." Arsalan Faysal — Revenue Systems Architect
When this architecture is fully deployed and running, the operational reality is this. Every week, Clay ingests engagement signals from LinkedIn content — your posts, competitor posts, thought leader content — enriches the people behind those signals through a multi-provider waterfall, filters them against the ICP, and pushes a clean, segmented list of verified decision-makers to four distinct LinkedIn Matched Audiences. Each audience receives ad creative matched to their intent signal, not generic brand advertising. The match rate is above 70% because the primary match input is LinkedIn Profile URL, not email. The ICP match is above 80% because the pre-filter stops credit spend on non-ICP contacts before the expensive enrichment passes run.
When those decision-makers click ads or visit the pricing page, the engagement tracking layer updates their intent score in real time. When a score crosses 90, the assigned AE receives a Slack alert with the contact's name, title, LinkedIn URL, and the specific actions that drove the score — before the AE has to guess who to call. When a score crosses 70, the contact enters a personalized email sequence whose opening line references the specific signal that triggered their enrollment — not a generic cold pitch.
When a website visitor from a target account hits the pricing page, the visitor identification layer fires within minutes, their contact record is enriched, and they are added to the "Pricing Visitors" matched audience on LinkedIn — so the next time they open LinkedIn, they see an ad that is directly relevant to the evaluation they are already conducting. Not a brand awareness ad. Not a category education ad. A specific, conversion-focused creative that meets them exactly where the behavioral data says they are in the buying journey.
That is what the architecture produces. Not better demographics in your ad targeting. A live, continuously updating audience of identified, enriched, intent-scored decision-makers at your target accounts — and a coordinated system that activates every relevant channel the moment the behavioral data says the time is right.