---
ref: workflow:linkedin-opener-check
title: Pick the best LinkedIn opener for each lead before sending
author: thedogwiththedataonit
tools: [tool:typesafe/answer-typed-questions, tool:crustdata/search-people, tool:heyreach/add-leads-to-campaign]
tags: [capability:classify-signals, capability:enroll-in-sequence, capability:find-prospects, channel:linkedin, has:api, motion:outbound]
updated: 2026-09-29
---

# Pick the best LinkedIn opener for each lead before sending

Finds leads with Crustdata, checks each lead's role and picks the opener that fits them with Jev, and adds them to that opener's campaign.

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

- Each draft opener checked, with any that pitches, asks for more than one thing or talks about the sender flagged.
- A table of every lead with whether they hold a target role, the opener picked for them and Jev's confidence.
- Each approved lead added to the HeyReach campaign that sends their opener.

## Inputs

Ask the user for these before you start.

- `target_segment`: the people to reach, e.g. heads of growth at B2B software companies with 50 to 500 employees in the US
- `target_roles`: the roles you sell to, each with one line, e.g. growth_lead: owns acquisition or activation; marketing_lead: runs marketing; founder: a founder at a company under 50 people
- `openers`: two to five draft first messages, each with a short name, e.g. benchmark: a question about their activation rate; teardown: an offer to share a teardown of their onboarding
- `campaigns`: the HeyReach campaign that sends each opener, by name, set up once, e.g. benchmark: Openers A; teardown: Openers B
- `max_leads`: the most leads to add in one run, e.g. 200
- `min_confidence`: how sure Jev must be before its answer is used without you, e.g. 0.8; a yes-or-no answer counts as yes at or above it and as no at or below 1 minus it

## Set up

### Answer typed questions (TypeSafe AI, tool:typesafe/answer-typed-questions)

Use the API.

- Base URL: https://api.typesafe.ai
- Endpoint: `POST /v1/systemone`
- Auth: send the header `Authorization: Bearer $TYPESAFE_API_KEY`
- Get a key: https://console.typesafe.ai

Note: Put every question about one record in one request. `GET /v1/models` lists the models and is the cheapest check of a key; a request over the rate limit gets a 429 with a Retry-After header.

Note: Send `state`, `model` (`jev-latest`) and named `questions`, each with `type`, `instructions` and `criteria`: a choice maps labels to descriptions, a score lists its levels in order, a noul's is optional. Read a score by its most likely level; send unsure answers to a person.

### Search people (Crustdata, tool:crustdata/search-people)

Use the first option your agent supports.

#### CLI (official)

Install the command, then confirm it runs.

```sh
curl -fsSL https://static-assets.crustdata.com/cli/install.sh | sh
crustdata --version
```

Run `crustdata person search`.

Set `$CRUSTDATA_API_KEY` in your environment first (get a key: https://app.crustdata.com/api-keys).

#### API (official)

- Base URL: https://api.crustdata.com
- Endpoint: `POST /person/search`
- Auth: send the header `Authorization: Bearer $CRUSTDATA_API_KEY`
- Get a key: https://app.crustdata.com/api-keys

### Add leads to a campaign (HeyReach, tool:heyreach/add-leads-to-campaign)

Use the API.

- Base URL: https://api.heyreach.io
- Endpoint: `POST /api/public/campaign/AddLeadsToCampaignV2`
- Auth: send the header `X-API-KEY: $HEYREACH_API_KEY`

Note: Create the key in the HeyReach app under Settings, API keys. Every request counts toward one workspace limit of 300 requests per minute, and read endpoints use POST with a JSON body of filters.

Note: The campaign must exist and have LinkedIn sender accounts assigned before leads go in. Each lead needs a LinkedIn profile URL; the response counts added, updated and failed leads.

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

1. **Check the openers** with Answer typed questions (TypeSafe AI). Send each opener's text as the state, with a noul `pitches_product` (asks for a meeting or describes the product), a noul `one_ask` (asks for exactly one thing) and a noul `about_them` (is about the reader, not the sender). Show the user the openers that pitch, don't ask for exactly one thing or aren't about the reader, or where an answer is unsure. Keep the openers that pass every check and the flagged ones the user approves.
2. **Find the leads** with Search people (Crustdata). Search for `target_segment`, up to `max_leads` people. Keep each person's name, title, company, LinkedIn profile URL, and headline when it has one.
3. **Match leads to openers** with Answer typed questions (TypeSafe AI). Send each lead's title, headline and company as the state, with a choice `role` over `target_roles` plus other, and a choice `opener` over the approved openers' names, each described by its text, for the opener that best fits this person's role and situation. Keep each lead's role, opener and their confidences.
4. **Check the unsure ones with the user** yourself. Drop the leads whose role is other. Show the user every lead whose role or opener confidence is below `min_confidence`, and keep what the user picks.
5. **Add them to the campaigns** with Add leads to a campaign (HeyReach). After the user approves, look up each campaign in `campaigns` by name, a read-only call, and add each lead by LinkedIn profile URL to the campaign for their opener.

## Notes

One campaign per opener keeps the results apart: HeyReach's reply rate per campaign then shows how each opener does with the people it was matched to. LinkedIn's User Agreement restricts automated activity, so keep volumes within your sender accounts' limits.

Run it before each new batch of leads, and drop the weaker openers once their campaigns have enough replies to judge.

## 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.
