# Personalized video campaign builder for HeyGen and HubSpot

> Build a batch of personalized sales videos from a HubSpot list, review every script before it renders, then send each one and log the touch.

- Workflow type: app
- Services: HeyGen, HubSpot, Gmail
- Categories: Sales, Marketing
- Published: 2026-08-24

## What it does

- Pick one of your saved HeyGen video templates and see exactly which lines of the script change from person to person.
- Pull a target list out of HubSpot using filters like lifecycle stage, contact owner, or last activity date, and match contact details to the parts of the script that change, so every row previews the real text that will be spoken.
- Hit Personalize on any row to put an AI assistant to work rewriting that one person's custom line from their CRM record, then edit what it wrote before anything renders.
- Watch the whole batch render live with thumbnails as they land, then email each finished video from the rep who owns the contact and log the touch on their record automatically.

## What you'll need

- A HeyGen account on a paid plan with at least one video template saved
- A HubSpot login with your contacts and contact owners set up
- A Gmail account for each rep who will be sending videos

## Prompt

I want an app my sales team opens to run personalized video campaigns, instead of rendering one video at a time by hand. The main surface is a campaign builder where a rep picks a video template, pulls a target list out of our CRM, reviews the exact script each person will hear, and then renders and sends the whole batch from one screen.

The landing view is a simple list of saved campaigns showing the campaign name, the template it uses, how many rows it has, how many videos have rendered, how many have been sent, and when it was last opened. From there a rep opens an existing campaign or starts a new one.

Building a campaign starts with the template. Load my HeyGen templates with List Templates and show them as a pickable list. When one is selected, call Retrieve Template Details to read its variable definitions and scenes, and display every variable that template exposes, since those variables are what the rest of the builder maps onto.

Next, build the audience. Use HubSpot Search Contacts with filters the rep sets in the UI: lifecycle stage, contact owner, last activity date, and free text search. Show the matching contacts as rows in a table. Use HubSpot List Owners to resolve each contact's owner into a name and an email address, so the app knows which rep owns each row and can send from them later.

Then map HubSpot fields onto the template variables. Give the rep a mapping panel where each template variable is bound either to a HubSpot contact property, such as first name, company, or job title, or to a static value that is the same for everyone. Every row must preview the fully resolved script exactly as it will be spoken, so a rep reads the real text before spending a render. Rows with an unmapped or empty required variable should be flagged and excluded from generation until they are fixed.

Each row has a Personalize with agent button. Pressing it kicks off a background agent for that single contact. The agent reads that contact's HubSpot properties with Get Contact, including job title, company, lifecycle stage, lead status, last activity date and any other populated properties, and rewrites the custom line variable for that person in our voice, keeping it to roughly one or two sentences. It writes the result back into that row. The row shows a pending state while the agent runs and fills in with the new line when it finishes, and the rep can freely edit the text afterward. The agent only proposes copy, it never renders anything itself. Reps can run it on one row, on selected rows, or on the whole list, and each row's agent run is independent so one failure does not block the others.

Pressing Generate sends only the approved rows to HeyGen Generate Video from Template, one call per row, and stores the returned video id on the row. Cap how many renders are in flight at once. Make the cap configurable and default it to a small number, because HeyGen limits concurrent renders per plan. Queue the remaining rows and start them as earlier renders finish, so a large campaign drains safely instead of erroring out.

After Generate, the screen becomes a live render queue. Poll Retrieve Video Status / Details for each in-flight video id every five to ten seconds and show each row's state as queued, processing, completed, or failed. Renders typically take between thirty seconds and three minutes. As a video completes, show its thumbnail in the row and call Retrieve Shareable Video URL to get a share link for it. Show failed rows with the error message HeyGen returned, and give each failed row its own Retry button that re-renders just that row, without re-running the campaign or touching rows that already succeeded.

From the finished list, a rep can send each video. Sending uses Gmail Send a Message from the mailbox of the rep who owns that contact, with an editable subject and body that includes the share link and a default template the rep can change. After a successful send, log the touch on the contact with HubSpot Create Note associated to that contact, recording which template was used and the link that was sent. Show the send state and the note state on each row so nobody double sends to the same person.

Persist campaigns so a rep can leave and come back later: the selected template, the filters, the variable mapping, the rows with their personalized copy, and each row's video id, render state, send state, and note state. Do not cache HeyGen video URLs, thumbnail URLs, or share links, because HeyGen expires all of them after seven days. Store only the video id, and refetch the video status and the share URL every time a campaign is opened, so the links on screen are always live.

Several reps use this app, so show who created each campaign, and default the audience filter to the current rep's own contacts while still letting them widen it to the whole team.

## How to customize

- Change the contact filters that build your target list, such as lifecycle stage, owner, last activity date, or any property you already use
- Set how many videos render at the same time so you stay inside the limit on your HeyGen plan
- Adjust the tone and length the personalization assistant writes to, and edit the email that goes out alongside each video

## FAQ

### Do I have to approve every script before a video renders?

Yes. The builder shows you the fully resolved script for every person on the list, and you can edit any line by hand. Nothing is sent to HeyGen until you press Generate, so you never spend a render on copy you have not read.

### What happens if one video fails to render?

That row stays in the queue marked as failed with the reason HeyGen gave, and it gets its own Retry button. You fix or retry just that one person without re-running the campaign or re-rendering anyone who already succeeded.

### Why does the app fetch the video links fresh each time instead of saving them?

HeyGen expires video, thumbnail, and share links after seven days. The app saves the video itself rather than the link, and pulls a current link every time you open a campaign, so a link you hand to a customer is never a dead one.

### Can my whole sales team work out of the same app?

Yes. Campaigns are saved and shared, and each video is emailed from the mailbox of the rep who owns that contact in HubSpot, so the message lands from a familiar name rather than a shared inbox.

### Will this work on a free HubSpot account?

The contact list and the note logging work on HubSpot's free tier. The video rendering side is what needs a paid HeyGen plan, since template rendering and API access are not part of the free HeyGen tier.

Use this prompt in General Input: https://www.generalinput.com/prompts/personalized-video-campaign-builder-for-heygen-and-hubspot