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.
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
Every 30 minutes, ClickRuntime reads your Marketing leads sheet and picks out rows without a status.
For each lead it takes the web domain from the website or email address.
It looks for a company with that domain in your Airtable Companies table, updating it if found or creating it if not.
The row in the sheet is marked Imported or Updated so it is not handled again.
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
Build your own
Need it to work differently?
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
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?
Does it change records sales has already edited?
Can I import into Contacts as well as Companies?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Research companies from a sheet into Airtable
Companies you add to a sheet are looked up and saved in Airtable with industry, size and a short summary.
See how it worksCheck purchase requests against your budget sheet
New purchase requests in Airtable are checked against the department budget in your sheet and approved, flagged or rejected.
See how it worksSave every form entry to Airtable and a sheet
Each form submission becomes an Airtable record and a sheet row, and you get an email confirming it arrived.
See how it worksKeep exploring
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.