Contact Lists
Contact lists are named groups of contacts used as audiences for campaigns (newsletter sends, review drip sequences, etc.).
Types
Static lists
Members are added and removed manually (or via API). Membership is stored in the contact_list_member join table.
Dynamic lists
No stored members. Instead, a filters JSON object defines the query — contacts matching the filters are resolved at query time. Example filter:
{ "stage": "customer", "tags": ["saas"] }Dynamic lists always reflect the current state of the contact base without needing manual updates.
Data model
ContactList → contact_list table
| Column | Type | Notes |
|---|---|---|
id | uuid | |
tenantId | uuid FK → tenants | |
name | varchar | Display name |
description | text | |
type | enum | static | dynamic |
filters | jsonb | For dynamic lists: filter criteria |
ContactListMember → contact_list_member table
| Column | Type | Notes |
|---|---|---|
contactListId | uuid FK → contact_list | |
contactId | uuid FK → contact | |
addedAt | timestamptz |
Unique constraint on [contactListId, contactId] — a contact can only appear once per list.
Campaign targeting
A campaign (e.g. ReviewCampaign) can target a contact list via contactListId. When the campaign runs, it resolves the list (static: stored members, dynamic: filter query) and sends to each contact in the list.
ContactList
│
▼
Campaign (ReviewCampaign / Newsletter)
│
▼
Sends to each resolved ContactUse cases
| List type | Example |
|---|---|
| Static | ”Customers from Jan 2026 launch cohort” |
| Dynamic | ”All active customers tagged enterprise” |
| Static | ”Import from old CRM — migration list” |
| Dynamic | ”All contacts in qualified_lead stage” |
Related
- Contacts — contact data model and stages
- Campaigns — campaign audience targeting
- Database schema