Social listening

How to send LinkedIn engagement leads to HubSpot and Clay

Route LinkedIn engagement into a HubSpot integration or a Clay table: the real field maps, why the comment does not land on a contact, dedupe, and the reply loop.

Signl pushes a qualified person into HubSpot as a contact upsert on email, and into Clay as one flat row carrying the comment, the opener and the intent. The difference matters: the context survives the Clay path and does not survive the HubSpot one, so which you pick depends on where you want to write the message.

Disclosure: Signl is ours. Every field name and scope below was read out of our own code on 24 October 2026: destinations/vendors.ts for HubSpot, destinations/clay.ts for the Clay row, destinations/webhook.ts for the generic payload. No click-by-click screenshots appear here, because the destination UI changes and a stale screenshot is worse than none.

Key facts

  • The HubSpot path writes six standard contact properties and upserts on email. The engagement context does not travel with it.
  • The Clay path carries 24 named columns, including the comment, the opener, the reason, the intent and the asset for lead magnets.
  • A generic webhook sends the same material as a signl.lead event, which is the route into Zapier, Make, n8n or your own endpoint.
  • HubSpot is the only destination that reports outcomes back by polling: deals and meetings, daily.
  • Dedupe happens before the send, on the person, so the same person never reaches the same campaign twice.

The architecture, in one pass

Five stages, and the integration question is only about the last one.

Collect the engagement, deduplicate to one record per person, qualify against your ICP, enrich the people who passed with a verified work email, then route. Qualification sits before enrichment deliberately, so a filtered person never consumes an email lookup; the reasoning is in the bounce tax and the records model is in LinkedIn comment tracking.

What arrives at the integration boundary is therefore a person who already has a verdict, a reason, a drafted opener and an email. The integration's job is to not throw those away.

The field maps

HubSpot

Signl calls the contacts batch upsert endpoint with idProperty set to email, which means the person is matched on email address and created if absent. The properties written:

HubSpot propertyFrom
emailThe verified work email found during enrichment
firstnamePerson first name, when present
lastnamePerson last name, when present
companyCompany name, when present
jobtitleTitle, when present
websiteCompany domain, when present

That is the complete list, and the honest consequence is the one nobody publishes: the comment, the opener, the reason and the intent do not reach HubSpot through this path. They exist, they travel to other destinations, and this adapter does not write them to custom properties.

So if your sellers write their messages inside HubSpot, the direct path will frustrate them. Two ways round it, both fine:

  1. Clay as the staging layer. Send to Clay, build the HubSpot write in Clay with whatever custom properties you want, and keep the enrichment and scoring you already run there.
  2. A webhook into your own automation. The payload below has everything; map it to HubSpot custom properties in Zapier, Make or n8n.

Connecting needs a HubSpot private app token with crm.objects.contacts.write, crm.objects.contacts.read and crm.objects.deals.read. Signl validates contacts access and then deals access separately, so if the deals scope is missing you get told exactly that rather than a generic rejection. The person must have an email: HubSpot is an email-only destination here, so a LinkedIn-only or X-only person is not eligible and will not be sent.

Clay

One flat row per person, posted to a Clay table's Monitor webhook URL. Flat and predictably named, because that is what Clay maps to columns best. Every send carries all 24 keys, using empty strings rather than omitting them, so the table's columns stay stable from the first row onwards.

The columns, in the order Clay first sees them:

signl_event, signl_id, name, first_name, last_name, email, title,
company, domain, linkedin_url, x_url, platform, engagement, comment,
post_topic, intent, reason, opener, offer, dm, asset_name, asset_url,
keyword, sent_at

comment is the verbatim text. reason is why the person passed your ICP check, in words. opener is the drafted first line, with the quoted fragment already verified against the comment. engagement is comment, reaction or repost. platform is LinkedIn or X. asset_name, asset_url and keyword are populated for lead magnet sources, which are covered in LinkedIn lead magnet posts.

The credential is the webhook URL, optionally followed by a space and the token Clay shows once when the source is created; Signl sends that token in the x-clay-webhook-auth header. Connecting deliberately posts a test row, because a Clay webhook source does not reveal its columns until it has seen a payload, and you cannot build the table without them.

Clay can also call Signl rather than receiving pushes, using an HTTP API column against Signl's public API with your Signl API key. If Clay is already your orchestration layer, that is usually the better shape. Our longer comparison of the two products, including where Clay is the better buy, is Signl vs Clay.

A generic webhook

The escape hatch, and the one destination that accepts a person with no email at all: anyone with an email, a LinkedIn profile or an X account is eligible, which makes it the only route for an X-only person.

