# Message variables (macros)

> Use standard and named contact variables reliably in portal campaigns, previews, journeys, and autoresponders.
> Source: https://docs.23telecom.co.uk/sms/macros/

Instructions for LLMs: This is one page of the 23 Telecom messaging API docs
(SMS today; more channels planned). Base URL: https://restlink23telecom.com/api/v1,
auth via the X-API-Key header. Match errors on the error_code field, never on
description text. Full docs: https://docs.23telecom.co.uk/llms-full.txt · Schemas: https://docs.23telecom.co.uk/openapi.yaml

Message variables insert a different contact value into each outgoing portal
campaign message.

## Where substitution happens

The portal substitutes variables in simple and advanced campaigns, A/B
variants, duplicate laps, journey Send SMS nodes, and autoresponders. Values
are applied per contact at send time and in database-backed previews.

  The external SMS API (`/sms/send`, `/sms/send-individual`, and
  `/integrations/sms/send`) does **not** substitute contact variables. Build
  each recipient's text yourself and use
  [/sms/send-individual](https://docs.23telecom.co.uk/sms/send-individual) for recipient-specific batches.

## Standard variables

| Variable | Value |
| --- | --- |
| `{first_name}` | First name |
| `{last_name}` | Last name |
| `{phone}` | Phone number |
| `{email}` | Email address |
| `{custom_1}` … `{custom_10}` | Ten custom contact fields |
| `{custom1}` … `{custom10}` | Legacy spellings of the custom fields |
| `{opt_out_link}` | Recipient-specific opt-out link |

## Named variables

Name custom fields in the People database variables block, during CSV import,
or in People settings. Names can contain at most 64 characters. They are
account-wide: team members see the same names in every workspace.

After naming a field `Deposit amount`, type the friendly name as a variable,
for example `{deposit amount}`.

## Matching

Matching is case-insensitive. Surrounding spaces, inner spaces, and underscores
are ignored, so `{deposit amount}`, `{Deposit_Amount}`, and `{depositamount}`
all match a field named `Deposit amount`.

Standard variable names take priority over custom names. If two custom names
collide after matching is normalized, the lower custom number wins. A rename
applies to the next send and preview.

## Unknown tokens stay literal

An unmatched token such as `{source}` or `{clickid}` is sent unchanged, which
allows tracker placeholders to keep working. Editors warn about unmatched
tokens and offer Map and Name actions, but the warning never blocks launch.
Spintax such as `{hello|hi}` is a separate feature and is not treated as a
contact variable.

## Empty values and cost

When “skip empty” is enabled, contacts without a value for a variable used by
the message are skipped. Estimates use each recipient's expanded text, while
the content budget reserves the worst-case width for every known variable.
See [encoding & segments](https://docs.23telecom.co.uk/sms/encoding) for GSM-7, Unicode, and segment limits.