Segments API
Segments are dynamic groups of subscribers defined by rules. When you view a segment, it evaluates its rules against your subscriber list in real time and returns the matching subscribers. The Segments API lets you list segments, inspect their rules, and see which subscribers match.
Base URL
https://app.sendbroadcast.com/api/v1
Authentication
All requests require a Bearer token with segment read permissions. See Authentication for details.
The Segment Object
| Field | Type | Description |
|---|---|---|
id |
integer | Unique identifier. |
name |
string | Segment name. |
description |
string | Optional description of the segment’s purpose. |
created_at |
datetime | When the segment was created. |
Example Segment Object (List View)
{
"id": 3,
"name": "Engaged Subscribers",
"description": "Subscribers who opened an email in the last 30 days",
"created_at": "2025-02-01T09:00:00.000Z"
}
How Segment Rules Work
Segments are built from groups of rules. The logic works like this:
- Within a group: All rules must match (AND logic).
- Between groups: Any group can match (OR logic).
This gives you the flexibility to build queries like: “subscribers who are active AND tagged ‘premium’” OR “subscribers who signed up in the last 7 days.”
The Rule Object
Each rule within a group has these fields:
| Field | Type | Description |
|---|---|---|
id |
integer | Unique identifier. |
field |
string | The subscriber field to evaluate. See Available Fields. |
operator |
string | The comparison operator. See Available Operators. |
value |
string | The value to compare against. |
secondary_value |
string | Second value for engagement window operators (minimum/maximum count). |
rule_type |
string | The data type of the rule: text, number, date, boolean, array, or engagement_window. |
value_type |
string | How to interpret the value: string, integer, float, date, boolean, array, or relative_date. |
position |
integer | Display order within the group. |
is_negative |
boolean | If true, negates the rule (NOT logic). |
match_type |
string | all or any – how to combine multiple values. |
case_sensitive |
boolean | Whether text comparisons are case-sensitive. |
Available Fields
| Field | Rule Type | Description |
|---|---|---|
email |
text | Subscriber email address. |
first_name |
text | First name. |
last_name |
text | Last name. |
tags |
text | Subscriber tags (use contains / not_contains to check for a specific tag). |
created_at |
date | When the subscriber was added. |
is_active |
boolean | Whether the subscriber is active. |
sequential_id |
number | The subscriber’s sequential ID within the channel. |
last_email_sent_at |
date | When the most recent email was sent to this subscriber. |
last_email_opened_at |
date | When the subscriber last opened an email. |
last_email_clicked_at |
date | When the subscriber last clicked a link. |
any_email_sent_at |
date | Whether any email was sent within a date range. |
any_email_opened_at |
date | Whether any email was opened within a date range. |
any_email_clicked_at |
date | Whether any link was clicked within a date range. |
total_emails_sent |
number | Total number of emails sent to this subscriber. |
total_emails_opened |
number | Total distinct emails opened. |
total_emails_clicked |
number | Total distinct emails with link clicks. |
has_opened_any_email |
boolean | Whether the subscriber has ever opened an email. |
has_clicked_any_email |
boolean | Whether the subscriber has ever clicked a link. |
emails_opened_within_days |
engagement_window | Count of emails opened within N days. |
emails_clicked_within_days |
engagement_window | Count of emails with clicks within N days. |
Available Operators
Text Operators
| Operator | Description |
|---|---|
equals |
Exact match. |
not_equals |
Does not match. |
contains |
Value appears anywhere in the field. For tags, checks if the subscriber has the tag. |
not_contains |
Value does not appear. For tags, checks the subscriber does not have the tag. |
starts_with |
Field begins with the value. |
ends_with |
Field ends with the value. |
is_empty |
Field is null or blank. |
is_not_empty |
Field has a value. |
tagged_with |
Subscriber clicked a link in a broadcast/sequence step tagged with this value. |
not_tagged_with |
Subscriber has not clicked a link in a broadcast/sequence step tagged with this value. |
Number Operators
| Operator | Description |
|---|---|
equals |
Equal to value. |
not_equals |
Not equal to value. |
greater_than |
Greater than value. |
less_than |
Less than value. |
greater_than_or_equal |
Greater than or equal to value. |
less_than_or_equal |
Less than or equal to value. |
Date Operators
| Operator | Description |
|---|---|
equals |
On this exact date. |
not_equals |
Not on this date. |
before |
Before this date. Supports relative dates. |
after |
After this date. Supports relative dates. |
on_or_before |
On or before this date. Supports relative dates. |
on_or_after |
On or after this date. Supports relative dates. |
is_empty |
Date is not set. |
is_not_empty |
Date is set. |
never |
Event has never occurred. |
within_last_days |
Event occurred within the last N days. Value is the number of days. |
not_within_last_days |
Event did not occur within the last N days. |
Boolean Operators
| Operator | Description |
|---|---|
is_true |
Field is true. |
is_false |
Field is false. |
Engagement Window Operators
Used with emails_opened_within_days and emails_clicked_within_days fields. These require both value (number of days) and secondary_value (count threshold).
| Operator | Description |
|---|---|
at_least_within_days |
At least secondary_value emails opened/clicked within value days. |
fewer_than_within_days |
Fewer than secondary_value emails opened/clicked within value days. |
Relative Dates
The date comparison operators before, after, on_or_before, and on_or_after support relative dates in addition to specific dates. A relative date dynamically calculates as “N days ago from today” each time the segment is evaluated, so the segment stays useful over time without manual updates.
To use a relative date, set value_type to "relative_date" and value to the number of days ago:
{
"field": "created_at",
"operator": "on_or_before",
"value": "80",
"rule_type": "date",
"value_type": "relative_date"
}
This rule matches subscribers who signed up 80 or more days ago. Tomorrow it will mean 80 days from tomorrow, and so on.
Relative dates also work with custom data date fields — set rule_type: "date" and value_type: "relative_date" on any custom_data.* field.
List Segments
Retrieve all segments for your channel.
GET /api/v1/segments.json
Example Request
curl -X GET "https://app.sendbroadcast.com/api/v1/segments.json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Example Response
{
"segments": [
{
"id": 3,
"name": "Engaged Subscribers",
"description": "Opened an email in the last 30 days",
"created_at": "2025-02-01T09:00:00.000Z"
},
{
"id": 4,
"name": "Inactive Subscribers",
"description": "No opens or clicks in 90 days",
"created_at": "2025-02-15T14:00:00.000Z"
}
],
"pagination": {
"total": 2,
"count": 2,
"from": 1,
"to": 2,
"current": 1,
"total_pages": 1
}
}
Get a Segment
Retrieve a segment along with its matching subscribers. The segment’s rules are evaluated in real time, so the subscriber list reflects the current state of your data.
GET /api/v1/segments/:id.json
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page |
integer | Page number for subscriber pagination (default: 1). |
Example Request
curl -X GET "https://app.sendbroadcast.com/api/v1/segments/3.json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Example Response
{
"segment": {
"id": 3,
"name": "Engaged Subscribers",
"description": "Opened an email in the last 30 days",
"created_at": "2025-02-01T09:00:00.000Z"
},
"subscribers": [
{
"id": 42,
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"ip_address": null,
"is_active": true,
"source": "api_subscription",
"subscribed_at": "2025-01-15T10:30:00.000Z",
"unsubscribed_at": null,
"created_at": "2025-01-15T10:30:00.000Z",
"custom_data": {},
"tags": ["newsletter", "premium"]
}
],
"pagination": {
"total": 850,
"count": 250,
"from": 1,
"to": 250,
"current": 1,
"total_pages": 4
}
}
Each page returns up to 250 subscribers.
Error Responses
| Status Code | Description |
|---|---|
401 Unauthorized |
Missing or invalid API token, or token lacks segment permissions. |
404 Not Found |
Segment with the given ID does not exist in your channel. |
Building Segments via API
Segments can also be created and updated through the API using the segment write permission. Rules are passed as nested attributes within groups.
Create a Segment
POST /api/v1/segments.json
curl -X POST "https://app.sendbroadcast.com/api/v1/segments.json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"segment": {
"name": "Active Premium Users",
"description": "Active subscribers with the premium tag",
"segment_groups_attributes": [
{
"match_type": "all",
"segment_rules_attributes": [
{
"field": "is_active",
"operator": "is_true",
"rule_type": "boolean",
"value_type": "boolean"
},
{
"field": "tags",
"operator": "contains",
"value": "premium",
"rule_type": "text",
"value_type": "string"
}
]
}
]
}
}'
Response
Status: 201 Created
{
"id": 5,
"name": "Active Premium Users",
"description": "Active subscribers with the premium tag",
"subscribers_count": 0,
"segment_groups": [
{
"id": 10,
"match_type": "all",
"position": null,
"segment_rules": [
{
"id": 20,
"field": "is_active",
"operator": "is_true",
"value": null,
"secondary_value": null,
"rule_type": "boolean",
"value_type": "boolean",
"position": null,
"is_negative": false,
"match_type": "all",
"case_sensitive": false
},
{
"id": 21,
"field": "tags",
"operator": "contains",
"value": "premium",
"secondary_value": null,
"rule_type": "text",
"value_type": "string",
"position": null,
"is_negative": false,
"match_type": "all",
"case_sensitive": false
}
]
}
],
"created_at": "2025-03-15T10:00:00.000Z",
"updated_at": "2025-03-15T10:00:00.000Z"
}
Update a Segment
PATCH /api/v1/segments/:id.json
Use _destroy: true on a group or rule to remove it.
Delete a Segment
DELETE /api/v1/segments/:id.json
curl -X DELETE "https://app.sendbroadcast.com/api/v1/segments/5.json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Response:
{
"message": "Segment deleted successfully"
}