Skip to content

Every 30 minutes

Import leads from a sheet into your Airtable CRM

New leads pasted into a sheet are added to Airtable as companies, without duplicates, and marked imported.

Runs
Every 30 minutes
Apps
Airtable, Google Sheets
AI
Not needed
Access
Sheets edit; Airtable read+write

Send this to your assistant

Create a ClickRuntime automation: every 30 minutes, import new rows from my 'Marketing leads' sheet into my Airtable 'Companies' table, skip any company already there by domain, and mark each row imported.

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 collects leads from webinars, trade shows and list purchases, and the easiest hand-off is a sheet. Sales works from an Airtable CRM. Someone has to move the rows across, check each company is not already in the base, and remember which rows they have done. When it is left for a week, the same company ends up in the CRM three times with different spellings.

Checking each lead's web domain against the CRM before creating anything, and marking the sheet row as imported, means marketing can keep pasting and sales only ever sees one record per company.

What you get out of it

  • One record per company

    Leads are matched on web domain, so 'Acme Ltd' and 'ACME' from the same domain update the same record.

  • Existing records are updated

    If the company is already in Airtable, the new contact details are added to it instead of creating a second one.

  • Clear status in the sheet

    Each row gets 'Imported' or 'Updated' written next to it, so marketing can see what has gone across.

  • No hand-off meeting

    Leads reach sales within half an hour of being pasted into the sheet.

How it works

What happens, step by step

  1. Every 30 minutes, ClickRuntime reads your Marketing leads sheet and picks out rows without a status.

  2. For each lead it takes the web domain from the website or email address.

  3. It looks for a company with that domain in your Airtable Companies table, updating it if found or creating it if not.

  4. The row in the sheet is marked Imported or Updated so it is not handled again.

  5. If any rows had no domain, you get one email listing them.

Before it runs live

  • Connect Airtable
  • Connect your Google Sheets account and pick the spreadsheets it may use

What you get

RunsEvery 30 minutes
Import leads from a sheet into your Airtable CRMtoday, 9:00Succeeded
Airtable · CompaniesImported: Fabrikam Robotics (fabrikam.example), contact Dana Ortiz Updated: Contoso Ltd (contoso.example), new contact added

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 Airtable and Google Sheets 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.
import_leads_from_a_sheet_into_airtable_crm.pyexample
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, notify, report_fetched
BASE_ID = "appXXXXXXXXXXXXXX"
SHEET_ID = "1AbCdEfGhIjKlMnOpQrStUvWxYz"
@on_trigger
def run(event):
    values = build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")),
                   cache_discovery=False).spreadsheets().values()
    rows = values.get(spreadsheetId=SHEET_ID, range="Marketing leads!A2:E").execute().get("values", [])
    new = [(i + 2, (r + [""] * 5)[:5]) for i, r in enumerate(rows) if len(r) < 5 or not r[4]]
    report_fetched(len(new))
    if not new:
        return {"imported": 0}
    api, headers = f"https://api.airtable.com/v0/{BASE_ID}/Companies", {"Authorization": f"Bearer {credentials.connection('airtable', 'work')}"}
    skipped = []
    for row_num, (company, contact, email, website, _) in new:
        domain = (website or email.split("@")[-1]).lower().replace("https://", "").replace("http://", "").replace("www.", "").strip("/")
        if not domain:
            skipped.append(str(row_num))
            continue
        found = http.get(api, headers=headers, params={"filterByFormula": f"{{Domain}}='{domain}'", "maxRecords": 1}).json()["records"]
        fields = {"Name": company, "Domain": domain, "Contact": contact, "Email": email, "Source": "Marketing sheet"}
        record = {"id": found[0]["id"], "fields": fields} if found else {"fields": fields}
        (http.patch if found else http.post)(api, headers=headers, json={"typecast": True, "records": [record]}).raise_for_status()
        values.update(spreadsheetId=SHEET_ID, range=f"Marketing leads!E{row_num}", valueInputOption="RAW",
                      body={"values": [["Updated" if found else "Imported"]]}).execute()
    if skipped:
        notify.email_me("Leads without a domain", "Rows missing a website or email: " + ", ".join(skipped))
    return {"handled": len(new) - len(skipped), "skipped": len(skipped)}

FAQ

Common questions

What if a lead has no website or email domain?
The row is left without a status and you get an email listing those rows, so someone can fill in the domain before the next run.
Does it change records sales has already edited?
Only the fields in the import are written, such as contact name and source. Notes, stage and owner set by sales are left as they are.
Can I import into Contacts as well as Companies?
Yes. The script can create a contact linked to the company record. Ask your AI assistant to add a Contacts table to the import.
What permissions does it need?
Sheets edit; Airtable read+write. 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 “Import leads from a sheet into your Airtable CRM” from your assistant

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