Custom Values & Fields

Custom Values & Custom Fields

Two related ideas power Mass's data extensibility. Custom values are the {{merge fields}} that get resolved into live copy — your dynamic placeholders. Custom fields are the columns you add to the CRM record to store data the platform doesn't ship by default. Together they let you shape both what you store and how it shows up everywhere, all resolved through one Context Engine.

15 min read · The complete data-extensibility guide

Two concepts, one engine

Custom values are dynamic placeholders; custom fields are data you store. Both flow through the Context Engine.

A custom value is a token like {{first_name}}, {{company}}, or {{deal.value}} that gets replaced with a real value at the moment a message, email, or design is rendered. A custom field is a piece of data you define and store on a record — say an "industry" or "plan tier" you want to keep on every contact. The two meet when you reference a custom field as a custom value: {{contact.custom_fields.industry}} stores it once and uses it anywhere.

Both are resolved by the Context Engine — the same deterministic fact-store that keeps your whole system congruent. Define a fact once, and every surface that renders a token reads from that single source of truth, so your funnels, emails, campaigns, and creative never drift out of sync.

  • Custom values{{merge field}} tokens that resolve into live copy at render time.
  • Custom fieldsyour own data columns on the CRM record, beyond the built-in profile.
  • Where they meetreference a custom field as a value with {{contact.custom_fields.<key>}}.
  • One engineboth resolve through the Context Engine, so every surface reads one source of truth.

Custom values: the merge-field resolver

A whitespace-tolerant, case-insensitive token grammar resolved against a real context.

Custom values are written as `{{token}}` placeholders. The resolver replaces each one against a context made of the contact and, optionally, a deal, the owner, and the tenant. Contact tokens cover first_name, last_name, full_name, email, phone, company, job_title, city, state, country, lifecycle_stage, lead_score, and derived values like last_activity_days and last_contacted_days. Deal tokens cover deal.title, deal.value, deal.currency, deal.stage, deal.probability, and deal.expected_close_date.

Tokens are case-insensitive and whitespace-tolerant, so `{{ First_Name }}` resolves the same as `{{first_name}}`. You control what happens when a value is missing — leave it empty or keep the raw token — and whether to HTML-escape the result, which matters when you're rendering into an HTML email body versus plain text.

  • Contact tokensname, email, phone, company, job title, location, lifecycle stage, lead score, and recency.
  • Deal & owner tokensdeal.title, deal.value, deal.stage, probability, close date — plus owner and tenant context.
  • Forgiving grammarcase-insensitive and whitespace-tolerant, so token casing and spacing never break a send.
  • Missing & escapingchoose empty-vs-keep on a missing value, and HTML-escape for HTML bodies.

Where custom values resolve

The same tokens work across messages, campaigns, the workflow builder, and designs.

Custom values aren't a CRM-only feature — they're a platform primitive. The merge-field resolver powers the body and subject of CRM messages, every step of a personalized campaign, and any template-preview path. A field catalog backs the UI picker so you can insert a token without memorizing its name, and the workflow builder exposes the same variables (including contact, user, account, and deal custom fields) for automations.

The Design Studio speaks the same language. A text layer can contain `{{token}}` substitutions, and any layer can bind a mergeField (text, image source, or fill) or a visibilityField to show or hide based on data. The design render SDK accepts the values at render time, so a single template produces on-brand, personalized creative at scale — and funnels and automations map the dotted CRM tokens onto the design engine's underscored names one-to-one.

  • Messages & campaignssubject and body of CRM messages and every step of a personalized campaign.
  • Workflow builderan inserter exposes contact, user, account, and deal custom-field variables for automations.
  • Design Studiotext-layer tokens, layer mergeFields, and visibility fields drive data-driven creative.
  • Render SDKvalues supplied at render time produce personalized, on-brand images at scale.

Custom fields: extending the record

Define your own fields and store them on the contact without a schema change.

When the built-in profile doesn't capture something you care about, you register a custom field. Each definition has a key, a label, a type, and a group, and the value is stored in the contact's `custom_fields` JSON — so adding a field never requires a database migration. Supported types are broad: text, number, boolean, date, datetime, select, multiselect, url, email, phone, textarea, currency, tags, and json.

Custom fields can be registered explicitly through the fields API, and the platform also discovers keys already present in your contacts' custom_fields by sampling them — so fields that arrived via form submissions or imports show up alongside the ones you defined by hand. Either way they're addressed as `custom_fields.<key>` everywhere a field key is expected.

  • Schema-freevalues live in the contact's custom_fields JSON — add a field with no migration.
  • Rich typestext, number, boolean, date, select/multiselect, url, email, phone, currency, tags, and json.
  • Defined & discoveredregister fields explicitly, and the platform surfaces keys already present in your data.
  • Consistent addressingevery custom field is referenced as custom_fields.<key> across the platform.

The field registry, filters & segments

One registry decides what's filterable and sortable — and keeps the AI honest.

A field registry is the single source of truth for what columns are filterable, sortable, and selectable on the contacts list. Static fields map one-to-one to record columns; custom fields are resolved at query time through the JSON operator, so the list adapts to your data model. That means a custom field you add is immediately usable in filters and saved views, not just on the record.

The registry is also injected into the natural-language-to-filter prompt, so when you describe a segment in plain language the AI can only build filters from fields that actually exist — it can't invent a column. The server-side query builder rejects unknown fields for the same reason, so segments stay valid and safe.

  • Single source of truththe registry defines filterable, sortable, and selectable fields for the whole list.
  • Custom fields in filtersa field you add is instantly usable in filters, sorts, and saved views.
  • AI can't hallucinatethe registry is injected into the NL-to-filter prompt so the AI uses real fields only.
  • Validated server-sidethe query builder rejects unknown fields, keeping every segment valid.

System custom fields & organization

Admin-defined fields across entities, organized into folders.

Beyond per-contact custom fields, admins can define system-level custom fields scoped to an entity type, with a display name, a field type, options, a default value, a placeholder, a sort order, and a folder for organization. Folders keep large field sets browsable — group everything onboarding-related together, billing fields in another, and so on — instead of one flat list.

These definitions give your workspace a consistent, governed set of fields that show up in the right places with the right input types, so data is captured uniformly no matter who's entering it.

  • Entity-scopedsystem fields are defined per entity type with their own input type and options.
  • Sensible defaultsdefault values, placeholders, required flags, and sort order are part of the definition.
  • Foldersgroup related fields into folders so large field sets stay browsable.
  • Governedadmin-defined fields keep data capture uniform across your whole team.

Why this keeps everything congruent

Define a fact once; every surface that renders it stays in sync automatically.

The reason custom values and custom fields share an engine is congruence. When your offer name, your audience, or a contact's industry lives in one fact-store, a change updates everywhere a token references it — the funnel headline, the email subject, the campaign step, and the ad creative all move together. There's no find-and-replace across surfaces because there was only ever one value.

That's the payoff of the Context Engine: custom fields decide what facts exist, custom values decide where they appear, and the engine guarantees they always agree. It's the difference between a stack of disconnected tools and one system that speaks with a single voice.

  • Define oncea fact lives in one place — the Context Engine fact-store.
  • Render anywhereany surface that uses the token reads that single value.
  • Change onceupdate the fact and every funnel, email, campaign, and design follows.
  • Always congruentyour whole system speaks with one voice because there's one source of truth.