If your CSV exports clean, stable headers, importing it into any sender is just field mapping. The convention is one column per step — like step_1_subject and step_1_body through step_N_subject and step_N_body — plus the basics like first_name and email. This guide shows the exact mapping for Smartlead, Instantly, Apollo, and HubSpot, one section each. Bookmark it for your next campaign.
First, understand the column layout
A personalized sequence CSV looks like this. Each row is one contact, and each step's subject and body live in their own columns, already written for that person.
| first_name | step_1_subject | step_1_body | step_2_subject | … | |
|---|---|---|---|---|---|
| theo@northwind.dev | Theo | The ingestion bug you posted | Theo, saw your post about… | Following up on the runbook | … |
Because the writing is already done per row, your sending tool does not generate anything. It just inserts the right column into the right step. That is what the merge field does.
Smartlead
In Smartlead, create a new campaign and upload the CSV as your lead list. Any column beyond the standard ones is read as a custom variable automatically. When you build your sequence, add one email step per step in your CSV, and reference the matching columns with double curly braces.
- Email 1 subject:
{{step_1_subject}} - Email 1 body:
{{step_1_body}} - Email 2 subject:
{{step_2_subject}}, and so on.
Send a test to yourself first to confirm the variables resolve. If you see the raw {{step_1_body}} text in the test, the column name in your CSV does not match the variable exactly, so check casing and spelling.
Instantly
The flow in Instantly is nearly identical. Upload the CSV when creating a campaign, and Instantly maps known columns and keeps the rest as custom variables. During import you can confirm or adjust how each column maps. Build your sequence steps and drop the same variables in, using Instantly's variable syntax — again one step per pair of columns.
One tip: Instantly lets you preview a few contacts before launching. Use it. Scan three or four rows to make sure each contact's body matches their company, not someone else's, which catches any column misalignment instantly.
Apollo
In Apollo, import the CSV into a list, and the per-step columns come in as custom fields on each contact. When you build a sequence, reference those custom fields as variables in the subject and body of each step. Apollo's variable picker will show your imported fields, so you select step_1_subject for the first email's subject line and so on.
Since Apollo also bundles data and sending, this is a common path for teams already living in Apollo: enrich and source there, draft the emails elsewhere, then bring the finished copy back in as fields.
HubSpot
HubSpot treats the columns as contact properties rather than campaign variables, so there is one extra setup step. Before importing, create custom contact properties that match your column names, such as a single-line text property called step_1_subject. Then import the CSV and map each column to its property.
In a HubSpot sequence or marketing email, you reference these as personalization tokens. Insert the token for step_1_body into the first email, and HubSpot fills in each contact's stored value. The mapping is a little more manual than the dedicated senders, but it works the same way underneath.
A quick troubleshooting checklist
| Symptom | Likely cause | Fix |
|---|---|---|
Raw {{step_1_body}} shows in the email | Variable name does not match the column | Match casing and spelling exactly |
| Wrong contact's text appears | Columns shifted during import | Re-import and verify the header row |
| A step is blank | Empty cell in that row | Filter for blanks before sending |
| Special characters look broken | Encoding mismatch | Save and import the CSV as UTF-8 |
Frequently asked questions
Sending tools referenced: Smartlead, Instantly, Apollo, and HubSpot. Exact menu labels change as these tools update, so use this as a map rather than a literal click path.