Send Typeform leads to ActiveCampaign with a Sheets backup

Every new Typeform response becomes a tagged ActiveCampaign contact and a fresh row in your lead log spreadsheet. No copy-paste, no missed leads.

Deterministic Code
TypeformActiveCampaignGoogle SheetsSalesMarketingLead EnrichmentData SyncEmail Automation
PromptCreate

Build a code workflow triggered by a Typeform webhook on the form_response event. Typeform will POST the response payload directly to the workflow's webhook URL (set up via the form's Connect tab in Typeform). Every new submission needs to (1) land in ActiveCampaign as a tagged contact and (2) append a backup row to a Google Sheets lead log so we always have a record, even when ActiveCampaign is skipped.

Parse the Typeform payload. From form_response.answers, extract email (required), first_name, last_name, and phone by matching the answer's field.type (email, text/short_text for names, phone_number). Also pull form_response.definition.title (the form title) and form_response.submitted_at. Build a deterministic tag slug from the form title by lowercasing, replacing non-alphanumeric runs with a single hyphen, trimming hyphens, and prefixing typeform-. Example: 'Demo Request Form' becomes typeform-demo-request-form.

Validate the email. If it's missing or fails a basic format check (one @, one dot in the domain, no whitespace), skip the ActiveCampaign branch entirely and jump straight to logging with status=skipped and a short reason. Do not silently drop the response.

ActiveCampaign branch (only when email is valid):

1) Call ActiveCampaign Create Contact in sync mode (POST /contact/sync) with email, firstName, lastName, and phone. This upserts on email match, so we get back the contact id whether the contact is new or existing. Capture the returned contact.id.

2) Resolve the tag id for the derived tag slug. First call ActiveCampaign List Tags filtered by the tag name (GET /tags?search=<tag>). If a tag with an exact name match exists, reuse its id. Otherwise call Create Tag (POST /tags) with tagType=contact and the derived slug as the tag name, then use the returned id.

3) Call Add Tag to Contact (POST /contactTags) with body { contactTag: { contact: <contactId>, tag: <tagId> } }. Treat a duplicate-association error as success (the tag is already on the contact).

Google Sheets branch (always runs, both for success and skipped):

Call Append Values on the configured spreadsheet and tab (configurable inputs: spreadsheetId, sheetName, default range like Sheet1!A:H, valueInputOption=USER_ENTERED). Append a single row with columns in this order: submitted_at, email, first_name, last_name, phone, form_title, activecampaign_contact_id (empty when skipped), status (synced or skipped), and a short note (e.g. missing email or invalid email format) when skipped.

Error handling: respect ActiveCampaign's 5 req/sec limit and Retry-After header on 429. If the Create Contact or tag steps fail after retries, still append the row to Google Sheets with status=error and the error message in the note column so the lead is never lost. Return a 200 to Typeform on every accepted submission so it does not retry forever.

Inputs the user should configure when installing: the Typeform connection (for webhook setup), the ActiveCampaign credential (apiKey + accountName), the Google credential, the target spreadsheetId, the sheet/tab name, and an optional override for the tag prefix (default typeform-).

What does this prompt do?

  • Captures every new Typeform submission the moment it lands, so leads never sit waiting for a sync job.
  • Adds or updates the lead in ActiveCampaign using their email, and applies a tag tied to the form so the right welcome series fires automatically.
  • Appends a tidy backup row to your Google Sheets lead log with the timestamp, contact details, form name, and the matching ActiveCampaign contact ID.
  • If a response is missing or has a malformed email, it still logs the row marked as skipped so nothing disappears silently.

What do I need to use this?

  • A Typeform account where you can turn on a webhook from the form's Connect tab.
  • An ActiveCampaign account with permission to add contacts and tags.
  • A Google account with edit access to the spreadsheet you want to use as your lead log.
  • The spreadsheet ready with a header row for timestamp, email, first name, last name, phone, form name, ActiveCampaign contact ID, and status.

How can I customize it?

  • Change which Typeform forms feed the workflow, or run separate copies per form so each one gets its own tag.
  • Edit the tag naming pattern so it matches how your ActiveCampaign automations are set up (for example a campaign code or a region prefix).
  • Add or remove columns in the lead log spreadsheet to match the fields your team actually reviews.
  • Adjust what counts as a skip, for example also skipping submissions from internal email domains or test entries.

FAQs

Will this create duplicate contacts in ActiveCampaign?
No. The workflow matches on email, so an existing contact is updated with the new details rather than duplicated. A new contact is only created when the email is brand new.
What happens if the form does not collect an email address?
The workflow still records the submission in your Google Sheet with a status of skipped, so you have a complete audit trail. ActiveCampaign is not called for that response.
Can I use this with more than one Typeform?
Yes. You can point several forms at the same workflow, and the tag applied in ActiveCampaign is derived from the form name so each form can trigger its own automation series.
Do I need a paid ActiveCampaign plan?
Any ActiveCampaign plan that supports tags and the standard API works. Tag-triggered automations are a core feature, not a premium add-on.
How fast does the lead reach ActiveCampaign after they submit?
Typeform sends the submission to the workflow within seconds, so the contact and tag are usually in ActiveCampaign before the respondent has closed the thank-you page.

Related templates

Call overdue Xero customers with an AI collections agent

Every weekday at 10am, an AI voice agent phones your most overdue Xero accounts, logs what each customer promised, and reports back to finance in Slack.

LiveKit
Xero
Deepgram
+2
Agentic Task
Local listing health board for every location you manage

See every Google Maps listing you manage on one screen, ranked worst first, with an audit button that writes the fix list for you.

Local Business Data
Google Sheets
App
Let support send one-off Loops emails without an engineer

Your team picks a template, finds the customer, checks they are safe to email, then sends it, with every send logged where the whole team can see it.

Loops.so
Stripe
Google Sheets
App
Stop cold emails to anyone with a live deal in Pipedrive

Every night at 2am, pull the contacts on your open and won deals and block them from your cold outreach before the next send goes out.

Mailshake
Pipedrive
Google Sheets
Deterministic Code
iMessage campaign console with pre-flight checks and delivery board

Build every text campaign in one screen: check who is actually reachable, see a realistic send plan, then watch delivery land row by row.

LoopMessage
Google Sheets
HubSpot
App
LinkedIn Ads budget pacing dashboard for every client account

See every LinkedIn ad account's spend against the budget you committed to, catch overspend early, and rebalance without rebuilding a spreadsheet.

LinkedIn Ads
Google Sheets
Slack Bot
App

Stop losing form leads between tools.

Connect Typeform, ActiveCampaign, and Google Sheets once, and Geni handles the rest every time a new response comes in.