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
| Parameter | Type | Required | Description |
|---|---|---|---|
emailListId | string | No | Filter 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
| Field | Type | Description |
|---|---|---|
name | string | Segment name (required, max 255 chars) |
description | string | Optional description |
emailListId | string | Email list ID (required) |
rules | array | Array of rule objects (see below) |
Rule Structure
Each rule object contains:
{
"field": "field_name",
"operator": "equals",
"value": "comparison_value"
}
Available Fields
email- Contact email addressfirst_name- First namelast_name- Last namestatus- Subscription status (subscribed, unsubscribed)tags- Contact tagscustom_fields.{field_name}- Any custom fieldcreated_at- Contact creation dateemail_opened- Last email open dateemail_clicked- Last email click date
Available Operators
| Operator | Description | Example Value |
|---|---|---|
equals | Exact match | "[email protected]" |
not_equals | Not equal | "unsubscribed" |
contains | Contains substring | "@gmail.com" |
not_contains | Does not contain | "test" |
greater_than | Greater than (numbers/dates) | "5" |
less_than | Less than (numbers/dates) | "100" |
within_days | Within last N days | "30" |
has_tag | Has specific tag | "premium" |
not_has_tag | Does 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
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max contacts to return |
offset | integer | 0 | Pagination 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
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max contacts to return |
offset | integer | 0 | Pagination 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
- Preview First: Always preview segments before creating to verify the rules work as expected
- Start Simple: Begin with simple rules and add complexity gradually
- Monitor Member Count: Track how segment sizes change over time
- Update Regularly: Segments recalculate automatically, but review rules periodically
- Meaningful Names: Use descriptive names that clearly indicate the segment's purpose
- 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
| Code | Description |
|---|---|
| 400 | Invalid rules or missing required fields |
| 404 | Segment or email list not found |
| 409 | Segment name already exists |
| 429 | Rate limit exceeded |
Related Endpoints
- Email Lists - Manage email lists
- Contacts - Manage contacts
- Campaigns - Send campaigns to segments