Segments API

The Segments API provides full CRUD (Create, Read, Update, Delete) operations for managing subscriber segments. Segments allow you to group subscribers based on rules and conditions, which can then be used to target specific audiences for broadcasts.

Required Permissions

All endpoints require authentication via an API token with appropriate permissions:

  • Read Permission: Required for GET endpoints (list, show)
  • Write Permission: Required for POST, PATCH, DELETE endpoints

Segment Object

The segment object contains the following fields:

Field Type Description
`id` integer Unique identifier of the segment
`name` string Name of the segment (required)
`description` string Description of the segment
`subscribers_count` integer Cached count of subscribers matching the segment
`segment_groups` array Array of rule groups (combined with OR logic)
`created_at` datetime When the segment was created
`updated_at` datetime When the segment was last updated

Segment Group Object

Each segment contains one or more groups. Groups are combined with OR logic (a subscriber matches if they match ANY group).

Field Type Description
`id` integer Unique identifier of the group
`match_type` string `all` (AND logic) or `any` (OR logic) for rules within this group
`position` integer Order of the group
`segment_rules` array Array of rules in this group

Segment Rule Object

Rules define the conditions for matching subscribers.

Field Type Description
`id` integer Unique identifier of the rule
`field` string The subscriber field to check (see allowed fields below)
`operator` string The comparison operator (see operators below)
`value` string The value to compare against
`secondary_value` string Secondary value for engagement window rules
`rule_type` string `text`, `number`, `date`, `boolean`, or `engagement_window`
`value_type` string `string`, `integer`, `float`, `date`, `boolean`, or `array`
`is_negative` boolean If true, negates the rule condition
`case_sensitive` boolean If true, text comparisons are case-sensitive

Allowed Fields

  • email - Subscriber email address
  • first_name - Subscriber first name
  • last_name - Subscriber last name
  • tags - Subscriber tags
  • created_at - When the subscriber was created
  • is_active - Whether the subscriber is active
  • sequential_id - The subscriber’s sequential ID
  • last_email_sent_at - When the last email was sent
  • last_email_opened_at - When the last email was opened
  • last_email_clicked_at - When the last email was clicked
  • any_email_sent_at - When any email was sent
  • any_email_opened_at - When any email was opened
  • any_email_clicked_at - When any email was clicked
  • total_emails_sent - Total emails sent to subscriber
  • total_emails_opened - Total emails opened by subscriber
  • total_emails_clicked - Total emails clicked by subscriber
  • has_opened_any_email - Whether subscriber has opened any email
  • has_clicked_any_email - Whether subscriber has clicked any email
  • emails_opened_within_days - Emails opened within N days
  • emails_clicked_within_days - Emails clicked within N days

Operators by Rule Type

Text rules: equals, not_equals, contains, not_contains, starts_with, ends_with, is_empty, is_not_empty

Number rules: equals, not_equals, greater_than, less_than, greater_than_or_equal, less_than_or_equal

Date rules: equals, not_equals, before, after, on_or_before, on_or_after, is_empty, is_not_empty, never, within_last_days, not_within_last_days

Boolean rules: is_true, is_false

Engagement window rules: at_least_within_days, fewer_than_within_days

List Segments

GET /api/v1/segments

Returns a paginated list of segments that belong to a channel.

Query Parameters

  • page: Page number (default: 1)

Request

curl -X GET \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  http://your-domain.com/api/v1/segments.json

Response

{
  "segments": [
    {
      "id": 1,
      "name": "Active Subscribers",
      "description": "Subscribers who have opened at least one email in the last 30 days.",
      "created_at": "2024-06-01T12:34:56Z"
    }
  ],
  "pagination": {
    "total": 1,
    "count": 1,
    "from": 1,
    "to": 1,
    "current": 1,
    "total_pages": 1
  }
}

Get Segment

GET /api/v1/segments/:id

Returns details of a specific segment along with a paginated list of matching subscribers.

Query Parameters

  • page: Page number for subscribers list (default: 1)

Request

curl -X GET \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  http://your-domain.com/api/v1/segments/1.json

Response

{
  "segment": {
    "id": 1,
    "name": "Active Subscribers",
    "description": "Subscribers who have opened at least one email in the last 30 days.",
    "created_at": "2024-06-01T12:34:56Z"
  },
  "subscribers": [
    {
      "id": "123",
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe",
      "ip_address": "192.168.1.1",
      "is_active": true,
      "source": "web_form",
      "subscribed_at": "2024-03-20T10:00:00Z",
      "unsubscribed_at": null,
      "created_at": "2024-03-20T10:00:00Z",
      "tags": ["newsletter", "product-updates"]
    }
  ],
  "pagination": {
    "total": 150,
    "count": 250,
    "from": 1,
    "to": 150,
    "current": 1,
    "total_pages": 1
  }
}

Create Segment

POST /api/v1/segments

Create a new segment with rules.

Parameters

  • name (required): Name of the segment
  • description (optional): Description of the segment
  • segment_groups_attributes (required): Array of rule groups, each containing:
    • match_type: all or any
    • segment_rules_attributes: Array of rules

