Documentation menu

Segments

Create dynamic segments to target specific subsets of your email lists based on custom rules and conditions.

Overview

Segments allow you to filter contacts within an email list based on:

  • Contact fields (email, name, status)
  • Custom fields
  • Tags
  • Subscription date
  • Email engagement (opens, clicks)

Segments are dynamic and automatically update as contacts match or unmatch the rules.

List All Segments

Get all segments for your account, optionally filtered by email list.

GET /api/segments?emailListId=list_123

Query Parameters

ParameterTypeRequiredDescription
emailListIdstringNoFilter segments by email list ID

Response

{
  "segments": [
    {
      "id": "segment_123",
      "name": "Engaged Users",
      "description": "Users who opened emails in last 30 days",
      "rules": [...],
      "email_list_id": "list_123",
      "member_count": 450,
      "last_calculated_at": "2024-01-22T10:00:00Z",
      "created_at": "2024-01-15T09:00:00Z",
      "updated_at": "2024-01-22T10:00:00Z"
    }
  ]
}

Get Single Segment

Get details for a specific segment.

GET /api/segments/:id

Response

{
  "id": "segment_123",
  "name": "Engaged Users",
  "description": "Users who opened emails in last 30 days",
  "rules": [
    {
      "field": "email_opened",
      "operator": "within_days",
      "value": "30"
    }
  ],
  "email_list_id": "list_123",
  "member_count": 450,
  "last_calculated_at": "2024-01-22T10:00:00Z",
  "created_at": "2024-01-15T09:00:00Z",
  "updated_at": "2024-01-22T10:00:00Z"
}

Create Segment

Create a new segment with custom rules.

POST /api/segments

Request Body

{
  "name": "VIP Customers",
  "description": "Customers with purchase_count > 5",
  "emailListId": "list_123",
  "rules": [
    {
      "field": "custom_fields.purchase_count",
      "operator": "greater_than",
      "value": "5"
    }
  ]
}

Field Options

FieldTypeDescription
namestringSegment name (required, max 255 chars)
descriptionstringOptional description
emailListIdstringEmail list ID (required)
rulesarrayArray of rule objects (see below)

Rule Structure

Each rule object contains:

{
  "field": "field_name",
  "operator": "equals",
  "value": "comparison_value"
}

Available Fields

  • email - Contact email address
  • first_name - First name
  • last_name - Last name
  • status - Subscription status (subscribed, unsubscribed)
  • tags - Contact tags
  • custom_fields.{field_name} - Any custom field
  • created_at - Contact creation date
  • email_opened - Last email open date
  • email_clicked - Last email click date

Available Operators

OperatorDescriptionExample Value
equalsExact match"[email protected]"
not_equalsNot equal"unsubscribed"
containsContains substring"@gmail.com"
not_containsDoes not contain"test"
greater_thanGreater than (numbers/dates)"5"
less_thanLess than (numbers/dates)"100"
within_daysWithin last N days"30"
has_tagHas specific tag"premium"
not_has_tagDoes not have tag"inactive"

Response

{
  "id": "segment_456",
  "name": "VIP Customers",
  "description": "Customers with purchase_count > 5",
  "rules": [...],
  "email_list_id": "list_123",
  "member_count": 87,
  "last_calculated_at": "2024-01-22T11:00:00Z",
  "created_at": "2024-01-22T11:00:00Z",
  "updated_at": "2024-01-22T11:00:00Z"
}

Update Segment

Update an existing segment's rules or details.

PUT /api/segments/:id

Request Body

{
  "name": "VIP Customers Updated",
  "description": "Premium customers",
  "rules": [
    {
      "field": "custom_fields.purchase_count",
      "operator": "greater_than",
      "value": "10"
    }
  ]
}

Response

{
  "id": "segment_456",
  "name": "VIP Customers Updated",
  "description": "Premium customers",
  "rules": [...],
  "email_list_id": "list_123",
  "member_count": 52,
  "last_calculated_at": "2024-01-22T12:00:00Z",
  "created_at": "2024-01-22T11:00:00Z",
  "updated_at": "2024-01-22T12:00:00Z"
}

Delete Segment

Delete a segment.

DELETE /api/segments/:id

Response

{
  "success": true,
  "message": "Segment deleted successfully"
}

Preview Segment

Preview which contacts would match a set of rules before creating the segment.

POST /api/segments/_preview?limit=50&offset=0

