Skip to content

Every 30 minutes

Send marketing-qualified HubSpot contacts to Salesforce

Contacts that reach MQL in HubSpot are created as Salesforce leads within 30 minutes, without duplicates, and sales hears about them in Slack.

Runs
Every 30 minutes
Apps
HubSpot, Salesforce
AI
Not needed
Access
HubSpot contacts read+write; Salesforce api

Send this to your assistant

Create a ClickRuntime automation: every 30 minutes, find HubSpot contacts with lifecycle stage MQL that haven't been sent yet, create a Salesforce lead unless one exists with that email, save the lead ID on the contact, and post the new leads to #sales.

Paste it into your assistant. It tells you what it will send or change before it runs live.

First time? Adding ClickRuntime to your assistant takes about two minutes.

Why use it

Why teams use this automation

Marketing nurtures contacts in HubSpot until they're ready for sales; sales works leads in Salesforce. The hand-off between the two is often a weekly export, which means a contact who requested a demo on Monday reaches a rep on Friday.

This automation checks HubSpot every 30 minutes for contacts that have reached marketing-qualified, creates them as Salesforce leads, and stamps the lead ID back on the HubSpot contact. Sales sees the new leads in Slack within half an hour.

What you get out of it

  • Hand-off in minutes, not days

    A contact reaching MQL is in Salesforce within 30 minutes.

  • No duplicate leads

    Existing leads with the same email are reused instead of created again.

  • A clear link between the two

    The Salesforce lead ID is saved on the HubSpot contact, so marketing can see what was handed over.

  • Sales knows straight away

    New leads are posted to #sales by name and company.

How it works

What happens, step by step

  1. Every 30 minutes the automation looks for HubSpot contacts at the MQL stage that don't yet have a Salesforce lead ID.

  2. For each, it checks Salesforce for a lead with the same email.

  3. If there isn't one, it creates a new Salesforce lead with the contact's details.

  4. The Salesforce lead ID is saved on the HubSpot contact so it's never sent twice.

  5. New leads are posted to #sales.

Before it runs live

  • Connect HubSpot
  • Connect Salesforce

What you get

RunsEvery 30 minutes
Send marketing-qualified HubSpot contacts to Salesforcetoday, 9:00Succeeded
Slack · #sales2 new MQLs from HubSpot are now Salesforce leads: Avery Kim (Tailspin Toys) Lee Jordan (Fourth Coffee)

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • Your own rules

    Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.

  • Any number of apps

    One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.

  • AI where it helps

    Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.

  • On a schedule or on each event

    Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.

Changes you can ask for

  • Act only on the items that match your own rules, and skip the rest
  • Add an AI step, for example to summarize, sort or draft a reply
  • Add another app, for example also send it to Slack
  • Combine it with other HubSpot and Salesforce steps into one automation

Under the hood

The code that runs this automation

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
new_hubspot_contacts_become_salesforce_leads.pyexample
from clickruntime import on_trigger, report_fetched, credentials, http, notify
HS = "https://api.hubapi.com/crm/v3/objects/contacts"
INSTANCE = "https://yourcompany.my.salesforce.com"
API = f"{INSTANCE}/services/data/v61.0"

@on_trigger
def run(event):
    hs = {"Authorization": f"Bearer {credentials.connection('hubspot', 'work')}"}
    contacts = http.post(f"{HS}/search", headers=hs, json={"limit": 50, "properties": ["email", "firstname", "lastname",
        "company", "phone"], "filterGroups": [{"filters": [
            {"propertyName": "lifecyclestage", "operator": "EQ", "value": "marketingqualifiedlead"},
            {"propertyName": "salesforce_lead_id", "operator": "NOT_HAS_PROPERTY"}]}]}).json()["results"]
    report_fetched(len(contacts))
    if not contacts:
        return {"summary": "No new MQLs"}
    sf = {"Authorization": f"Bearer {credentials.connection('salesforce', 'work')}"}
    created = []
    for c in contacts:
        p = c["properties"]
        email = (p.get("email") or "").replace("'", "")
        found = http.get(f"{API}/query", headers=sf, params={"q": f"SELECT Id FROM Lead WHERE Email = '{email}' LIMIT 1"}).json()["records"]
        lead_id = found[0]["Id"] if found else http.post(f"{API}/sobjects/Lead", headers=sf, json={
            "FirstName": p.get("firstname"), "LastName": p.get("lastname") or email, "Email": email,
            "Company": p.get("company") or "Unknown", "Phone": p.get("phone"), "LeadSource": "HubSpot"}).json()["id"]
        if not found:
            created.append(f"{p.get('firstname')} {p.get('lastname')} ({p.get('company')})")
        http.patch(f"{HS}/{c['id']}", headers=hs, json={"properties": {"salesforce_lead_id": lead_id}}).raise_for_status()
    if created:
        notify.slack(f"{len(created)} new MQLs from HubSpot are now Salesforce leads:\n" + "\n".join(created), channel="#sales")
    return {"contacts": len(contacts), "created": len(created)}

FAQ

Common questions

What do I need to set up in HubSpot?
A single-line text contact property called salesforce_lead_id. It's how the automation knows a contact has already been sent.
Can it use a different stage than MQL?
Yes. Any lifecycle stage or property can be the trigger, such as SQL or a lead score above a figure.
What does the lead source say?
HubSpot, so you can report on leads that came through marketing. You can change it to the original source if you prefer.
What permissions does it need?
HubSpot contacts read+write; Salesforce api. Nothing else in your accounts is used.
Does it need AI?
No. It runs without AI, so it doesn't use your plan's AI allowance.
How many runs does it use?
One run each time it checks. Checks that find nothing new and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

Set up “Send marketing-qualified HubSpot contacts to Salesforce” from your assistant

Copy the prompt above, or connect your assistant first. Free plan, no credit card.