TL;DR
- It's one action, not a sync. Clay ships a single Add Lead to Campaign action for HeyReach. The campaign must already exist, be Active, and have been built on an empty lead list — Clay cannot create campaigns.
- HeyReach uses SINGLE braces. Variables are
{first_name}, not{{first_name}}. If you copy a working cold-email setup across, every variable silently fails. This is the single most common Clay → HeyReach bug. - The action returns counts — use them. Unlike most push actions, this one gives you Added, Updated and Failed lead counts. That's a free reconciliation column. Most people never map it.
- A missing variable swaps the whole message. HeyReach's fallback isn't an inline default — it's an entire backup message. Half-enriched rows don't produce a hole in your copy, they quietly send generic copy instead.
- Your exclude list is locked at launch. HeyReach documents the exclude list as a draft-only setting — you cannot change it once the campaign is active. Suppression is a pre-launch decision, not a fix.
The enrichment is never the hard part. The hard part is the handoff — the moment a row leaves Clay and becomes a real connection request sent from a real LinkedIn account that you cannot un-send. Email gives you a bounce and a shrug. LinkedIn gives you a permanent record on a profile your client owns, and a restriction risk if you do it carelessly at volume.
This is the Clay → HeyReach handoff done properly: exactly what the integration does, the syntax difference that breaks copied email workflows, how sender routing actually behaves across a fleet of accounts, and the four places where the two vendors' own documentation disagrees — so you can set those options deliberately rather than discover them in production.
Sourcing note: the actions, inputs, outputs, variable syntax, character limits, exclusion behaviour and pricing below are VERIFIED against Clay's and HeyReach's own documentation and pricing page as retrieved 4 August 2026. Where their docs contradict each other, or where a behaviour genuinely isn't documented, we say so plainly instead of picking the version that reads better. We have not invented credit costs, rate limits or plan gates for anything the docs leave blank — and there are several. GenFlows runs LinkedIn DM automation as a service, which is why we know where the sharp edges are.
The Short Answer
Build the HeyReach campaign first on an empty lead list, write the sequence, and inventory every variable it uses. In Clay, add the native Add Lead to Campaign action, map First name, Last name and the personal LinkedIn URL, and name every custom field so it matches the HeyReach variable exactly — single braces, alphanumerics and underscores only. Gate the push column so it only runs when the LinkedIn URL is present and every variable in your copy is non-empty and within LinkedIn's character limit. Then map the action's Failed count into its own column and watch it. That gate plus that one output column is the difference between a clean handoff and 400 generic connection requests sent from your client's account.
What the Integration Actually Is (And Isn't)
Connect it in Clay with Add enrichment → search "HeyReach" → Integrations → + Add account, pasting the API key from Integrations → HeyReach API in your HeyReach account. What you get is deliberately small — one action:
| Field | Required? | Notes that matter |
|---|---|---|
| Campaign ID | Yes | Picked from a dropdown of your HeyReach campaigns. The campaign must exist and be Active |
| First name / Last name | Yes | Clean these in Clay. LinkedIn display names carry credentials, emoji and job titles |
| Professional URL | Yes | The personal LinkedIn profile URL. This is the identity key for the whole system — there is no email-style verification step |
| LinkedIn account | Optional | Assigns the lead to a specific sender. The lever that matters most at agency scale — see below |
| Location, company name, current position, email, summary | Optional | Standard fields. Push them anyway — they make the HeyReach inbox usable for whoever handles replies |
| Custom fields | Optional | Your personalisation. Names must be an exact match for the HeyReach variable, alphanumerics and underscores only |
Three constraints follow from that, and all three catch people out:
- The campaign must pre-exist — and be built a specific way. Clay's docs are explicit that you must create an active campaign in HeyReach first, and that the campaign needs to have been created with Create empty list so that it is designated as a lead list. A campaign built around an already-populated list is not a valid destination for a push.
- Clay cannot create campaigns. Sequence, senders, schedule and limits are all HeyReach-side decisions. If a push fails, verify the campaign exists and is active before debugging anything else.
- Leads land in the campaign and its list. HeyReach's own documentation confirms that everything pushed from Clay is automatically added to the campaign's lead list too. That list is what you'll later reuse as an exclusion list — so name it deliberately today.
Worth knowing: "campaigns can't be created programmatically" is a limit of the Clay integration, not of HeyReach. HeyReach's own public API documents a campaign-create endpoint plus separate endpoints for updating the sequence, sender accounts and schedule. So if you genuinely need campaign creation inside an automated flow, the path is Clay's HTTP API action (or n8n as the orchestrator) against HeyReach's API — not the native action. Most teams don't need this. Knowing it exists stops you from architecting around a limit that isn't there.
If the enrichment side isn't solid yet, start with waterfall enrichment setup and the Clay workflow playbook. This post assumes enrichment works and only the handoff is at stake.
The Bug That Breaks Almost Every First Attempt: Single Braces
This is the most valuable paragraph here, so it goes early. HeyReach personalisation variables use single curly braces. Its documentation shows the pattern as {variable_name}, with examples like {FIRST_NAME}, {AI_Icebreaker_1} and {websiteSummary}.
Nearly every cold-email tool — and therefore nearly every Clay table your team has already built — uses double braces: {{first_name}}. If you clone a working email table, swap the push action for HeyReach and reuse the copy, the variables will not resolve. You will not get an error. You will get sends.
Four naming rules that silently break personalisation:
- Single braces only.
{icebreaker}resolves.{{icebreaker}}does not. - Exact match, case for case. Both vendors' docs stress this independently. HeyReach's Clay guide puts "EXACT MATCH" in capitals.
{Icebreaker}and{icebreaker}are different variables. - Alphanumerics, hyphens and underscores only. No spaces, no other punctuation inside the braces. Clay's own docs restrict custom field names to alphanumerics and underscores — so intersect the two rule sets and just use
snake_case. - The variable must exist in the HeyReach sequence first. Write the copy, then build the Clay columns to match it — never the reverse.
One piece of folklore to discard: you'll find third-party guides showing an inline fallback syntax along the lines of {{FirstName | there}} for HeyReach. We could not find that syntax anywhere in HeyReach's own documentation, and it contradicts the single-brace pattern its docs do show (directional — treat any inline-default syntax as unverified until you see it in HeyReach's UI). What HeyReach documents instead is materially different, and it's the next section.
The Fallback Is a Whole Message, Not a Default Value
In a cold email tool, a missing variable leaves a hole: "Hi , saw the launch." HeyReach works differently, and the difference changes how you should gate.
HeyReach documents a fallback message — described in its own help centre as a backup message that is sent if a personalisation variable does not load correctly. It's a separate field in the interface holding alternative copy, not an inline default inside the braces.
The consequence is subtle and worth sitting with. A half-enriched row doesn't produce visibly broken copy that someone will notice and complain about. It produces a plausible generic message, sent from your client's account, to a prospect you spent credits enriching. Nothing looks wrong. Your reply rate just quietly drops, and the postmortem blames the copy.
So the fallback is a seatbelt, not a strategy. Write a genuinely decent one — assume a meaningful share of leads will receive it — but do the real work in Clay:
- Build one "ready to send" boolean column. TRUE only when the LinkedIn URL is present and every variable your copy uses is non-empty. One column you can reason about beats ten scattered conditions.
- Set the push column's "Only run if" to that column. Clay's conditional runs handle AND/OR/NOT, and there's a plain-language builder if you'd rather describe the rule than write it.
- Turn table-level auto-run off while you build and test on five to ten rows. Clay recommends exactly this to avoid burning credits on accidental runs — and it's what stops rows pushing before Claygent has finished writing the first line. Turn auto-update back on once the gate is proven.
- Add a length check. The one nobody adds — see below.
Length-Gate Your Icebreakers (The Check Nobody Builds)
LinkedIn connection request notes are hard-capped, and HeyReach documents the split plainly: up to 300 characters on Premium accounts, up to 200 on non-Premium. That is dramatically less room than an email first line, and an LLM asked for "a one-sentence personalised opener" will cheerfully return 340 characters.
Two things follow. First, tell the model the budget in the prompt and verify the output — a formula column that flags any icebreaker over your ceiling, wired into the ready-to-send gate. Second, know which accounts in your fleet are Premium, because the same copy that fits from a Sales Navigator seat may not fit from a bare account. If you're planning capacity across a fleet, our guides to Sales Navigator for outbound and connection-request and DM templates cover the copy side in depth.
Sender Routing: The Field That Matters at Agency Scale
The LinkedIn account field on the Clay action is optional, and that optionality is where agency workflows get interesting. Set it, and you decide which sender approaches which prospect. Leave it blank, and HeyReach handles distribution across the campaign's assigned accounts.
Set it deliberately when:
- Geography or language matters. A DACH prospect approached by the German-speaking account outperforms round-robin.
- Seniority matters. Founder-level prospects get the founder's account; the rest get the SDR fleet.
- You're protecting a specific account. New or freshly warmed accounts should receive a deliberately thin slice, not an even share.
- Existing relationships exist. If one account is already a first-degree connection with a prospect, route to that account and change the sequence — don't send a connection request to someone you're already connected to.
Two caveats, stated honestly. HeyReach's exact distribution algorithm when the field is blank is not something we found documented — treat "it spreads evenly" as an assumption to verify in your own campaign stats rather than a fact (directional). And per-account daily volume is governed by HeyReach's campaign settings and by LinkedIn's own platform behaviour, which are not the same thing. We covered that distinction, and what's actually enforced versus community-observed, in LinkedIn outreach limits and account safety. Read that before you scale sender count.
Use the Output Counts — This Integration Actually Gives You Some
Most push actions are write-only: you fire data at a tool and hope. Clay's HeyReach action returns three outputs — Added Leads Count, Updated Leads Count and Failed Leads Count — and in our experience almost nobody maps them.
Map all three. Then:
- Failed count > 0 is your alarm. Filter that view daily during a launch. The usual culprits are a malformed or stale LinkedIn URL, a missing required name field, or a campaign that isn't active.
- Updated rather than Added means HeyReach recognised the lead. That's your duplicate signal, and it's useful — it tells you your source lists overlap before that shows up as two senders approaching the same person.
- Added of zero across a whole batch usually means everyone was already in the campaign. HeyReach's docs describe exactly this: duplicates are blocked from entering a campaign twice, and if every lead already exists, zero leads are added.
This is the same discipline we apply to CRM writes — see CRM data hygiene for outbound teams and Clay + HubSpot sync. A push you cannot verify is not a pipeline, it's a hope.
Suppression: Decide Before You Launch, Because It Locks
Here is the constraint that most surprises people coming from email. HeyReach documents the exclude list as available only while the campaign is in draft — once the campaign is activated, the exclusion list cannot be modified.
Think about what that means operationally. There is no equivalent of adding a domain to a global suppression list mid-flight. If a client says "don't touch these 40 accounts" after launch, your options are pausing, cloning or managing it lead by lead — not editing the exclusion.
Two documented traps in exclusions:
- Don't use a freshly imported CSV as your exclude list. HeyReach's help centre explicitly warns against this and recommends running a new list through a campaign first so the data matches properly. A suppression list that silently fails to match is worse than none, because you'll trust it.
- Finished campaigns wake up. HeyReach's documentation notes that finished campaigns automatically reactivate when new leads arrive via the API. A Clay table still pointed at last quarter's "completed" campaign can restart it without anyone touching HeyReach. Audit your table's campaign target whenever you retire a campaign.
HeyReach's campaign-launch flow also offers broader exclusion filters — excluding leads already contacted by other campaigns, and excluding first-degree connections, at either selected-account or organisation-wide scope. Worth noting for accuracy: its dedicated exclude-list help article documents only the exclude-list dropdown, while these wider filters appear in the campaign-launch documentation. We'd treat the exact scope wording of each filter as something to confirm in your own workspace at launch (directional — two official pages describe different option sets). Also add leads to a running campaign, then pause and resume it; HeyReach advises this to make sure new leads are picked up properly.
The Workflow, Step by Step
| # | Step | Rule that makes it safe |
|---|---|---|
| 1 | Create the campaign in HeyReach on an empty lead list; add senders, sequence, schedule | Non-negotiable. Clay cannot create campaigns, and the list must be a designated lead list |
| 2 | Set the exclude list and exclusion filters now | Draft-only setting. You cannot change it after activation |
| 3 | Write the sequence, then list every variable it uses — single braces, snake_case | This list is the contract. Nothing gets pushed that isn't on it |
| 4 | Write a genuinely usable fallback message | Assume real prospects will receive it, because they will |
| 5 | In Clay: get the API key from Integrations → HeyReach API, connect the account | One key per HeyReach workspace — keep client workspaces separate |
| 6 | Clean names and normalise the LinkedIn URL in their own columns | The URL is the identity key. Garbage in, failed push out |
| 7 | Build the ready to send boolean: URL present + all variables non-empty + icebreaker within 200/300 chars | The single most valuable column in the table |
| 8 | Add Add Lead to Campaign; map fields and custom fields; set "Only run if" to step 7 | Custom field names must match the sequence variables exactly |
| 9 | Optionally set the LinkedIn account per lead for deliberate sender routing | Language, seniority, account age, existing connections |
| 10 | Map Added / Updated / Failed counts into visible columns | Your only reconciliation. Filter on Failed > 0 daily during launch |
| 11 | Test on 5–10 rows with auto-run OFF; inspect the leads inside HeyReach before scaling | Check the variables rendered — don't just check the lead arrived |
| 12 | Enable auto-update for ongoing pushes; pause/resume the campaign after bulk adds | Signal-triggered tables become continuous campaigns this way |
Why This Beats a CSV Upload
HeyReach supports several ways in — existing lead lists, CSV import, transferring qualified leads between campaigns, adding individuals from the inbox, and the API or integrations like Clay. CSV works. It just doesn't compound.
| CSV import | Native Clay action | HeyReach API direct | |
|---|---|---|---|
| Setup effort | Lowest | Low — one action, one API key | Highest — you own auth and payloads |
| Continuous / triggered | No — manual every time | Yes, with auto-update | Yes |
| Per-lead gating | No — you gate by filtering the file | Yes — conditional run per row | Yes, if you build it |
| Sender routing per lead | No | Yes — optional account field | Yes |
| Push confirmation | UI summary at import time | Added / Updated / Failed counts per row | Full response handling |
| Can create campaigns | No | No | Yes — documented create endpoint |
| Best for | One-off lists you've already cleaned | Signal-triggered, always-on outbound | Productised agency workflows |
The real argument for the native action is that it turns a list into a system. Once the gate holds, anything that lands in the Clay table — an intent signal, a new hire at a target account, a website visitor — becomes a routed, personalised LinkedIn touch without anyone exporting anything.
Sequencing LinkedIn Against a Live Cold Email Campaign
Most teams running this integration are also emailing the same people, and this is where a clean handoff turns into a mess. Two independent systems, two identity keys — email address in one, LinkedIn URL in the other — and no shared suppression between them.
Three rules we hold to:
- Clay is the source of truth for who is being touched, not the sending tools. Keep one row per person with columns recording what's been pushed where. Neither HeyReach nor your email tool can see the other.
- Stagger, don't stack. A connection request and a cold email landing the same morning reads as a campaign, not a person. Sequence the channels deliberately — the multi-channel playbook covers the cadence, and cold email vs LinkedIn covers which channel to lead with by segment.
- A reply anywhere stops everything everywhere. This is manual work across two tools. Own it, or it will embarrass you — a prospect who replied on LinkedIn yesterday should not get email step four tomorrow. Our reply-handling guide and notes on routing and speed-to-lead both apply here.
What HeyReach Costs (Retrieved 4 August 2026)
Pricing matters here because the sender-account model, not the software, is what determines cost at scale. From HeyReach's own pricing page today:
| Plan | Monthly | Annual (per month) | Senders |
|---|---|---|---|
| Growth | $79 per sender | $63 per sender | Priced per sender — scales linearly |
| Agency | $999 | $799 | 25 included; whitelabel branding |
| Unlimited | $2,999 | $2,399 | Unlimited; multi-client branding as a $500 add-on |
Two observations. First, API access and workspaces are listed on every tier — so this integration isn't gated behind the agency plan, which is unusual and genuinely useful if you're a single team testing the pattern. Second, the crossover: at $79 per sender, Growth reaches the Agency plan's $999 at around 13 senders, which is roughly where the 25-sender bundle starts paying for itself. We reached the same breakeven independently in our LinkedIn automation tools comparison.
Ignore the pricing aggregators. Several third-party "HeyReach pricing 2026" pages currently list a $59 Growth sender price and a $1,999 Unlimited tier. Those figures do not match HeyReach's own pricing page as we retrieved it on 4 August 2026 ($79 and $2,999 respectively). Pricing pages change and ours will age too — check the vendor's page, not a comparison site, and note the date you checked. On the Clay side of the bill, our honest Clay pricing review covers what's actually knowable about credits.
What the Docs Don't Tell You
Three genuine blanks, stated as blanks rather than filled with plausible numbers:
- No credit cost is published for the Clay action. Clay's HeyReach documentation states no credit cost and no plan gate. We're not going to invent one.
- Per-request lead caps and API rate limits are not something we could verify from a primary page. HeyReach's public API reference is a Postman collection, and figures circulating on third-party sites (a leads-per-request cap, a requests-per-minute ceiling) did not appear on the HeyReach pages we could read. Don't architect around a number you found on an aggregator. The one hard figure we did verify from HeyReach's campaign API documentation is that its sender-account array accepts 1–100 accounts.
- Stale LinkedIn URL behaviour isn't documented. People change vanity URLs and profiles get restricted. Whether a redirected URL resolves or fails is not stated anywhere we found — which is exactly why the Failed count column matters. Measure it in your own account rather than trusting a guide, including this one.
The honest compliance note: no third-party LinkedIn automation tool is sanctioned by LinkedIn's terms of service — HeyReach included, and every competitor equally. That's a business risk you accept knowingly, not a detail to discover after an account restriction. The practical mitigations are conservative per-account volumes, genuine personalisation, and never concentrating a client's entire pipeline in one profile. We go through what's actually enforced versus merely rumoured in LinkedIn outreach limits and account safety.
Frequently Asked Questions
Does Clay have a native HeyReach integration?
Yes. Clay offers a single native action, Add Lead to Campaign, connected with an API key from Integrations → HeyReach API in your HeyReach account. It requires Campaign ID, first name, last name and the personal LinkedIn profile URL, and it returns Added, Updated and Failed lead counts. HeyReach lists API access on all of its paid tiers, so the integration isn't restricted to the agency plan.
Why aren't my Clay variables working in HeyReach?
Almost always the brace style. HeyReach uses single curly braces — {first_name} — while most cold email tools use double braces. Copying a working email setup across is the single most common cause. After that, check for case mismatches (names must match exactly), spaces or punctuation inside the braces, and whether the variable exists in the HeyReach sequence at all. Clay restricts custom field names to alphanumerics and underscores, so snake_case is the safe choice.
Can Clay create a HeyReach campaign automatically?
No. Clay's documentation is explicit that campaigns cannot be created from within Clay — the campaign must already exist, be Active, and have been created on an empty lead list. HeyReach's own public API does document a campaign-create endpoint, so campaign creation is possible via Clay's HTTP API action or an orchestrator like n8n. It just isn't part of the native integration.
What happens if a personalisation variable is empty when HeyReach sends?
HeyReach documents a fallback message: a backup message sent when a personalisation variable does not load correctly. That's different from most email tools, where a blank variable leaves a visible hole in otherwise-personalised copy. The practical risk is that a half-enriched lead receives plausible generic copy and nobody notices — so gate the push in Clay on every variable being non-empty, and write a fallback you'd genuinely be happy to send.
How long can a LinkedIn connection request note be?
HeyReach documents up to 300 characters for Premium accounts and up to 200 characters for non-Premium accounts. That is much tighter than an email first line, so add a length-check column in Clay that flags any AI-generated icebreaker exceeding your ceiling, and remember the limit differs across the sender accounts in your fleet.
Can I add leads to a HeyReach campaign that's already running?
Yes. HeyReach supports adding leads to campaigns with ongoing, paused or finished status, and advises pausing and resuming the campaign once leads are added so they're picked up properly. Duplicates are blocked from entering the same campaign twice — if every lead already exists, zero are added. One warning: HeyReach's documentation notes that finished campaigns reactivate automatically when new leads arrive via the API, so audit which campaign your Clay table targets before retiring a campaign.
Running LinkedIn and cold email as one system is where most of the value is — and where most of the mess is. If you'd rather not maintain the gates, the sender routing and the cross-channel suppression yourself, that's the work we do: read the LinkedIn automation tools comparison to pick your stack, or talk to our team about running it for you.
By the GenFlows GTM engineering team. Integration mechanics, variable syntax, character limits, exclusion behaviour and pricing verified against Clay's and HeyReach's own documentation and pricing page. Last updated August 2026.
The GenFlows team builds AI-powered cold outbound systems for B2B teams.