Request Body

{
  "emailListId": "list_123",
  "rules": [
    {
      "field": "status",
      "operator": "equals",
      "value": "subscribed"
    },
    {
      "field": "custom_fields.city",
      "operator": "equals",
      "value": "New York"
    }
  ]
}

Query Parameters

ParameterTypeDefaultDescription
limitinteger50Max contacts to return
offsetinteger0Pagination offset

Response

{
  "total": 234,
  "count": 50,
  "limit": 50,
  "offset": 0,
  "contacts": [
    {
      "id": "contact_123",
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe",
      "status": "subscribed",
      "custom_fields": {
        "city": "New York"
      },
      "created_at": "2024-01-15T10:00:00Z"
    }
  ]
}

Get Segment Contacts

Get all contacts that match a segment's rules.

GET /api/segments/:id/contacts?limit=50&offset=0

Query Parameters

ParameterTypeDefaultDescription
limitinteger50Max contacts to return
offsetinteger0Pagination offset

Response

{
  "total": 450,
  "count": 50,
  "limit": 50,
  "offset": 0,
  "contacts": [...]
}

Code Examples

Create a Segment with Multiple Rules

const apiKey = 'your_api_key';
const baseUrl = 'https://api.postbeagle.com/api';

// Create segment for engaged subscribers in New York
const response = await fetch(`${baseUrl}/segments`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Engaged NYC Subscribers',
    description: 'Active subscribers in New York',
    emailListId: 'list_123',
    rules: [
      {
        field: 'status',
        operator: 'equals',
        value: 'subscribed'
      },
      {
        field: 'custom_fields.city',
        operator: 'equals',
        value: 'New York'
      },
      {
        field: 'email_opened',
        operator: 'within_days',
        value: '30'
      }
    ]
  })
});

const segment = await response.json();
console.log(`Created segment with ${segment.member_count} members`);

Preview Before Creating

import requests

api_key = 'your_api_key'
base_url = 'https://api.postbeagle.com/api'

headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}

# Preview the segment
preview_data = {
    'emailListId': 'list_123',
    'rules': [
        {
            'field': 'custom_fields.purchase_count',
            'operator': 'greater_than',
            'value': '5'
        }
    ]
}

response = requests.post(
    f'{base_url}/segments/_preview',
    headers=headers,
    json=preview_data
)

preview = response.json()
print(f'This segment would have {preview["total"]} members')

# If satisfied, create the segment
if preview['total'] > 0:
    segment_data = {
        **preview_data,
        'name': 'High Value Customers',
        'description': 'Customers with 5+ purchases'
    }
    
    response = requests.post(
        f'{base_url}/segments',
        headers=headers,
        json=segment_data
    )
    
    segment = response.json()
    print(f'Segment created: {segment["id"]}')

Complex Rule Examples

Multiple Conditions (AND logic)

All rules must match:

{
  "rules": [
    {
      "field": "status",
      "operator": "equals",
      "value": "subscribed"
    },
    {
      "field": "tags",
      "operator": "has_tag",
      "value": "premium"
    },
    {
      "field": "custom_fields.lifetime_value",
      "operator": "greater_than",
      "value": "1000"
    }
  ]
}

Date-Based Segment

Subscribers who joined in the last 7 days:

{
  "rules": [
    {
      "field": "created_at",
      "operator": "within_days",
      "value": "7"
    }
  ]
}

Engagement-Based Segment

Subscribers who haven't engaged in 60 days:

{
  "rules": [
    {
      "field": "email_opened",
      "operator": "not_within_days",
      "value": "60"
    }
  ]
}

Best Practices

  1. Preview First: Always preview segments before creating to verify the rules work as expected
  2. Start Simple: Begin with simple rules and add complexity gradually
  3. Monitor Member Count: Track how segment sizes change over time
  4. Update Regularly: Segments recalculate automatically, but review rules periodically
  5. Meaningful Names: Use descriptive names that clearly indicate the segment's purpose
  6. Test with Campaigns: Send test campaigns to segments before full campaigns

Validation Rules

  • Segment names must be unique per email list
  • At least one rule is required
  • Rule fields must be valid contact fields or custom fields
  • Rule operators must match the field type
  • Email list must exist and belong to the user

Error Codes

CodeDescription
400Invalid rules or missing required fields
404Segment or email list not found
409Segment name already exists
429Rate limit exceeded