Skip to main content

Batch SMS: the Insert variable picker

The Compose & Preview step of the Messages → Batch SMS wizard personalizes a shared template with {{variable}} placeholders. Three controls make that personalization safe to send: the Insert variable picker, the resolved per-recipient preview, and the gate that blocks Next: Send while a referenced variable has no backing value. This page covers all three. For the wizard steps around them — recipients, drafts, segments, cost, and the send contract — see Batch SMS: one-off multi-recipient sending. For AI-generated drafts that you personalize afterwards, see Batch SMS AI assist.

1. Where the picker lives

On the Compose & Preview step, an Insert variable chip row sits directly below the Message field. Each chip is one personalization field rendered as its {{field}} token; clicking a chip inserts that token into the message body. The chip list is built from your recipients:
  • CSV columns. Every column of the uploaded CSV except the routing columns — the phone column and, in per-row mode, the per-row message column. Routing columns address or replace the message, so they never appear as chips.
  • Contact custom fields. When recipients come from contacts, their custom fields are offered the same way.
A typical upload therefore offers {{first_name}} and {{last_name}} next to whatever org-specific columns your CSV carries, such as {{loyalty_tier}} or {{appointment_date}}. When the upload has no personalization columns, the chip row is replaced by a hint: “No personalization fields available. Upload a CSV with extra columns (e.g. first_name, last_name) or pick contacts with custom fields to enable variables.” The picker coexists with the other two ways text reaches the body:
  • Manual typing. The field is a plain textarea; type or paste {{variable}} tokens by hand at any time.
  • AI assist. The Sparkles toggle above the field drafts and rewrites copy — it writes text, the picker inserts placeholders. Neither blocks the other; see Batch SMS AI assist.
The picker only appears on shared-template batches. If your CSV carries a per-row message column, the wizard switches to per-row mode and skips the compose step entirely — see Prepare recipients.

2. Insert variables at the caret

Clicking a chip inserts the token at the cursor, not at the end of the body:
  1. The token splices in at the caret position. If you have a range of text selected, the selection is replaced by the token.
  2. The field keeps focus and the caret lands just past the inserted token, so you can continue the sentence.
Position the caret where the personalization belongs — for example between Hi and , your order is ready — then click the chip. Nothing is ever appended to the end of the body unless the cursor was already there. The picker inserts the plain {{field}} token. Liquid filters are typed by hand around or instead of a chip, using the same syntax the send API documents:
A default: filter supplies a fallback when a row has no value for the field, which also satisfies the unresolved-variable gate below. The full variable family (standard, contact, custom, agent, and region variables) is listed in the Template variable catalogue.

3. Preview the resolved message

The right-hand preview resolves the template against a real recipient instead of showing the {{…}} literals:
  • Preview recipient. A dropdown above the phone preview lists your valid recipients (up to the first 100) by phone number. It defaults to the first recipient; picking another phone re-resolves every surface below it.
  • Phone preview. The message bubble renders the body with that recipient’s values substituted — Hi {{first_name}}, … reads Hi Amara, … when Amara is selected.
  • Character and segment counter. The N / 1600 · S segments counter above the field counts the resolved body for the selected recipient, not the template with its {{…}} literals. Switching preview recipient can change both figures, because resolved names have different lengths and encodings.
  • Message Preview list. Under the editor, the first five recipients are listed with their per-row resolved bodies, so you can eyeball several substitutions at once.
What the preview shows is what the send path bills: segments are counted per resolved body, GSM-7 at 160 characters per segment (153 multipart) and UCS-2 at 70 (67 multipart). The review step repeats the same accounting across all recipients before you confirm.

4. Unresolved variables block the Send step

While the body references a variable that cannot be resolved, the wizard shows an Unresolved variables warning under the field and disables Next: Send. Two conditions trigger it:
  • Unknown variables. The token’s name matches no CSV column and no contact field — typically a typo such as {{first_namee}}. The warning lists them: Unknown variables: {{first_namee}}.
  • Missing values. The column exists but one or more rows are empty for it. The warning lists each variable with the affected row count: Missing values: {{first_name}} (2 recipients).
The warning closes with the hint “Add a column to your CSV or correct the recipient data before continuing.”, and hovering the disabled button explains “Resolve the flagged variables (or remove them) before continuing to Send.” The gate exists so a misspelled token can never reach a recipient as literal {{…}} text. To clear it, use whichever path fits:
  1. Add the column. Add the missing column to the CSV (or fill the empty cells) and re-upload, then the chip resolves for every row.
  2. Correct the chip. Delete the mistyped token and click the right chip, or fix the name by hand.
  3. Remove the token. Drop the personalization from that sentence.
  4. Supply a fallback. For missing values, a default: filter — {{ first_name | default: "there" }} — gives empty rows a value and clears the flag for them.
Once every referenced variable resolves, the warning disappears and Next: Send re-enables.

5. Worked example: three rows, two encodings

Upload this CSV:
Type Hi , click the {{first_name}} chip, and finish the sentence, so the body reads:
The chip landed at the caret after Hi , not at the end of the line. With +14155550001 selected as the preview recipient, the phone bubble shows Hi Amara, your pickup is ready… and the counter reads the resolved 88 characters. Every variable resolves — first_name is a CSV column and all three rows carry a value — so the gate stays open. The per-row billable segments, however, differ by encoding: Select Zoë as the preview recipient and the counter flips to her resolved length with 2 segments, because ë forces UCS-2’s 70-character (67 multipart) segmentation while the other two rows fit one GSM-7 segment. The review step’s encoding breakdown shows the same 2-vs-1 split across the batch before you confirm, so the row that silently doubles the bill is visible before send. Now misspell the chip as {{first_namee}}: the warning appears with Unknown variables: {{first_namee}}, Next: Send disables, and the batch cannot proceed until you click the correct chip, add a matching column, or remove the token.

See also