Hardcoding a client’s phone number, booking links, and pricing across a dozen funnel steps and workflows is asking for pain. The moment they change a tracking line or update a seasonal offer, you’re stuck manually editing dozens of text elements, button links, and email templates across the account.
I set up a centralized Custom Values setup on every sub-account I build. Update a single key in your settings, and that change immediately propagates across your landing pages, email campaigns, SMS notifications, and outbound webhooks.

Custom Values vs Custom Fields: The Core Difference
It’s easy to mix these up because the UI names sound similar, but they handle completely different scopes:
- Custom Values are global variables scoped to the sub-account level. Every visitor, contact, and workflow sees the exact same value. If you set
{{custom_values.business_support_phone}}to(555) 019-2834, that string renders identically for everyone. - Custom Fields are record-level variables scoped to a specific contact or opportunity. They store unique lead data like a submission date or vehicle model. If you need to store individual form responses, check out our guide on how to map form submission data to custom fields in GoHighLevel.
Rule of thumb: If the data belongs to the business (support email, booking URLs, core offer prices), use a Custom Value. If it changes from lead to lead, use a Custom Field.
Step 1: Setting Up Your Global Custom Values
Head to your sub-account, click Settings in the bottom-left corner, and open Custom Values. Click + Add Custom Value in the top right.
Stick to a clean naming convention before you add dozens of random tags. I use category_name in snake_case so merge tags are predictable inside workflow builders. Here is the baseline set I drop into every new client account:
company_legal_name: Registered business entity for footer disclaimers.company_support_email: Inbound support address.company_main_phone: Primary call-tracking or office number.link_google_review: Direct review generator link.offer_core_price: Current price string for the main offer.url_calendar_booking: The primary booking funnel URL.
HighLevel auto-generates the system key based on your label. If you enter Offer Core Price, HighLevel builds the merge tag {{custom_values.offer_core_price}}.
Step 2: Injecting Custom Values into Funnels and Web Pages
You can drop custom values into text blocks, button redirects, and custom HTML widgets across the funnel builder.
For standard copy, paste the merge tag right into your text block or pick it from the merge dropdown:
Standard Plan
${{custom_values.offer_core_price}}/month
Questions? Call us at {{custom_values.company_main_phone}}
When someone loads the live page, HighLevel evaluates the tag server-side and injects your stored value (e.g., 97), rendering $97/month cleanly in the browser.
You can also use custom values inside tracking snippets and custom JS blocks to pass business parameters into third-party tools:
window.agencyConfig = { accountName: "{{custom_values.company_legal_name}}", supportEmail: "{{custom_values.company_support_email}}", phoneRaw: "{{custom_values.company_main_phone}}"
};
console.log("Initialized tracking for: " + window.agencyConfig.accountName);If your dynamic funnel steps fail to load or throw SSL warnings after setting this up, check our guide on how to fix GoHighLevel domain SSL pending and DNS errors.
Step 3: Powering Workflow Automations with Custom Values
Workflows are where this setup saves the most time. Instead of hardcoding phone numbers or booking URLs into every SMS and email action, use merge tags.
Per the official HighLevel merge fields documentation, custom values evaluate just before the message is queued for dispatch.
Here’s a standard onboarding SMS action combining contact data with global values:
Hey { {contact.first_name}
}, thanks for signing up with { {custom_values.company_legal_name}
}
!
Your onboarding session is confirmed. If you need to reschedule or have questions before our call, ring us directly at { {custom_values.company_main_phone}
}
or visit { {custom_values.url_calendar_booking}
}
.
Talk soon!If you push data to external endpoints using the Webhook action inside a workflow, you can pass custom values directly in your JSON payload:
{ "contact_email": "{{contact.email}}", "contact_id": "{{contact.id}}", "agency_reference": "{{custom_values.company_legal_name}}", "webhook_source_system": "GoHighLevel_Production", "support_route": "{{custom_values.company_support_email}}"
}If your outgoing webhooks fail to parse merge variables, check our walkthrough on custom values and custom fields in GoHighLevel webhooks for payload debugging tips.
Managing Snapshot Deployments at Scale
If you manage multiple sub-accounts with HighLevel Snapshots, Custom Values are non-negotiable. Without them, deploying a snapshot means opening every single page, email, and workflow to manually replace placeholder text like “[INSERT COMPANY NAME]”.
The clean deployment flow looks like this:
- Replace all business-specific strings across funnels, emails, SMS templates, and triggers with custom value tags.
- Export the snapshot to your agency dashboard.
- Load the snapshot into your new sub-account.
- Open Settings > Custom Values and fill in the client’s specific details once.
The whole account is live in minutes. When you update the master snapshot down the line, you can push updates without overwriting existing sub-account data if you follow the rules in our guide on how to update GoHighLevel snapshots without overwriting sub-account assets.
What I Ran: A Quick Node.js Script to Audit Custom Values
When you’re auditing an account with 40+ custom values, spotting missing strings in the UI is annoying. I wrote a small script against the GoHighLevel API v2 to pull all custom values for a location and flag anything unpopulated.
import axios from 'axios'; const LOCATION_ID = 'loc_abc123xyz';
const ACCESS_TOKEN = 'pit-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'; async function checkMissingCustomValues() { try { const response = await axios.get( `https://services.leadconnectorhq.com/locations/${LOCATION_ID}/customValues`, { headers: { Authorization: `Bearer ${ACCESS_TOKEN}`, Version: '2021-07-28' } } ); const values = response.data.customValues || []; console.log(`Found ${values.length} total custom values.`); const unconfigured = values.filter(cv => !cv.value || cv.value.trim() === ''); if (unconfigured.length > 0) { console.warn(`WARNING: ${unconfigured.length} Custom Values are currently empty:`); unconfigured.forEach(item => console.log(` - ${item.name} (${item.fieldKey})`)); } else { console.log('All Custom Values are populated.'); } } catch (error) { console.error('Failed to fetch custom values:', error.response?.data || error.message); }
} checkMissingCustomValues();Running this flagged 4 empty values in my test sub-account in under 500ms, catching a missing calendar URL before running paid traffic to the funnel.
Gotchas: Syntax Errors, Caching, and Truncation
A few common pitfalls will break your merge tags if you aren’t careful:
1. Whitespace Inside the Merge Tag
HighLevel’s template parser is strict about whitespace inside curly braces. {{custom_values.company_main_phone}} resolves properly. If you write {{ custom_values.company_main_phone }} with spaces inside the brackets, the parser skips it and prints the raw curly braces directly on your live page.
2. Button URL Link Prefixes
If you’re using a custom value in a button action (Go to Website URL > {{custom_values.url_calendar_booking}}), make sure the value stored in settings includes the https:// protocol. If it’s just saved as booking.example.com, the funnel builder treats it as a relative URL and directs leads to https://yourdomain.com/booking.example.com, hitting a 404.
3. CDN Caching Delays
When you update a Custom Value in Settings, workflow emails and SMS updates apply instantly. Live funnel pages, however, sit behind HighLevel’s Cloudflare cache and can take up to 2 minutes to refresh. If a live page doesn’t show your updated value right away, hard-refresh your browser (Cmd+Shift+R or Ctrl+F5) or wait a couple of minutes for edge invalidation.
Frequently Asked Questions
Can I use Custom Values inside HighLevel Email Campaign Subject Lines?
Yes. Paste the merge tag (like Update from {{custom_values.company_legal_name}}) directly into the subject line or preview text input in the email builder or workflow action.
What happens if a Custom Value is referenced in an SMS but left blank?
If the key is empty in Settings, HighLevel swaps in an empty string. The SMS still sends, but the sentence will look broken (e.g., “Call us at today!”). To configure defensive fallbacks, check our guide on GoHighLevel merge fields and fallback values.
Can Custom Values be updated dynamically via Workflows?
No. Standard workflow actions cannot modify Custom Values. They are static sub-account globals meant to be updated manually by an admin or programmatically via the HighLevel API v2.
Can I format numbers or currency automatically inside a Custom Value?
No. Custom Values store raw string literals. If you want currency symbols, commas, or specific phone formats (like $1,499 or +1 (800) 555-0199), format the string directly in the Custom Value field.
Next Steps for Your Automation Stack
With Custom Values wired up, your funnels and workflows become modular and reusable across snapshots. If your setup routes data through external endpoints and you need to handle traffic surges cleanly, check out our guide on how to handle webhook spikes with a Redis buffer queue in Node.js.