{
  "event": "signl.lead",
  "sent_at": "2026-10-24T09:14:22.108Z",
  "lead": {
    "id": "...",
    "name": "...",
    "first_name": "...",
    "last_name": "...",
    "email": "...",
    "title": "...",
    "company": "...",
    "domain": "...",
    "linkedin_url": "...",
    "x_url": null,
    "signl_comment": "...",
    "signl_opener": "...",
    "signl_reason": "...",
    "signl_intent": "...",
    "signl_post_topic": "...",
    "signl_engagement": "...",
    "signl_platform": "..."
  }
}

The merge variables sit alongside the person's fields with their signl_ prefix intact. Connecting posts a signl.test event first so you can confirm the endpoint before any real person arrives. The URL must be https.

Deduplication, and the mistake to avoid

Two layers, and you need both.

Signl's layer. Dedupe happens on the person before the send, and a rule never sends the same person to the same campaign twice. Autopilot is capped at 10 rules and 500 sends a day per account, which is also a practical dedupe control: more rules means more chances for two of them to find the same good person and route them to two campaigns.

Your CRM's layer. HubSpot's upsert on email handles the "already a contact" case cleanly, which is why email is the match key. Clay does not dedupe for you; use signl_id, which is stable per engagement, or linkedin_url, which is stable per person, as the key in your table. Use linkedin_url if the question you care about is "have we seen this human before".

The mistake worth naming: routing to both HubSpot and an email sequencer from two separate rules, then being surprised when a HubSpot workflow also enrols them. Pick one system as the enrolment authority.

The outcome loop

This is the part most engagement setups never close, and it is what makes the next month's sourcing decisions better than this month's.

DestinationHow outcomes return
HubSpotPolled daily. Deals and meetings associated with the contact come back into Signl
Instantly, Smartlead, lemlistReply webhooks, registered with your key on connect or by pasting Signl's URL into the tool
HeyReach, ExpandiReply reporting per the tool's own path
ClayNothing comes back. Clay is a table, not a sequencer
Generic webhookNothing comes back

Once replies and deals flow back, get_pipeline_report and the source list answer the only question that matters about a source: did anyone talk to us. A source producing 400 people and no conversations should be dropped, and you cannot know that without this loop. Reading it from an agent is covered in Claude LinkedIn prospecting.

Limits

  • HubSpot needs an email. No email, no send on that path. Use Clay or a webhook.
  • Context is lost on the HubSpot path. Stated above, worth repeating, because it is the thing people discover a fortnight in.
  • Clay and webhooks are write-only. No replies, no deals, no outcome data.
  • Credentials are one-way. Anything you paste is stored server side, never repeated back, and never kept in Signl's own call log. You replace rather than retrieve.
  • Nothing here sends a message. Signl prepares, qualifies and routes; the connected tool sends, which is where your deliverability and account risk belong. Native LinkedIn sending from your own account is listed as coming soon on our pricing page.
  • Objections override everything downstream. When someone objects, Signl suppresses and erases them globally and permanently, for every customer. Your CRM will not know, so mirror it there; the UK ICO treats an objection to direct marketing as an absolute right with no exemptions (read 24 October 2026). This is not legal advice.

Frequently asked questions

Does the comment text reach HubSpot?

Not through the direct HubSpot path. Signl's HubSpot adapter upserts a contact by email and writes standard properties: email, first name, last name, company, job title and website. The opener, reason, intent and comment travel as named fields to Clay and to webhooks instead. If you want them in HubSpot, route through one of those.

What does Signl need before it can send to HubSpot?

An email address on the person, and a HubSpot private app token with three scopes: crm.objects.contacts.write, crm.objects.contacts.read and crm.objects.deals.read. The deals scope is what lets outcomes come back. Signl checks both contacts and deals access when you connect and tells you which scope is missing rather than failing generically.

How does Clay receive the data?

As one flat JSON row per person, posted to a Clay table's Monitor webhook URL, with an optional token in the x-clay-webhook-auth header. Connecting posts a test row on purpose, because a Clay webhook source only shows its columns once it has seen a payload, and you build the rest of the table from those columns.

Can Clay call Signl rather than the other way round?

Yes, both directions work. Signl pushes rows into a Clay table, and Clay can call Signl's public API from an HTTP API column using your Signl API key. Teams who already run their enrichment and scoring in Clay usually prefer the second, with Clay as the orchestrator and Signl as the source of qualified people.

Your next buyer could already be in the comments.

Find the people worth talking to, see why each one matters, and send them to the tool you already use.