# Review and approve Lemlist openers before anyone gets enrolled

> Stage a batch of prospects, let an agent draft a personalized opener for each one, then approve them line by line before a single lead enters a campaign.

- Workflow type: app
- Services: Lemlist, Google Sheets, HubSpot
- Categories: Sales, Marketing
- Published: 2026-08-31

## What it does

- Load a batch of prospects from a Google Sheet or a HubSpot contact search into one review screen with name, company, email and an opener column
- Hit Draft openers and a research agent reads up on each selected prospect, then writes a personalized one line opener into their row along with a note on what it found
- Edit any opener inline, mark each prospect approved or rejected, and watch the drafted, approved and rejected counts update as you work
- Push only the approved rows into the campaign you pick, carrying the opener and any extra personalization across, so nothing unapproved can ever reach a send

## What you'll need

- A Lemlist account with at least one campaign already set up
- A Google account with your prospect sheet, or a HubSpot login if you would rather pull the batch from your CRM
- A list of prospects with names, companies and email addresses

## Prompt

Build me an app for staging and quality checking a batch of prospects before anyone gets enrolled in a Lemlist campaign. Today that review happens in a spreadsheet with a research tab open beside it. The human approval gate is the whole product here: a reviewer reads and okays every opener before it can be sent, so do not build an auto push path or any way for a row to reach a campaign without a person approving it.

The main screen is a staging table with one row per prospect and columns for name, company, email, opener, status, and campaign. A Load batch control brings prospects in two ways. From Google Sheets, the reviewer picks a spreadsheet and range and maps columns to name, company, and email, and the handler reads it with Get Values. From HubSpot, the reviewer filters a contact search by properties such as lifecycle stage, owner, or created date, and the handler reads it with Search Contacts. Store every loaded batch along with its source so the same list never gets loaded twice: dedupe incoming rows by email address against prospects already staged, and report a count of skipped duplicates after each load.

A Draft openers button kicks off an embedded background agent over the rows the reviewer has selected. For each prospect the agent researches the person and their company on the web, then writes a single personalized one line opener into that prospect's opener column and sets the row status to drafted. Have the agent write each row back as it finishes so the table fills in progressively rather than all at once, and have it save a short note of what it found so the reviewer can sanity check the claim behind the opener. If the agent cannot ground an opener in a real finding, it should leave the opener blank and flag the row rather than invent something.

The reviewer then works the table like a queue: edit any opener inline, then mark the row approved or rejected. The target is a 30 to 60 second review per opener, so keep rows compact and put the opener text, the research note, and the approve and reject controls all within reach without opening a modal. Show running counts of drafted, approved, and rejected across the batch. Approving is what unlocks a prospect for sending, and nothing else in the app may set that status.

A Push approved button enrolls only the approved rows. The reviewer first picks a target campaign from a dropdown populated by List Campaigns. For each approved prospect, check Get Lead by Email first and skip anyone already present in that campaign, then call Create Lead in Campaign with their name, email, and company, populating Lemlist's built in icebreaker field with the approved opener. Icebreaker is a reserved lead field alongside email, firstName, lastName, phone, linkedinUrl, companyName, and companyDomain, so the opener belongs there rather than in a custom variable. Any extra personalization columns the batch carries go through Add Lead Variables as custom variables. Custom variable names cannot collide with a reserved name or with an existing custom variable, so validate the names before creating them.

Track a status on every prospect of drafted, approved, rejected, or pushed. Move a row to pushed only after Lemlist confirms the lead was created, and store the campaign name so the table shows which campaign each prospect landed in. Enforce the approval gate in the handler and not just in the UI: the push handler must refuse any prospect whose status is not approved, and editing an opener after approval should knock the row back to drafted so the new wording gets read before it can go out. Rejected and pushed rows stay visible for the record and are never eligible to be pushed again.

If the batch came from a Google Sheet, offer an optional write back that uses Update Values to put the final status and the approved opener into columns on the source sheet, so the spreadsheet the team already keeps stays in sync with what actually got enrolled.

## How to customize

- Set the tone and length of the openers the agent writes, or give it a few of your own examples to match
- Add extra personalization columns beyond the opener and have them carried into the campaign as merge fields
- Turn on writing the review status and approved opener back to your source spreadsheet so the sheet the team already keeps stays in sync

## FAQ

### Can a prospect get emailed without me approving them first?

No. The push step only picks up rows you have marked approved, and the app refuses anything else even if it is selected on screen. If you edit an opener after approving it, the row drops back to drafted so you read the new version before it can go out.

### Where do the personalized openers come from?

When you hit Draft openers, a research agent looks up each selected prospect and their company on the web, then writes a one line opener into their row along with a short note about what it found. If it cannot find anything solid it leaves the opener blank and flags the row instead of inventing something.

### Can I rewrite an opener I do not like?

Yes. Every opener is editable directly in the row. Most teams spend 30 to 60 seconds per prospect tightening the wording so it reads like a person wrote it, then approve or reject and move on to the next one.

### Do I have to keep my prospects in a spreadsheet?

No. You can load a batch from a Google Sheet or pull one straight from a HubSpot contact search. Either way the app remembers what it has already loaded, so the same list does not get staged twice.

### How does the opener show up in my emails?

It lands in the icebreaker field Lemlist already gives every lead, so you can drop it into any campaign email as a merge tag. Extra personalization columns from your batch are carried across as custom fields you can use the same way.

Use this prompt in General Input: https://www.generalinput.com/prompts/review-and-approve-lemlist-openers-before-anyone-gets-enrolled