GoHighLevel Merge Fields: The Complete Personalization Guide for Emails, SMS, and Funnels in 2026

How to Use GoHighLevel Merge Fields

Quick Answer: GoHighLevel merge fields use double-curly-brace syntax — {{contact.first_name}}, {{custom_values.agency_name}} — to insert dynamic contact data into emails, SMS messages, and funnel pages. The merge field fails silently when the syntax is wrong or the custom value is missing, resulting in blank text or literal curly braces in your messages. The full syntax reference and the conditional personalization configuration are in Section 2.

Your automated messages are sending with “Hi {{contact.first_name}}” in them. Or worse — “Hi ,” with a blank where the name should be.

Both failures have the same root cause: a merge field that did not resolve. This guide covers the correct GHL merge field syntax, how to configure conditional personalization, and how to debug merge fields that are not resolving.

GoHighLevel Merge Field Syntax Reference

The GHL Workflow Engine resolves merge fields using a standardized syntax. The field source determines the prefix.

Merge Field Category Syntax Example Data Source
Contact Standard Fields {{contact.first_name}} CRM contact record
Contact Custom Fields {{contact.custom_field_key}} Contact-level custom fields
Custom Values (Global) {{custom_values.your_key}} Agency or sub-account Custom Values
Appointment Data {{appointment.start_time}} Booking confirmation workflows
Opportunity Data {{opportunity.name}} Pipeline deal workflows
Location Data {{location.name}} Sub-account business info
User Data {{user.first_name}} Assigned user on contact

Field Note — April 15, 2026: Debugged a merge field issue for a client today. Their appointment reminder SMS was sending “Your appointment is on at ” — both the date and time were blank. The workflow used {{appointment.start_date}} and {{appointment.start_time}}. Those field keys do not exist. The correct GHL syntax is {{appointment.start_date_time}} for the combined field, or you use the custom date format picker in the workflow action settings. Spent 45 minutes testing every appointment merge field variation. The GHL documentation lists some fields that no longer work in 2026. Always test in a real workflow on a test contact before going live.

Conditional Personalization in GoHighLevel

Conditional personalization uses GHL’s “IF/THEN” logic inside workflow steps to send different message versions based on contact data. This is more powerful than simple merge fields — it changes entire message blocks based on contact attributes.

/* Example: Conditional SMS using GHL workflow branching */

// Branch condition: contact.custom_field.industry == "dental"
// SMS on TRUE branch:
"Hi {{contact.first_name}}, your dental appointment is confirmed for {{appointment.start_date_time}}. Reply STOP to opt out."

// Branch condition: contact.custom_field.industry == "hvac"
// SMS on TRUE branch:
"Hi {{contact.first_name}}, your HVAC service appointment is scheduled. Our tech will arrive {{appointment.start_date_time}}. Questions? Call {{location.phone}}."

// Else branch (no industry set):
"Hi {{contact.first_name}}, your appointment is confirmed. See you {{appointment.start_date_time}}."

This produces genuinely personalized messages — not just name insertion. The contact’s industry field drives an entirely different message body.

Expected Error — Merge field shows literal text: If {{contact.first_name}} appears literally in your sent message, the workflow is using a “Send Email” or “Send SMS” action that is not in an active workflow context, or the contact record does not have a first name value. Add a fallback in the message: “Hi {{contact.first_name | default: “there”}},” — this syntax is supported in GHL email actions but not SMS actions (SMS does not support liquid filter syntax).

Custom Values vs. Custom Fields: Which to Use

If the data changes per contact…

Use Contact Custom Fields. These are stored on the individual contact record. Example: industry, lead source, appointment preference. Access them with {{contact.your_field_key}}.

If the data is the same across all contacts in the sub-account…

Use Custom Values. These are sub-account-level constants. Example: your agency phone number, your booking URL, your business name. Access them with {{custom_values.your_key}}. Update once — applies everywhere automatically.

If the data is the same across all sub-accounts in your agency…

Use Agency-Level Custom Values set in Agency Settings. These propagate to all sub-accounts but can be overridden at the sub-account level if needed.

Critical Failure Points: Merge Field Mistakes

Failure Point 1 — Wrong Field Key Case: GHL merge field keys are case-sensitive in some contexts. {{contact.firstName}} and {{contact.first_name}} are different fields. The standard GHL fields use snake_case (underscores). Custom field keys use whatever key you defined when creating the field. Check the exact key spelling in Sub-Account → Custom Fields.

Failure Point 2 — Missing Fallback for Empty Fields: If a merge field references a contact field that is empty, GHL renders nothing — not a space, not a placeholder, nothing. “Hi {{contact.first_name}},” becomes “Hi ,” when the name field is empty. Always use a fallback in email actions or add a workflow filter that only proceeds if the required field is not empty.

The Consensus Break: Custom Values Are Underused by 90% of GHL Users

The GHL community focuses heavily on contact-level merge fields. Custom Values are mentioned in passing but rarely taught systematically. This is a significant operational gap.

Every sub-account we audit at AutoGenCRM contains hardcoded text where Custom Values should be — phone numbers, addresses, booking URLs, and offer names typed directly into workflow messages. When any of those details change, the operator must find and update every workflow that contains the hardcoded text.

A sub-account built with Custom Values for all stable business data takes 30 minutes longer to set up initially. It saves 2–4 hours every time any business detail changes — which happens constantly with active clients. See our snapshot templates which are built with Custom Values architecture from the start.

Verified working as of April 15, 2026.

Frequently Asked Questions

What is the correct merge field syntax in GoHighLevel?

GoHighLevel merge fields use double curly braces: {{contact.first_name}} for contact fields, {{custom_values.key_name}} for Custom Values, {{appointment.start_date_time}} for appointment data. Keys are case-sensitive and use snake_case formatting. Test any merge field in a test contact workflow before deploying to live leads.

Why is my GoHighLevel merge field showing as blank?

Blank merge fields in GHL have three common causes: (1) The contact record does not have a value for that field — add a fallback or filter contacts by field-not-empty before the message action. (2) The merge field key is misspelled or using wrong case — verify the exact key in Sub-Account → Custom Fields. (3) The field is a Custom Value that has not been configured in the sub-account — check Sub-Account → Custom Values and ensure the key has a value assigned.

Can I use merge fields in GoHighLevel SMS messages?

Yes. GoHighLevel SMS messages support all standard merge field syntax — {{contact.first_name}}, {{custom_values.key}}, {{appointment.start_date_time}}. However, SMS does not support Liquid filter syntax (like | default: “there”) that email actions support. For SMS, handle empty field scenarios at the workflow branch level — only send SMS when the required fields are confirmed to have values.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top