guideautomationcold-email

Automate Outbound Follow-ups with n8n, Clay, and HubSpot

TL;DR

Use n8n to listen for reply or bounce events from Smartlead or Instantly, enrich the contact with Clay, then write the result back to HubSpot or Pipedrive automatically so no follow-up falls through the cracks.

On this page

Most outbound follow-up breakdowns I’ve seen at mid-market B2B SaaS companies happen in the exact same place. A prospect replies with “not now, check back in Q3,” the sequence pauses, and nobody writes that to the CRM. Three months later the rep has no idea the conversation happened. The fix is not a new sequencer. It is a lightweight automation layer that listens to your sequencer’s events, enriches the contact on the fly, and commits a structured record to your CRM before the rep ever opens their inbox. n8n is the orchestration engine I reach for here because it handles conditional logic and HTTP calls without the per-task pricing that makes Zapier painful at volume.

What This Workflow Actually Does

Three nodes deep. That is the whole pattern: capture an event from your cold email tool, enrich the sender’s company with Clay, then write a deal or contact note to HubSpot or Pipedrive. The whole thing runs in under four seconds per event in production. I’ve deployed this stack at clients running 2,000 to 8,000 outbound touches per month, and it eliminates the black hole where replied or bounced contacts vanish from the CRM pipeline entirely.

Before wiring a single node, make sure three things are in place: API keys for your sequencer (Smartlead or Instantly), a Clay table configured with the enrichment waterfall you want (I run Clearbit first, then LinkedIn, then Apollo as the final fallback), and a HubSpot or Pipedrive sandbox to test writes against. The n8n docs on HTTP Request nodes are genuinely good. Skim them before you start.

Step 1
Set the webhook trigger in n8n

Create a new workflow. Drop a Webhook node as the trigger, set method to POST, and copy the generated URL. In Smartlead, go to Settings > Webhooks and paste that URL. Check the events you want: 'Reply Received', 'Email Bounced', and 'Sequence Completed'. Instantly users do the same under Campaigns > Integrations > Webhooks. Test the connection by firing a dummy event from the sequencer's webhook test tool and confirm n8n receives the JSON payload.

Step 2
Parse and normalize the payload

Smartlead and Instantly ship slightly different JSON schemas. Add a Code node (JavaScript) immediately after the webhook trigger to normalize the fields you need: email address, campaign name, event type, and timestamp. I map them to a standard object with four keys: email, campaignName, eventType, and triggeredAt. This single normalization step makes the rest of the workflow sequencer-agnostic, so you can swap Smartlead for Instantly later without rewiring every downstream node.

Step 3
Enrich the contact via Clay's API

