Skip to content

Segments

Organize contacts into segments for targeted broadcasts. Segments can be manual (explicitly add/remove contacts) or dynamic (auto-populated based on filter rules).

POST
/segments

Create a new segment. Omit rules for a manual segment, or provide rules for a dynamic segment that auto-populates based on conditions.

json
{
  "name": "Pro Users",
  "rules": {
    "operator": "and",
    "conditions": [
      {
        "field": "properties.plan",
        "comparator": "equals",
        "value": "pro"
      },
      {
        "field": "unsubscribed",
        "comparator": "equals",
        "value": "false"
      }
    ]
  }
}
GET
/segments

List all segments with contact counts.

json
{
  "segments": [
    {
      "id": 31,
      "publicId": "seg_abc123def456ghi789",
      "name": "Pro Users",
      "rules": { "operator": "and", "conditions": [ ... ] },
      "contactCount": 342,
      "createdAt": "2026-03-23T10:00:00.000Z",
      "updatedAt": "2026-03-23T10:00:00.000Z"
    },
    {
      "id": 32,
      "publicId": "seg_jkl012mno345pqr678",
      "name": "Beta Testers",
      "rules": null,
      "contactCount": 58,
      "createdAt": "2026-03-20T10:00:00.000Z",
      "updatedAt": "2026-03-20T10:00:00.000Z"
    }
  ]
}
GET
/segments/:id

Retrieve a single segment with its rules (null for a manual segment), its contact count, and the first 100 members inline. Page through larger segments with GET /segments/:id/members?page=1&per_page=100.

json
{
  "segment": {
    "id": 31,
    "publicId": "seg_abc123def456ghi789",
    "name": "Pro Users",
    "rules": {
      "operator": "and",
      "conditions": [
        { "field": "properties.plan", "comparator": "equals", "value": "pro" }
      ]
    },
    "contactCount": 342,
    "contacts": [
      { "id": 9120, "publicId": "con_abc123def456ghi789", "email": "alice@example.com", ... }
    ],
    "createdAt": "2026-03-23T10:00:00.000Z",
    "updatedAt": "2026-03-23T12:00:00.000Z"
  }
}
PATCH
/segments/:id

Update a segment. name is required on every update; include rules to change them, or set rules to null to convert a dynamic segment to manual.

json
{
  "name": "Active Pro Users",
  "rules": {
    "operator": "and",
    "conditions": [
      {
        "field": "properties.plan",
        "comparator": "equals",
        "value": "pro"
      },
      {
        "field": "email",
        "comparator": "contains",
        "value": "@company.com"
      }
    ]
  }
}
POST
/segments/preview

Count the contacts that match a set of rules without creating or modifying a segment. Returns the count only. Limited to 10 requests per minute.

json
{
  "rules": {
    "operator": "and",
    "conditions": [
      {
        "field": "properties.plan",
        "comparator": "equals",
        "value": "pro"
      }
    ]
  }
}
POST
/segments/:id/contacts

Add contacts to a manual segment. Provide an array of contact public ids (con_…), up to 1,000 per request. The response counts the contacts actually added.

json
{
  "contact_ids": [
    "con_abc123def456ghi789",
    "con_jkl012mno345pqr678"
  ]
}
DELETE
/segments/:id/contacts/:contactId

Remove a single contact from a manual segment.

json
{
  "success": true
}
DELETE
/segments/:id

Delete a segment. Contacts in the segment are not deleted.

json
{
  "success": true
}

Dynamic Segment Rules

Dynamic segments auto-populate based on filter rules. Rules consist of an operator (and or or) and an array of conditions. Each condition has a field, comparator, and value:

json
{
  "rules": {
    "operator": "and",
    "conditions": [
      { "field": "properties.plan", "comparator": "equals", "value": "pro" },
      { "field": "email", "comparator": "contains", "value": "@company.com" }
    ]
  }
}

Comparators

ComparatorDescription
equalsExact match on the field value
not_equalsField value does not match
containsField value contains the substring
starts_withField value starts with the string
ends_withField value ends with the string
greater_thanNumeric comparison (also for event counts)
less_thanNumeric comparison (also for event counts)
greater_than_or_equalNumeric comparison (also for event counts)
less_than_or_equalNumeric comparison (also for event counts)
beforeDate is before the value (YYYY-MM-DD)
afterDate is after the value (YYYY-MM-DD)
in_last_daysDate falls within the last N days (whole number)
is_setField has a value (no value needed)
is_not_setField has no value (no value needed)

Available Fields

Conditions can target built-in contact fields or any custom contact property. A rule set holds 1–50 conditions:

FieldDescription
emailContact email address
firstNameContact first name
lastNameContact last name
unsubscribedSubscription status (true/false)
engagementSegmentEngagement tier: active, at_risk or dormant
createdAtWhen the contact was created (date comparators)
lastEngagedAtLast open or click (date comparators)
emailsOpenedOpens in a rolling window — set windowDays (1–365, default 30); value is the count
emailsClickedClicks in a rolling window — set windowDays (1–365, default 30); value is the count
properties.<name>Any custom contact property, prefixed with properties. (e.g. properties.plan). A bare property name is not a valid field.

Related