# Bring your list. Leave the sequence.

> Moving your LinkedIn outreach from a sequence builder to HeyLead: export the list as a CSV, import it with import_prospects, and let agents replan each person instead of running fixed steps. What changes, what you lose, and the first hour step by step.

This is the Markdown twin of https://heylead.dev/switching (the page, in text). Index for agents: https://heylead.dev/llms.txt

Last updated 24 September 2026

You run a sequence builder you configure step by step, and it holds a list you spent weeks on. This page moves that list into HeyLead and tells you what changes when agents plan each person instead of running your steps, what you lose, and what the first hour looks like. HeyLead is an AI agent for LinkedIn outreach: it finds the right people, writes to them in the voice of your own LinkedIn posts, follows up, and handles replies. It runs from Claude Code, Cursor, any MCP client or a web dashboard.

## Export your list

Your sequence builder exports the list as a CSV. Keep whatever columns it gives you: name, LinkedIn URL, title, company, email, location. HeyLead needs a name in every row, plus one of a title, a company or a LinkedIn URL. It does not need the columns renamed or the file cleaned. Header names are matched case-insensitively, so `Job Title`, `Position`, `Organization` and `Profile URL` all land. One file per campaign. The order of the rows does not matter; HeyLead sorts them by fit.

## Import it

The import is `import_prospects` ( `src/heylead/tools/import_prospects.py` in the MIT client, heylead 0.10.396). Point it at a `.csv` or `.xlsx` file, up to 200,000 rows, or paste CSV text for a handful of rows. A legacy `.xls` is refused; save it as `.xlsx` or `.csv`.

| Column | Headers it recognises | Needed |
| --- | --- | --- |
| Name | Name, Full Name, Contact Name, Person, Lead | Yes |
| Title | Title, Job Title, Position, Role | One of the three |
| Company | Company, Company Name, Organization, Org |
| LinkedIn URL | LinkedIn URL, LinkedIn, Profile URL, LinkedIn Profile, URL, Link |
| LinkedIn ID | LinkedIn ID, Public ID, Slug | No |
| Email | Email, Email Address, E-mail | No |
| Location | Location, City, Region, Country, Geo | No |

What the import does, in the order it does it:

- **Every row is accounted for.** Each row of the file gets exactly one disposition: `imported`, `skipped` with the reason, or `deduped-against` a named earlier row. The totals are reconciled against the file's row count before anything is written. If they do not add up, the import refuses rather than reporting a partial import as a success.
- **Dedup against what you already have.** The same profile twice in one file, contacts already in the campaign, company pages posing as people, your existing 1st-degree connections (it reads your connection list), people contacted in another campaign, and your exclusion list. Each is a named reason in the report.
- **A dry run first.** `dry_run=True` reports the full per-row disposition without creating a contact, sending anything or fetching a single profile. The only LinkedIn call it makes is reading your own connection list, so the preview matches the real import.
- **Hand-picked rows skip the fit floor.** A campaign scores every person HeyLead found in a search and does not contact anyone under its fit floor (0.5 by default). A row that came in through the import is exempt: the hosted scheduler's gate ( `_passes_send_fit` in heylead-api `app/services/scheduler.py`) passes any contact whose source is `csv_import`, for warm-up, invitations and messages alike. A list you chose by hand is yours to send to.
- **The ceilings still apply.** Invitations stop at your LinkedIn plan's ceiling: 20 a day and 100 a week on a free account, 168 and 320 on Premium and Sales Navigator (measured 16 September 2026; see [pricing](https://heylead.dev/pricing)). A seat makes at most 150 profile reads in any rolling 24 hours, across every campaign and job, and posts at most 10 comments a day. An imported list is queued behind the same ceilings as a searched one; a 500-row file on a free account is five weeks of invitations, not one.
- **Nothing is sent by the import.** Rows are queued as `pending`. The campaign sends to them once you launch it, inside the sending window.