Add an HTTP Request node pointed at your Clay table's row-creation endpoint. Pass the normalized email address as the lookup key. Clay will waterfall your configured enrichment sources and return firmographic fields: company name, headcount, industry, tech stack, and LinkedIn URL. Set the node to wait for the enriched response. Clay's async enrichment typically resolves in one to three seconds for a warm table. Per the [Clay API docs](https://docs.clay.com/api-reference), you can poll the row status or use their webhook callback. Polling on a one-second interval is simpler for most RevOps teams and is what I recommend to start.

Step 4
Route by event type with an IF node

Drop an IF node after the enrichment step. Branch on eventType: if 'Reply Received', route to the CRM contact-update path. If 'Email Bounced', route to a separate path that marks the contact as 'Bad Data' and optionally triggers a Clay re-verification pass. If 'Sequence Completed' with no reply, route to a task-creation path that assigns a manual follow-up to the owning rep. This branching is where n8n earns its keep. Zapier would charge you three separate zaps and lose the shared enrichment context between them.

Step 5
Write to HubSpot or Pipedrive

On the reply path, use the native HubSpot node to upsert the contact (match on email), update the lifecycle stage to 'Sales Qualified Lead' if the reply is positive, and create an engagement note with the enriched firmographics appended. For Pipedrive teams, use the native Pipedrive node to create or update a Person record and log an Activity with the event details. Set the note body to include Clay's returned company size and tech stack so reps have context without leaving the CRM. I always timestamp the note with the original reply time from the webhook payload, not n8n's execution time, so the CRM timeline stays accurate.

The Gotcha That Will Break Your First Run

The enrichment step is where most implementations stall. Clay’s API is asynchronous by default and response time varies depending on which waterfall sources trigger. Fire and forget with no wait, and your CRM write node executes before the enriched fields are populated. You end up logging a contact with only the email address. Nothing else.

The trap: Setting the HTTP Request node to fire-and-forget on the Clay row creation call. The downstream CRM node runs immediately, reads an empty enrichment response, and writes a skeleton contact record. Your reps see contacts with no company data and assume the automation is broken. They stop trusting it and go back to manual logging. I’ve watched this exact pattern kill adoption at two clients. Both had solid webhook setups. Both got tripped up right here.

// Code node: poll Clay row until enriched
const maxAttempts = 8;
const delayMs = 1500;

async function pollClayRow(rowId, apiKey) {
  for (let i = 0; i < maxAttempts; i++) {
    const res = await $http.request({
      method: 'GET',
      url: `https://api.clay.com/v1/rows/${rowId}`,
      headers: { Authorization: `Bearer ${apiKey}` }
    });
    if (res.data.enrichmentStatus === 'complete') {
      return res.data;
    }
    await new Promise(r => setTimeout(r, delayMs));
  }
  throw new Error('Clay enrichment timed out after 12s');
}

return await pollClayRow(
  $input.item.json.clayRowId,
  $env.CLAY_API_KEY
);

The polling approach above adds at most 12 seconds of latency to the workflow. That is completely acceptable for an async follow-up automation. Nobody is waiting at their desk for this to finish. Alternatively, configure Clay’s webhook callback to fire back to a second n8n webhook endpoint and use n8n’s “Wait” node to pause execution until that callback arrives. The webhook approach is cleaner at scale but adds another URL to manage and another failure surface to monitor.

Shipping It to Production

Once the workflow passes testing in the n8n sandbox, flip it to active and monitor the first 48 hours manually. Check three things: webhook delivery rate from the sequencer (Smartlead logs these under Settings > Webhook Logs), Clay enrichment success rate per row (anything below 70% means your waterfall sources need reconfiguration), and CRM write errors in n8n’s execution history. Then set up an error workflow in n8n that catches failed executions and posts a Slack message with the contact email and the error reason. This is not optional. Silent failures in CRM sync are the fastest way to lose rep trust in any automation, and rep trust is harder to rebuild than the workflow itself.

According to HubSpot Research’s 2024 Sales Trends report, sales reps spend an average of 21% of their day on manual data entry. This workflow does not eliminate that entirely. What I’ve measured at clients running high-volume outbound is roughly an 80% reduction in cold-email-to-CRM data entry time, which frees reps to focus on calls and personalization instead.

The full stack costs under $200 per month for most mid-market teams. n8n Cloud at around $50, Clay on a starter plan, and whatever you’re already paying for HubSpot or Pipedrive. One RevOps operator, about one day of work to implement from scratch. That is a better return than any sequencer add-on I’ve evaluated at that price point. Wire the webhook, normalize the payload, enrich before you write, and your outbound motion finally has a memory.

Sources

Filed under:

guideautomationcold-email

Frequently asked questions

Can n8n connect directly to Smartlead or Instantly?

Yes. Both tools expose webhook and REST API endpoints. n8n can receive a Smartlead webhook on reply or bounce events and call the Instantly REST API to pause or update a sequence with no middleware.

How does Clay fit into an n8n outbound workflow?

Clay acts as the enrichment layer. n8n sends a contact record to a Clay table via the HTTP Request node, Clay waterfalls enrichment sources, and n8n reads the enriched row back before writing to the CRM.

Does this workflow work with both HubSpot and Pipedrive?

Yes. n8n ships native nodes for both CRMs. You can branch the workflow with an IF node to write to HubSpot or Pipedrive based on which workspace the contact belongs to.

What triggers the follow-up automation in n8n?

The most reliable trigger is a webhook from Smartlead or Instantly fired on specific campaign events: reply received, email bounced, link clicked, or sequence completed with no response.

Is n8n hard to self-host for a mid-market RevOps team?

Not if you have one technical operator. n8n Cloud removes the infra overhead entirely and costs around $50 per month for most RevOps team volumes, which is the route I recommend for teams without a dedicated DevOps resource.


← Back to Blog

Enjoying this? Share it with your team.

Some links are affiliate links. Disclosure.