Skip to content

Segmentation Rules

This document describes how to create and use segmentation rules in the Celebration Marketing Buyer Intent Platform.

Segmentation rules allow you to dynamically filter leads based on various criteria including geographic location, intent data, firmographic information, and custom conditions. Rules are defined using a JSON-based DSL (Domain-Specific Language) that supports nested logic operators.

A segmentation rule is a JSON object that can contain:

  • Conditions — Individual field comparisons
  • Logic OperatorsAND, OR, NOT for combining conditions
  • Nested Rules — Rules within rules for complex logic
{ "logic": "AND", "conditions": [{ "field": "state", "operator": "EQ", "value": "CA" }] }

Matches exact values.

{ "field": "state", "operator": "EQ", "value": "CA" }

Supported fields: state, status, companySize, industry, etc.

Matches if the field value is in the provided array.

{ "field": "state", "operator": "IN", "values": ["CA", "NY", "TX"] }

Supported fields: Any field with discrete values.

Numeric or date comparison.

{ "field": "intentScore", "operator": "GTE", "value": 75 }

Supported fields: intentScore, qualityScore, createdAt, etc.

Numeric or date comparison.

{ "field": "intentScore", "operator": "LTE", "value": 50 }

Supported fields: intentScore, qualityScore, createdAt, etc.

Checks if an array field contains any of the specified values.

{ "field": "intentTopics", "operator": "CONTAINS_ANY", "values": ["Cloud Migration", "Digital Transformation"] }

Supported fields: intentTopics (JSONB array)

Exact match for intent topics (case-sensitive).

{ "field": "intentTopics", "operator": "EXACT_MATCH", "value": "Cloud Migration" }

Supported fields: intentTopics

Matches leads within a specified radius of a geographic point.

{ "field": "location", "operator": "WITHIN_RADIUS", "center": { "lat": 37.7749, "lng": -122.4194 }, "radius_miles": 50 }

Supported fields: location (PostGIS GEOGRAPHY(POINT))

Note: Requires the PostGIS extension enabled in PostgreSQL.

All conditions must be true.

{ "logic": "AND", "conditions": [{ "field": "state", "operator": "EQ", "value": "CA" }, { "field": "intentScore", "operator": "GTE", "value": 75 }] }

At least one condition must be true.

{ "logic": "OR", "conditions": [{ "field": "state", "operator": "EQ", "value": "CA" }, { "field": "state", "operator": "EQ", "value": "NY" }] }

Negates the result of conditions or nested rules.

{ "logic": "NOT", "conditions": [{ "field": "isSuppressed", "operator": "EQ", "value": true }] }

You can nest rules to create complex logic:

{
"logic": "AND",
"rules": [
{ "logic": "OR", "conditions": [{ "field": "state", "operator": "EQ", "value": "CA" }, { "field": "state", "operator": "EQ", "value": "NY" }] },
{ "logic": "AND", "conditions": [{ "field": "intentScore", "operator": "GTE", "value": 75 }, { "field": "intentTopics", "operator": "CONTAINS_ANY", "values": ["Cloud Migration", "Digital Transformation"] }] }
]
}

This rule matches leads that are:

  • In California OR New York
  • AND have an intent score ≥ 75
  • AND have intent topics containing “Cloud Migration” OR “Digital Transformation”

Contact fields: email, phone, firstName, lastName, jobTitle, department

Company fields: companyName, domain, companySize, industry, naicsCode, revenueRange

Geographic fields: address, city, state, zipCode, county, country, location (PostGIS point)

Intent fields: intentTopics (JSONB array), intentScore, intentStrength, intentRecency

Lead management fields: status, qualityScore, isSuppressed, createdAt, updatedAt, lastEngagedAt, engagementCount

{ "logic": "AND", "conditions": [{ "field": "state", "operator": "EQ", "value": "CA" }, { "field": "intentScore", "operator": "GTE", "value": 80 }, { "field": "status", "operator": "EQ", "value": "new" }] }
{ "logic": "AND", "conditions": [{ "field": "companySize", "operator": "IN", "values": ["1000-5000", "5000+"] }, { "field": "state", "operator": "IN", "values": ["CA", "NY", "TX", "WA"] }, { "field": "industry", "operator": "IN", "values": ["Technology", "Software", "SaaS"] }] }
{ "logic": "AND", "conditions": [{ "field": "intentTopics", "operator": "CONTAINS_ANY", "values": ["Cloud Migration", "AWS Migration", "Azure Migration"] }, { "field": "intentScore", "operator": "GTE", "value": 70 }] }
{ "logic": "AND", "conditions": [{ "field": "location", "operator": "WITHIN_RADIUS", "center": { "lat": 37.7749, "lng": -122.4194 }, "radius_miles": 50 }, { "field": "status", "operator": "EQ", "value": "new" }] }

Complex: high-value leads excluding suppressed

Section titled “Complex: high-value leads excluding suppressed”
{
"logic": "AND",
"rules": [
{ "logic": "OR", "conditions": [{ "field": "intentScore", "operator": "GTE", "value": 85 }, { "field": "qualityScore", "operator": "GTE", "value": 90 }] },
{ "logic": "NOT", "conditions": [{ "field": "isSuppressed", "operator": "EQ", "value": true }] },
{ "field": "companySize", "operator": "IN", "values": ["500-1000", "1000-5000", "5000+"] }
]
}
  • Start simple — Begin with basic conditions and add complexity as needed.

  • Use indexed fields — Prefer fields with database indexes (state, status, intentScore, createdAt) for better performance.

  • Combine conditions efficiently — Use AND for narrowing down, OR for expanding.

  • Test incrementally — Test each condition separately before combining.

  • Monitor segment size — Large segments may impact performance. Consider adding date filters.

  • Use date ranges — Filter by createdAt to limit segment size:

    { "field": "createdAt", "operator": "GTE", "value": "2024-01-01T00:00:00Z" }
  • Avoid overly complex rules — Deeply nested rules can be hard to maintain. Consider splitting into multiple segments.

Segments are automatically recalculated when:

  • A new lead is imported
  • A lead’s data is updated
  • The segment rules are modified
  • Manual recalculation is triggered

Manual recalculation: Use the “Recalculate” button in the segment detail page.

  • Index usage — Rules using indexed fields (state, status, intentScore) perform better
  • JSONB queriesintentTopics queries use GIN indexes for fast array searches
  • Geographic queriesWITHIN_RADIUS requires PostGIS and spatial indexes
  • Segment size — Large segments (>10,000 leads) may take longer to calculate
  • Check field names match exactly (case-sensitive)
  • Verify operator syntax is correct
  • Test individual conditions separately
  • Check data types match (string vs. number)
  • Add date range filters to limit segment size
  • Use indexed fields in primary conditions
  • Avoid deeply nested rules (>3 levels)
  • Consider splitting large segments
  • Verify PostGIS extension is enabled
  • Check that location field has valid coordinates
  • Ensure center coordinates are valid (lat: -90 to 90, lng: -180 to 180)
  • Verify radius_miles is a positive number

Segments can be created and managed via the UI or programmatically. See the Integration Guide for details.