**Where the import runs today.** `import_prospects` is served by the local Python client ( `uvx heylead`) started with `HEYLEAD_TOOLS=all`; the hosted server at `heylead.dev/mcp` and the dashboard have no import yet. The local client drives your hosted workspace with the token under Settings → Integrations → Chat client → Local Python client ( `setup_profile(backend_jwt=...)`), and the import pushes the campaign to the cloud when it finishes. Outreach then runs from the cloud like any hosted campaign, with your laptop closed. See [the local client](https://heylead.dev/docs/self-hosted). For a short list, `create_campaign(people="<profile URLs>")` in the same client seeds a campaign from exactly those people, with no search and no import.

## What changes

A sequence builder runs the steps you configured, in the order you configured them, for everyone on the list. HeyLead's agents replan each person as the facts about them change, and every decision is readable with `inspect` or on the campaign page. The agents, each named after the file that runs it in the hosted backend:

- **The planner** writes a per-person daily plan from where that person is: not yet warmed, invited and waiting, connected, replied ( `daily_strategy.py`).
- **The strategist** rewrites the leftover plan when a signal, an acceptance or a first reply lands, at most 3 actions a day for one person ( `strategist_replan.py`).
- **The send-fit judge** reads each draft against the live thread and the timing and refuses a send a person would not make, such as a follow-up too soon after your own unanswered message ( `send_fit_agent.py`).
- **The reply agent** reads, classifies and answers replies from the campaign's facts, and holds anything ambiguous for you; "not now" gets a check-in in 30 days ( `reply_agent.py`).
- **The closer** books the meeting once the thread already agrees on one, at most 5 bookings a day ( `hot_lead_closer.py`).

Three defaults differ from a sequence builder, and each one is a limit you can read:

- **Approval mode by default.** A new workspace holds opening messages and follow-ups until you approve them, and the approved text is what is sent. Invitations are not held. Autopilot is one switch away, in Settings → Sending or `scheduler(action="approval_mode")`.
- **Ceilings follow your LinkedIn plan.** The invitation ceiling belongs to the seat, not to the HeyLead plan. HeyLead reads it, enforces it, and backs off from 5 minutes to 6 hours when LinkedIn pushes back before it is reached. Sends run Monday to Friday 08:00 to 22:00 in your time zone by default, and no LinkedIn call is made between 22:00 and 08:00.
- **Reads and acts are separate tools.** `show_status`, `inspect`, `campaign_status`, `accounts` and `prospect_view` only read; `campaign`, `prospect` and `scheduler` act. Every tool tells your AI client which it is, so the client can look without asking you and ask before anything is sent.

## What you lose

- **No visual sequence editor.** There are no steps to drag into order. You write the brief; the agents above decide the steps per person. What you can set is in `edit_campaign`: the follow-up count (up to 2 on Free, 5 on Pro), the InMail fallback and its quiet days, discovery on or off. Email on or off is a toggle in the campaign's settings on the dashboard.
- **No CRM of its own.** Contacts, stages, tags and notes live in HeyLead ( `contacts`, `update_contact`), and `contacts(action='export')` takes them out. The only CRM sync is HubSpot: `crm_sync` with a HubSpot private-app key, from the local client with `HEYLEAD_TOOLS=all`.
- **Google Calendar only.** `book_meeting` and the closer create the event on your Google Calendar. No other calendar is connected.
- **Email only where an address exists.** The email fallback goes to a person whose row carries an email, 14 days after an invitation with no answer, and only once you have connected a Gmail or Outlook mailbox through Unipile.
- **No import from the dashboard or the hosted server yet.** The import runs in the local client, as above.

## The first hour, step by step

1. **Connect HeyLead to your client.** In Claude Code:
   ```
   claude mcp add --transport http --scope user heylead https://heylead.dev/mcp
   ```
   then open `/mcp`, select heylead and sign in with Google. Cursor, VS Code and other clients are on the [quickstart](https://heylead.dev/docs/quickstart). No MCP client? Sign in at the [dashboard](https://heylead.dev/dashboard/login).
2. **Connect LinkedIn** in the dashboard. The seat connects through Unipile; your LinkedIn password never touches HeyLead. Ask your AI "Show my HeyLead status": `show_status` answers, and `accounts` shows the seat.
3. **Describe your offer and who you want.** `generate_icp` returns two to four buyer personas grounded in your website. Or write the brief yourself: what you sell, who it is for, what you are asking of them. The brief is what the agents write from.
4. **Create the draft.** `create_campaign` finds matching people and saves a draft. Nothing is sent. If you want only your own list in it, `edit_campaign(enable_discovery="off")` stops it finding more.
5. **Import your CSV into the draft.** From the local client with `HEYLEAD_TOOLS=all`:
   ```
   import_prospects(file_path="~/Downloads/list.csv", dry_run=True)
   ```
   Read the row dispositions, then run it again without `dry_run`. The report says how many rows imported, were skipped, and were deduped, and why.
6. **Review the draft.** `campaign_status` or the campaign page shows who is in it and what will happen first. `edit_campaign` changes the follow-up count, the InMail fallback and discovery; the campaign's settings on the dashboard hold the email toggle.
7. **Launch.** `campaign(action="launch")`. Warm-up and invitations start inside your plan's ceiling and the sending window. `campaign(action="emergency_stop")` pauses everything.
8. **Approve the first openers.** When invitations are accepted, `inspect(action="waiting")` lists the opening messages held for you, and `prospect(action="approve_message")` sends the text you approved. The dashboard's Approvals page does the same. Switch to autopilot when you trust the drafts.

HeyLead is not affiliated with LinkedIn. It reaches LinkedIn through Unipile, which is also not affiliated. HeyLead sends at a human pace: at most 20 invitations a day and 100 a week on a free LinkedIn account, Monday to Friday 08:00 to 22:00 in your time zone. LinkedIn's own rules are in the [Terms](https://heylead.dev/terms). Nothing on this page names or describes any other product beyond "a sequence builder you configure step by step" that "exports your list as a CSV".

[Start free, no card](https://heylead.dev/dashboard/login)

Related: [Pricing and the ceilings](https://heylead.dev/pricing) · [Tool reference](https://heylead.dev/docs/tools) · [The local client](https://heylead.dev/docs/self-hosted) · [What is HeyLead?](https://heylead.dev/what-is-heylead)
