How to personalize LinkedIn messages with first name, company and custom fields
Insert a variable like {{first_name}} once in WarmySender's campaign builder, and every prospect receives a message with their own name, company, and any custom data you imported from a CSV — automatically, at send time.
What is a variable, and how does it work?
A variable is a placeholder you put in your message that gets swapped for the prospect's real information just before sending. For example, type Hi {{first_name}} and WarmySender sends "Hi Marie" to Marie, "Hi Pierre" to Pierre, and "Hi Karim" to Karim — automatically, for every prospect on your list. You write the message once; every prospect gets a version that looks hand-written for them.
Variables work the same way in every channel WarmySender supports: LinkedIn invite notes, LinkedIn follow-up messages, LinkedIn InMails (subject and body), cold email subject lines, and cold email bodies. The same token, like {{first_name}}, means the same thing everywhere — so you can copy a personalized line from a cold email step into a LinkedIn invite note and it will still render correctly.
WarmySender is a 4-pillar outreach platform — Cold Emailing, Email Warmup, LinkedIn Outreach, and Multichannel sequences. Variables are the foundation of personalization in every pillar.
What variables can I use without importing anything?
WarmySender ships with 15 built-in variables — drawn from each prospect's profile, your sender mailbox, your campaign settings, and any LinkedIn URL you imported — that you can use in any message without importing custom fields. Every built-in variable appears in the Insert Variable button's panel under a labeled category.
Contact variables (your prospect's profile)
{{first_name}}- The prospect's first name. Example: Marie.
{{last_name}}- The prospect's last name. Example: Dupont.
{{email}}- The prospect's email address. Example: [email protected].
{{title}}- The prospect's job title. Example: Marketing Director.
{{city}}- The prospect's city. Example: Lyon.
{{country}}- The prospect's country. Example: France.
{{industry}}- The prospect's industry. Example: SaaS.
Company variables
{{company}}- The prospect's company name. Example: Acme SA.
Sender variables (you, the person sending)
{{sender_name}}- Your full name as set in your mailbox profile. Example: Numan Hamza.
{{sender_email}}- The mailbox the message is sending from. Example: [email protected].
{{sender_company}}- Your company name. Example: WarmySender.
Campaign variables
{{campaign_name}}- The name of the running campaign. Example: Q2 Outbound to SaaS Founders.
LinkedIn-specific variables
{{linkedin_profile_url}}- A link to the prospect's LinkedIn profile. Example: linkedin.com/in/marie-dupont.
{{linkedin_member_id}}- The LinkedIn member ID for the prospect (used in advanced workflows).
Variable names are case-insensitive — {{first_name}} and {{firstName}} both work and resolve to the same value. We recommend the snake_case form (first_name) for consistency with the Insert Variable button, but if your team already uses camelCase your existing templates will keep working.
How do I add custom fields from a CSV?
Any extra column in your CSV beyond the standard ones automatically becomes a custom variable. If your CSV has a column called recent_post_topic, you can immediately use {{recent_post_topic}} in your message and each prospect will get their own value substituted in — no extra setup, no field-mapping ceremony.
Worked example: imagine you scrape each prospect's most recent LinkedIn post topic into a column called recent_post_topic before import. Your invite note can then say:
Hi {{first_name}} — really enjoyed your recent post on {{recent_post_topic}}. Would love to connect.
WarmySender sends:
- To Marie (recent_post_topic = "ABM in late-stage SaaS"): Hi Marie — really enjoyed your recent post on ABM in late-stage SaaS. Would love to connect.
- To Pierre (recent_post_topic = "PLG signals for outbound"): Hi Pierre — really enjoyed your recent post on PLG signals for outbound. Would love to connect.
The Insert Variable button shows your custom fields in a dedicated "Custom Fields" section so you do not have to remember the exact column names. Column names are normalized to lowercase with underscores, so a CSV header Recent Post Topic becomes the token {{recent_post_topic}}.
Two ways to write a custom field — both work the same
Every custom field can be written two equivalent ways, and they resolve to exactly the same value. For a custom field named hook, both of these are correct and interchangeable:
{{custom.hook}}— the explicit form, with thecustom.prefix that matches the "Custom Fields" group in the Insert Variable button.{{hook}}— the short form, with no prefix.
Use whichever you prefer. Hi {{first_name}} — loved your point about {{custom.hook}}. and Hi {{first_name}} — loved your point about {{hook}}. send the identical message to every prospect. The Insert Variable button inserts the {{custom.hook}} form, but if you have already typed {{hook}} in a template it will keep working without any change.
Match the field name exactly
Custom field names must match the column you imported exactly — same spelling and the same capitalization. Matching is case-sensitive for custom fields, so a column named hook is written {{custom.hook}} (or {{hook}}), not {{custom.Hook}} or {{custom.HOOK}}. If the spelling or capitalization does not line up with your column, that field will come through blank.
To keep this simple, we recommend importing your custom columns in lowercase (for example hook, observation, shared_connection) and using the lowercase token to match. The Insert Variable button always inserts the exact, correctly-cased token for you, so clicking it is the safest way to avoid a mismatch.
You can have as many custom fields as you like — there is no hard cap. The most personalized cold outreach campaigns we see typically use one to three custom fields beyond the built-in variables.
What if some prospects are missing a field?
Add a fallback. The syntax is {{variable_name | default: 'fallback'}} — when the field is missing or empty for a prospect, WarmySender substitutes the fallback string instead, so you never get a message that reads "Hi ,". Set a fallback on every variable that appears in the first line of your message.
Examples:
Hi {{first_name | default: 'there'}}— sends "Hi Marie" to Marie, "Hi there" to a prospect whose first name is missing.Working at {{company | default: 'your company'}}— sends "Working at Acme SA" to Marie, "Working at your company" if the company field is blank.Hi {{first_name | default: 'friend'}} from {{company | default: 'your team'}}— combines two fallbacks in the same line.
The fallback string goes in single quotes inside the braces. You can use any text you like — including spaces, punctuation, and emoji. The fallback applies only when the variable is missing or empty for a given prospect; prospects with the field populated get their real value.
Fallbacks work on custom fields exactly the same way. A custom field that you expect to be blank for some prospects should always carry a fallback — for example {{custom.hook | default: 'Hi'}} (or the short form {{hook | default: 'Hi'}}) sends the prospect's real hook when it is filled in and "Hi" when it is empty. An empty custom field with no fallback simply renders as nothing, so the surrounding text closes up around the blank.
We recommend setting a fallback on every variable that appears in the first line of your message — the greeting is the most visible place for a missing field, and a smooth fallback like "Hi there" reads naturally where "Hi ," would look broken.
How do I preview the rendered message before sending?
Every step in the campaign editor has a Preview pane on the right that shows the rendered message with the first prospect's actual data substituted in. Use it to sanity-check your variables before you launch — the preview updates live as you type.
If you insert {{first_name}} and then type more text, you see the substitution in real time. If a variable shows up in the preview as a blank space or as the literal token text, that is a signal the field is missing for the preview prospect — switch the preview to a different prospect (there is a selector at the top of the preview pane) and verify the variable resolves correctly, or add a fallback.
The preview pane also catches typos. If you accidentally type {{firstname}} with no underscore for a custom field that does not exist in your list, the preview shows the raw token text — that is your cue to fix the typo or check that your CSV has the expected column.
Can you show a complete worked example?
Here is a 3-step LinkedIn sequence that uses both built-in and custom variables with sensible fallbacks. Imagine you have imported a CSV with a custom column called shared_connection. The same patterns work in cold email campaigns and LinkedIn outreach campaigns alike.
Step 1: invite note (300-character limit on LinkedIn)
Hi {{first_name | default: 'there'}} — I noticed we both know {{shared_connection | default: 'a few people in {{industry}}'}}. Would love to connect and trade notes on what is working in {{industry | default: 'your space'}} this quarter.
Step 2: follow-up message after acceptance
Thanks for connecting, {{first_name | default: 'there'}}. Quick question — what is the biggest challenge you are seeing at {{company | default: 'your company'}} on the {{industry | default: 'outbound'}} side right now? Happy to share what we are seeing across other {{industry | default: 'similar'}} teams if useful.
Step 3: closing message a few days later
Following up here, {{first_name | default: 'there'}} — just wanted to mention that I put together a quick teardown of three {{industry | default: 'outbound'}} sequences that are working in 2026. Want me to send it over?
Every prospect on the list receives a message that reads as if it was written specifically for them, even though you only wrote it once. WarmySender substitutes the variables at send time, respecting your daily LinkedIn limits, your sending window, and your account ramp.
Common questions about variables
What happens if a prospect does not have a first name on file?
The variable renders as an empty string by default — so Hi {{first_name}}, with a missing first name becomes Hi , which reads awkwardly. To handle this cleanly, always add a fallback to greeting variables: Hi {{first_name | default: 'there'}}, renders as Hi Marie, for Marie and Hi there, for a prospect with a blank first name. We recommend setting a fallback on every variable that appears in the first line of your message.
Can I use variables in the subject line of an InMail or cold email?
Yes. The subject line is a full template field with the same variable support as the message body. You can personalize InMail and cold email subjects with {{first_name}}, {{company}}, custom fields, and fallbacks — exactly as you would in the body. A personalized subject line typically lifts open and reply rates noticeably; an InMail subject of "Quick question for {{first_name | default: 'you'}}" outperforms a generic "Quick question" in most workspaces we see.
What happens if I misspell a variable name?
If you type a variable that does not exist — say {{first_naem}} with the letters transposed — the message renders the empty value at that spot, so the prospect would see a blank space where the variable was. The Preview pane catches this before launch: switch the preview to a prospect you know has a first name, and if the position is blank, the variable name is wrong. We also validate every variable reference at campaign launch time and block the launch with a clear error if your template references a custom field that does not exist on any prospect in your audience.
Do variables work in the LinkedIn connection invite note too?
Yes, and they are recommended there. LinkedIn invite notes are capped at 300 characters, so every character matters — and personalization is the single highest-impact lever you have to lift acceptance rates. The variables work the same way as in any other field: insert {{first_name}} with the {} button, set a sensible fallback, and your invite notes will be personalized for every prospect within the 300-character limit. WarmySender counts characters after variable substitution, so the editor warns you if a prospect's name is long enough to push the rendered invite over the limit.
Are variable names case-sensitive? What about {{first_name}} versus {{firstName}}?
Both work — WarmySender accepts either format. We normalize variable names internally, so {{first_name}}, {{firstName}}, and even {{First_Name}} all resolve to the same value. We recommend the snake_case form (first_name) for consistency with what the Insert Variable button inserts, but if your team already uses camelCase, your existing templates will continue to work without changes.
Can I use variables in email campaigns the same way?
Yes — the variable system is shared across every channel WarmySender supports. The same {{first_name}}, {{company}}, and custom-field tokens work in cold email subject lines, cold email bodies, LinkedIn invite notes, LinkedIn follow-up messages, and LinkedIn InMails (both subject and body). A multichannel campaign that combines email and LinkedIn steps can share personalization tokens across all of them — define your custom field once on import, and use it everywhere.
How do I add a new custom field after I have already imported the list?
Two options. (1) Edit your CSV to add the new column, re-import it, and choose "Update existing prospects" in the import dialog — WarmySender matches by email address and adds the new column without disturbing the rest of your data. (2) Add the field directly on a single prospect via the prospect detail page if you only need to update a handful. After the new field is in your audience, it appears in the Insert Variable button under "Custom Fields" automatically — refresh the campaign editor to pick it up.
What is the difference between {{first_name}} and {{firstName}}?
None — WarmySender accepts either format and the two are aliases for the same value, so you can mix and match without breaking anything. We standardize on the snake_case form ({{first_name}}) in the Insert Variable button because it matches the way our CSV import headers are normalized, but the rendering engine treats the two interchangeably. Pick whichever style your team prefers.
My message step says it is waiting on a template fix, but my custom fields are filled in — what is going on?
Both ways of writing a custom field now work and are treated as the same thing: {{custom.hook}} and the short form {{hook}} resolve to the identical value for a custom field named hook. If a step is still flagged as waiting on a template fix even though your data looks complete, check that the field name in your message matches your imported column exactly — same spelling, same capitalization (matching is case-sensitive for custom fields). For example, a column named hook must be written {{custom.hook}} or {{hook}}, never {{custom.Hook}}. The quickest way to guarantee a match is to click the Insert Variable button and pick the field from the "Custom Fields" list, which inserts the exact, correctly-cased token. If a particular field is meant to be blank for some prospects, add a fallback — {{custom.hook | default: 'Hi'}} — so an empty value is filled in instead of leaving the step waiting.
People also ask
Common adjacent questions about variables and personalization that come up alongside this guide.
Can I use variables in cold email campaigns too?
Yes — the Insert Variable button works identically in the cold email step editor. The same tokens ({{first_name}}, {{company}}, custom fields, fallbacks) substitute the same way at send time. See the worked example above for tokens that are equally valid in cold email and LinkedIn steps.
What is the difference between variables and merge tags?
They are the same thing. "Variable" is what we call them in the WarmySender editor; "merge tag" is the older mail-merge term you may have seen in tools like Mailchimp. Both refer to the same idea: a placeholder like {{first_name}} that gets replaced with each prospect's real data at send time.
Can I use AI to personalize each message individually instead of variables?
That is a separate feature on our roadmap. Variables cover the deterministic case — every prospect named Marie gets "Marie" in the greeting. AI-per-message personalization (writing a fully unique sentence for each prospect from a profile snippet) is a stronger lift on reply rate but a different mechanism. The two are complementary, not exclusive: in a future release you'll be able to use AI to populate a custom field at import time and then reference that field as a variable in your message.
Does the Insert Variable button work in the multichannel campaign builder?
Yes. The multichannel campaign builder uses the same step editors as single-channel LinkedIn and email campaigns, so the {} button is in every step regardless of channel. Tokens you define on import (custom fields) are available across every step in the multichannel sequence.
What happens if I use a variable that does not exist on a prospect?
It renders as an empty string at send time, which is why fallbacks matter. The launch-time validator catches the common case where a custom-field name is wrong (typo, mis-cased, not present in the imported CSV) and blocks the launch with a clear error. The Preview pane is your second safety net — preview the message against a few prospects before launch.
Can I preview a specific prospect's message before sending?
Yes. The Preview pane on the right of the step editor has a prospect selector at the top — click it to switch between prospects on your audience, and the rendered message updates instantly. Useful for spot-checking a prospect with edge-case data (long name, missing company, exotic custom-field value).
Still stuck on a variable that is not rendering the way you expect? Email [email protected] with a screenshot of the editor and the Preview pane, and we will help you sort it out.