Skip to main content
The CRM module lets you define custom entity types, fields, pipelines, and stages — then store structured data entries linked to any record in the system. The most common use case is storing custom data per customer, but entries can reference any record type (orders, leads, etc.).

Architecture

All CRM data lives in the crm_entries Elasticsearch index. Each entry is linked to an external record via two fields:
FieldTypeDescription
reference_typekeywordThe type of record (e.g. customer, order, lead)
reference_idkeywordThe ID of the referenced record
This generic linking means you can build any kind of structured data on top of the CRM module without being locked to customers.

Concepts

Entities

An entity defines a type of CRM record (e.g. “Deals”, “Contacts”, “Tracker”). Each entity has:
  • A name and slug (machine-readable identifier)
  • Fields that define the data structure
  • Pipelines with stages for workflow tracking

Fields

Fields define what data can be stored on entries. Each field has:
PropertyDescription
labelHuman-readable label
keyMachine-readable key (used in API and templates)
typetext, number, date, boolean, or select

Pipelines & Stages

Pipelines represent workflows. Each pipeline contains ordered stages with optional colors and semantic statuses (e.g. won, lost, active). Entries move through stages as they progress.

Customer CRM Data

The most common pattern is linking CRM entries to customers. When a customer visits a page, the template engine automatically resolves their customer_id from Elasticsearch (creating the customer record if needed).

Example: Weight Loss Tracker

  1. Create a CRM entity called “Weight Tracker” with fields like current_weight, goal_weight, last_checkin
  2. Create a pipeline “Progress” with stages “Starting”, “In Progress”, “Goal Reached”
  3. Store data via backend scripts or the template engine:
// `slug` = CRM entity machine name from entity settings (e.g. pattern-tracker), required on every call
setCrmField({ slug: 'pattern-tracker', fieldKey: 'current_weight', value: 185 });
setCrmField({ slug: 'pattern-tracker', fieldKey: 'goal_weight', value: 165 });
setCrmField({ slug: 'pattern-tracker', fieldKey: 'last_checkin', value: '2026-03-15' });
slug identifies the CRM entity (board/type). referenceType / referenceId default to the current customer when omitted. For another record: setCrmField({ slug: 'pattern-tracker', referenceType: 'order', referenceId: '12345', fieldKey: 'status', value: 'shipped' }). See Data Functions.
  1. Read it back on any page:
var weight = getCrmField({ slug: 'pattern-tracker', fieldKey: 'current_weight' });
var goal = getCrmField({ slug: 'pattern-tracker', fieldKey: 'goal_weight' });
if (weight && goal && Number(weight) <= Number(goal)) {
  setVariable('show_congrats', true);
}

Viewing Customer CRM Data

Customer CRM entries are visible in the Customer Details page under the CRM tab. This shows all CRM entries linked to that customer across all entity types.

Template Engine Functions

The CRM adapter exposes three functions in the template engine:
FunctionDescription
getCrmEntries({ slug, ... })Fetch entries for one entity slug + reference
getCrmField({ slug, fieldKey, ... })Get one field (slug + fieldKey required)
setCrmField({ slug, fieldKey, value, ... })Set one field (slug, fieldKey, value required)
slug is always required (the entity’s slug from CRM settings). Reference defaults: customer + session customer id.
setCrmField({ slug: 'pattern-tracker', fieldKey: 'score', value: 85 });
var score = getCrmField({ slug: 'pattern-tracker', fieldKey: 'score' });
See Data Functions for full parameter details and examples.

API Endpoints

CRM entries are managed through the standard CRM API:
GET    /brands/{brand}/crm/entities/{entity}/entries
POST   /brands/{brand}/crm/entities/{entity}/entries
GET    /brands/{brand}/crm/entries/{entry}
PUT    /brands/{brand}/crm/entries/{entry}
DELETE /brands/{brand}/crm/entries/{entry}
Filter by reference:
GET /brands/{brand}/crm/entities/{entity}/entries?reference_type=customer&reference_id={customer_id}