Request

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "Gmail Users",
      "description": "Subscribers with Gmail addresses",
      "segment_groups_attributes": [
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "email",
              "operator": "contains",
              "value": "gmail.com",
              "rule_type": "text",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments

Response

{
  "id": 5,
  "name": "Gmail Users",
  "description": "Subscribers with Gmail addresses",
  "subscribers_count": 0,
  "segment_groups": [
    {
      "id": 10,
      "match_type": "all",
      "position": 1,
      "segment_rules": [
        {
          "id": 20,
          "field": "email",
          "operator": "contains",
          "value": "gmail.com",
          "secondary_value": null,
          "rule_type": "text",
          "value_type": "string",
          "position": 1,
          "is_negative": false,
          "match_type": "all",
          "case_sensitive": false
        }
      ]
    }
  ],
  "created_at": "2024-06-15T10:00:00Z",
  "updated_at": "2024-06-15T10:00:00Z"
}

Complex Segment Example

Create a segment with multiple groups and rules:

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "Engaged Premium Users",
      "description": "Active subscribers who opened emails recently OR have VIP tag",
      "segment_groups_attributes": [
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "is_active",
              "operator": "is_true",
              "value": "true",
              "rule_type": "boolean",
              "value_type": "boolean"
            },
            {
              "field": "last_email_opened_at",
              "operator": "within_last_days",
              "value": "30",
              "rule_type": "date",
              "value_type": "string"
            }
          ]
        },
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "tags",
              "operator": "contains",
              "value": "vip",
              "rule_type": "text",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments

This creates a segment matching subscribers who: - (Are active AND opened an email in the last 30 days) OR - (Have the “vip” tag)

Update Segment

PATCH /api/v1/segments/:id

Update an existing segment.

Parameters

All parameters are optional. Only include the fields you want to update:

  • name: Name of the segment
  • description: Description of the segment
  • segment_groups_attributes: Array of rule groups (include id for existing groups, or omit to create new)
    • Include _destroy: true to delete a group

Request - Simple Update

curl -X PATCH \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "Updated Segment Name",
      "description": "Updated description"
    }
  }' \
  http://your-domain.com/api/v1/segments/5

Request - Update Rules

curl -X PATCH \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "segment_groups_attributes": [
        {
          "id": 10,
          "match_type": "any",
          "segment_rules_attributes": [
            {
              "field": "email",
              "operator": "contains",
              "value": "company.com",
              "rule_type": "text",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments/5

Response

{
  "id": 5,
  "name": "Updated Segment Name",
  "description": "Updated description",
  "subscribers_count": 0,
  "segment_groups": [
    {
      "id": 10,
      "match_type": "any",
      "position": 1,
      "segment_rules": [
        {
          "id": 21,
          "field": "email",
          "operator": "contains",
          "value": "company.com",
          "secondary_value": null,
          "rule_type": "text",
          "value_type": "string",
          "position": 1,
          "is_negative": false,
          "match_type": "all",
          "case_sensitive": false
        }
      ]
    }
  ],
  "created_at": "2024-06-15T10:00:00Z",
  "updated_at": "2024-06-15T11:00:00Z"
}

Delete Segment

DELETE /api/v1/segments/:id

Delete a segment.

Request

curl -X DELETE \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  http://your-domain.com/api/v1/segments/5

Response

{
  "message": "Segment deleted successfully"
}

Error Responses

401 Unauthorized

{
  "error": "Unauthorized"
}

This error occurs when: - No authorization header is provided - The token is invalid or expired - The token doesn’t have the required permissions

404 Not Found

{
  "error": "Segment not found"
}

This error occurs when: - The segment ID doesn’t exist - The segment belongs to a different broadcast channel

422 Unprocessable Entity

{
  "error": "Name can't be blank, must have at least one rule"
}

This error occurs when: - Required fields are missing - The segment has no rules - Validation fails for any other reason

Usage Examples

Create a Segment for Recent Subscribers

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "New Subscribers (Last 7 Days)",
      "description": "Subscribers who joined in the last week",
      "segment_groups_attributes": [
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "created_at",
              "operator": "within_last_days",
              "value": "7",
              "rule_type": "date",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments

Create a Segment for Inactive Subscribers

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "Inactive Subscribers",
      "description": "Subscribers who have not opened any email in 90 days",
      "segment_groups_attributes": [
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "last_email_opened_at",
              "operator": "not_within_last_days",
              "value": "90",
              "rule_type": "date",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments

Create a Segment for Highly Engaged Subscribers

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "segment": {
      "name": "Highly Engaged",
      "description": "Subscribers who opened at least 3 emails in the last 30 days",
      "segment_groups_attributes": [
        {
          "match_type": "all",
          "segment_rules_attributes": [
            {
              "field": "emails_opened_within_days",
              "operator": "at_least_within_days",
              "value": "30",
              "secondary_value": "3",
              "rule_type": "engagement_window",
              "value_type": "string"
            }
          ]
        }
      ]
    }
  }' \
  http://your-domain.com/api/v1/segments