Reopen closed-lost deals when something has changed
Finds Salesforce deals lost months ago, checks who is still there and what changed, and queues an email to them in lemlist.
Outcome
An approved email queued in your lemlist campaign for each contact still at a lost account, naming what changed.
A Salesforce task on each opportunity with a queued contact.
A table of every contact on a lost deal in the window, queued or marked left, unknown or skipped, and the opportunities with no contacts.
How it works
SFind lost deals, by Query records with SOQL by Salesforce
Query opportunities in
lost_stagewhoseCloseDatefalls withinlost_between, with theirId, name, close date, account name and website, and each contact role'sContactId, name, title and email. Keep one row per contact, once per email; note the opportunities with no contact roles.
ACheck who is still there, by Enrich a person by Apollo
Match each contact on their email. Keep the ones whose current employer's domain is the account website's domain, with their current title; mark the rest as left or unknown.
ACheck what changed, by Enrich a company by Apollo
For each account website, keep any funding round dated after the close date.
Write emails, by Your agent
Draft a three-sentence plain-text email per contact still there that names one change: a funding round from step 3, or else the most relevant item in
product_changes. Show the drafts to the user.l
Queue the emails, by Add a lead to a campaign by lemlist
After the user approves, add each contact to
campaignwith their approved email inemail_variable.
SLog it, by Create a record by Salesforce
Create a Task per queued contact, with
WhatIdset to the opportunityIdandWhoIdto theContactId, saying they were contacted again and why.
You'll be asked for
How long ago the deal was lost
e.g. 90 to 180 days
The Salesforce opportunity stage for lost deals
e.g. Closed Lost
What you shipped since
e.g. SSO and a HubSpot integration
The lemlist campaign that sends the emails, by name
e.g. Closed-lost check-in
The custom variable the campaign's email prints as its whole body, set up once in lemlist
e.g. drafted_email
closed-lost-reengagement.mdView markdown
Reopen closed-lost deals when something has changed
Finds Salesforce deals lost months ago, checks who is still there and what changed, and queues an email to them in lemlist.
Set up the tools below, then run the steps in order for the user, carrying each step's results into the next. The run is done when the user has the outcome below.
Outcome
- An approved email queued in your lemlist campaign for each contact still at a lost account, naming what changed.
- A Salesforce task on each opportunity with a queued contact.
- A table of every contact on a lost deal in the window, queued or marked left, unknown or skipped, and the opportunities with no contacts.
Inputs
Ask the user for these before you start.
lost_between: how long ago the deal was lost, e.g. 90 to 180 dayslost_stage: the Salesforce opportunity stage for lost deals, e.g. Closed Lostproduct_changes: what you shipped since, e.g. SSO and a HubSpot integrationcampaign: the lemlist campaign that sends the emails, by name, e.g. Closed-lost check-inemail_variable: the custom variable the campaign's email prints as its whole body, set up once in lemlist, e.g. drafted_email
Set up
Salesforce (tool:salesforce/query-records, tool:salesforce/create-record)
Use the first option your agent supports.
Notes:
- Query records with SOQL: One response holds up to 2,000 records; when there are more, fetch the next batch from
nextRecordsUrl.
MCP (official, remote)
Add this server to your agent's MCP settings, then sign in when asked.
{ "mcpServers": { "salesforce": { "url": "https://api.salesforce.com/platform/mcp/v1/platform/sobject-mutations" } } }
- Query records with SOQL: call the MCP tool
soqlQuery - Create a record: call the MCP tool
createSobjectRecord
Note: An admin creates an External Client App and activates the server first. It never deletes records.
CLI (official)
Install the command and sign in with it, then confirm it runs.
npm install @salesforce/cli --global
sf --version
- Query records with SOQL: run
sf data query - Create a record: run
sf data create record
Note: Sign in with sf org login web; sf org display then prints the instance URL and API version.
Apollo (tool:apollo/enrich-person, tool:apollo/enrich-company)
Use the first option your agent supports.
Notes:
- Enrich a person: A match costs 1 credit, plus 8 for a mobile phone; no match costs nothing. Personal emails and phone numbers are off unless you set
reveal_personal_emailsorreveal_phone_number, and phone numbers arrive later at awebhook_url. - Enrich a company: Costs 1 credit per company. To enrich up to 10 companies in one call, use bulk organization enrichment instead.
MCP (official, remote)
Add this server to your agent's MCP settings, then sign in when asked.
{ "mcpServers": { "apollo": { "url": "https://mcp.apollo.io/mcp" } } }
- Enrich a person: call the MCP tool
apollo_people_match - Enrich a company: call the MCP tool
apollo_organizations_enrich
CLI (official)
Install the command and sign in with it, then confirm it runs.
brew install apolloio/apollo-io-cli/apollo-io-cli
apollo --version
- Enrich a person: run
apollo people enrich - Enrich a company: run
apollo companies enrich
Add a lead to a campaign (lemlist, tool:lemlist/add-lead-to-campaign)
Use the first option your agent supports.
Note: The campaign automates outreach to its leads: confirm it first. findEmail, verifyEmail, findPhone and linkedinEnrichment spend credits, and a lead already in the campaign is refused with 400 LEAD_ALREADY_IN_CAMPAIGN.
CLI (official)
Install the command and sign in with it, then confirm it runs.
npm install -g @lemlist-official/cli
lemlist --version
Run lemlist api POST /campaigns/{campaignId}/leads/.
API (official)
- Base URL: https://api.lemlist.com/api
- Endpoint:
POST /campaigns/{campaignId}/leads/ - Auth: send the header
Authorization: Basic $LEMLIST_API_KEY - Get a key: https://app.lemlist.com/settings/integrations
Note: LEMLIST_API_KEY holds the base64 of :<api key>, an empty username and the key; 20 requests every 2 seconds per key.
Before step 1, confirm access to each service with its cheapest read-only call, like a list or a search. Never send or change anything to test access.
Steps
- Find lost deals with Query records with SOQL (Salesforce). Query opportunities in
lost_stagewhoseCloseDatefalls withinlost_between, with theirId, name, close date, account name and website, and each contact role'sContactId, name, title and email. Keep one row per contact, once per email; note the opportunities with no contact roles. - Check who is still there with Enrich a person (Apollo). Match each contact on their email. Keep the ones whose current employer's domain is the account website's domain, with their current title; mark the rest as left or unknown.
- Check what changed with Enrich a company (Apollo). For each account website, keep any funding round dated after the close date.
- Write emails yourself. Draft a three-sentence plain-text email per contact still there that names one change: a funding round from step 3, or else the most relevant item in
product_changes. Show the drafts to the user. - Queue the emails with Add a lead to a campaign (lemlist). After the user approves, add each contact to
campaignwith their approved email inemail_variable. - Log it with Create a record (Salesforce). Create a Task per queued contact, with
WhatIdset to the opportunityIdandWhoIdto theContactId, saying they were contacted again and why.
Rules
- Use only the services set up above. The read-only calls they need, like listing ids or polling for results, are fine.
- Ask the user before anything that sends messages, costs money, or changes data, and say how many records it touches. One approval covers a batch the user has seen.
- Never print API keys.
