Skip to main content

Segments API

Create and manage saved filter configurations that can be reused across all analytics endpoints.


Overview

Segments allow you to:

  • Save complex filter combinations for reuse
  • Apply consistent filters across reports
  • Share segments with your team
  • Use system segments for common patterns

Base path: /segments


Segment Structure

A segment consists of a name, display name, and filter conditions:

{
"id": "seg_abc123",
"site_id": "my-site",
"name": "paid-spain",
"display_name": "Paid Traffic Spain",
"description": "CPC traffic from Spain",
"filters": {
"conditions": [
{"field": "utm_medium", "operator": "eq", "value": "cpc"},
{"field": "country", "operator": "eq", "value": "ES"}
]
},
"color": "#F59E0B",
"is_system": false,
"created_by": 123,
"created_at": "2025-01-05T10:00:00Z",
"updated_at": "2025-01-05T10:00:00Z"
}

Filter Fields

Available fields for segment conditions:

FieldDescriptionExample Values
utm_sourceTraffic sourcegoogle, facebook
utm_mediumTraffic mediumcpc, organic, email
utm_campaignCampaign namespring_sale
utm_termSearch termrunning shoes
utm_contentAd contentbanner_a
countryCountry codeES, US, FR
device_typeDevice categorydesktop, mobile, tablet
browserBrowser nameChrome, Safari
osOperating systemWindows, iOS
pathURL path/products/, /blog/
content_groupingContent groupblog, products
referrerReferrer URLfacebook.com
referrer_domainReferrer domainfacebook.com
channelChannel groupOrganic Search, Direct

Filter Operators

OperatorDescriptionExample
eqEquals{"field": "country", "operator": "eq", "value": "ES"}
neqNot equals{"field": "country", "operator": "neq", "value": "US"}
containsContains substring{"field": "path", "operator": "contains", "value": "/blog/"}
not_containsDoes not contain{"field": "path", "operator": "not_contains", "value": "/admin/"}
starts_withStarts with{"field": "path", "operator": "starts_with", "value": "/products/"}
ends_withEnds with{"field": "path", "operator": "ends_with", "value": ".html"}
inIn list{"field": "country", "operator": "in", "value": ["ES", "FR", "DE"]}
not_inNot in list{"field": "device_type", "operator": "not_in", "value": ["tablet"]}
regexRegex match{"field": "path", "operator": "regex", "value": "^/products/[0-9]+"}
not_regexRegex not match{"field": "utm_source", "operator": "not_regex", "value": "^spam"}

Filter Logic

Simple Mode (AND)

All conditions combined with AND:

{
"filters": {
"conditions": [
{"field": "country", "operator": "eq", "value": "ES"},
{"field": "device_type", "operator": "eq", "value": "mobile"}
]
}
}

Result: country = 'ES' AND device_type = 'mobile'

Advanced Mode (OR between groups)

Multiple groups combined with OR, conditions within each group with AND:

{
"filters": {
"groups": [
{
"conditions": [
{"field": "country", "operator": "eq", "value": "ES"},
{"field": "device_type", "operator": "eq", "value": "mobile"}
]
},
{
"conditions": [
{"field": "country", "operator": "eq", "value": "FR"},
{"field": "device_type", "operator": "eq", "value": "desktop"}
]
}
]
}
}

Result: (country = 'ES' AND device_type = 'mobile') OR (country = 'FR' AND device_type = 'desktop')

Exclusion Mode (NOT)

Use not_groups to exclude matching records:

{
"filters": {
"conditions": [
{"field": "country", "operator": "eq", "value": "ES"}
],
"not_groups": [
{
"conditions": [
{"field": "utm_source", "operator": "eq", "value": "spam"}
]
}
]
}
}

Result: country = 'ES' AND NOT (utm_source = 'spam')


List Segments

GET /segments?site_id={site_id}

Get all segments for an account.

Query Parameters:

ParameterTypeDefaultDescription
site_idstringrequiredSite ID
include_systembooleantrueInclude system segments

Response:

{
"success": true,
"data": [
{
"id": "seg_system_organic",
"name": "organic-search",
"display_name": "Organic Search",
"description": "Visitors from organic search results",
"color": "#10B981",
"is_system": true,
"filter_count": 1
},
{
"id": "seg_abc123",
"name": "paid-spain",
"display_name": "Paid Traffic Spain",
"description": "CPC traffic from Spain",
"color": "#F59E0B",
"is_system": false,
"filter_count": 2
}
]
}

Get Segment

GET /segments/{segment_id}?site_id={site_id}

Get a segment by ID or name.

Path Parameters:

ParameterDescription
segment_idSegment ID (seg_xxx) or name slug (paid-spain)

Response:

{
"success": true,
"data": {
"id": "seg_abc123",
"site_id": "my-site",
"name": "paid-spain",
"display_name": "Paid Traffic Spain",
"description": "CPC traffic from Spain",
"filters": {
"conditions": [
{"field": "utm_medium", "operator": "eq", "value": "cpc"},
{"field": "country", "operator": "eq", "value": "ES"}
]
},
"color": "#F59E0B",
"is_system": false,
"created_by": 123,
"created_at": "2025-01-05T10:00:00Z",
"updated_at": "2025-01-05T10:00:00Z"
}
}

Create Segment

POST /segments?site_id={site_id}

Create a new segment.

Required scope: editor or higher

Request Body:

{
"name": "eu-mobile-paid",
"display_name": "EU Mobile Paid Traffic",
"description": "Paid traffic from EU countries on mobile devices",
"filters": {
"conditions": [
{"field": "utm_medium", "operator": "eq", "value": "cpc"},
{"field": "device_type", "operator": "eq", "value": "mobile"},
{"field": "country", "operator": "in", "value": ["ES", "FR", "DE", "IT", "PT"]}
]
},
"color": "#8B5CF6"
}
FieldTypeRequiredDescription
namestringYesUnique slug (lowercase, alphanumeric, hyphens)
display_namestringYesHuman-readable name (1-100 chars)
descriptionstringNoDescription (max 500 chars)
filtersobjectYesFilter conditions
colorstringNoHex color code (#RRGGBB)

Response (201 Created): Full segment object


Update Segment

PUT /segments/{segment_id}?site_id={site_id}

Update an existing segment.

Request Body:

{
"display_name": "EU Mobile CPC Traffic",
"filters": {
"conditions": [
{"field": "utm_medium", "operator": "in", "value": ["cpc", "ppc"]},
{"field": "device_type", "operator": "eq", "value": "mobile"},
{"field": "country", "operator": "in", "value": ["ES", "FR", "DE", "IT", "PT", "NL", "BE"]}
]
}
}

All fields are optional. Only provided fields are updated.

warning

System segments cannot be modified. Duplicate them first if you need a variation.


Delete Segment

DELETE /segments/{segment_id}?site_id={site_id}

Delete a segment.

Response: 204 No Content

warning

System segments cannot be deleted.


Duplicate Segment

POST /segments/{segment_id}/duplicate?site_id={site_id}&new_name={new_name}

Create a copy of an existing segment with a new name.

Query Parameters:

ParameterTypeDescription
new_namestringName for the new segment (slug format)

Example:

POST /segments/organic-search/duplicate?site_id=my-site&new_name=organic-search-spain

Response (201 Created): Full segment object of the new copy


System Segments

Sealmetrics includes built-in segments for common patterns:

NameDisplay NameFilter
all-trafficAll TrafficNo filters
organic-searchOrganic Searchutm_medium = organic
paid-searchPaid Searchutm_medium = cpc
socialSocial Mediachannel = Social
directDirect Trafficchannel = Direct
referralReferral Trafficchannel = Referral
mobileMobile Usersdevice_type = mobile
desktopDesktop Usersdevice_type = desktop

System segments:

  • Cannot be modified or deleted
  • Can be duplicated to create custom variations
  • Are included by default in segment lists

Using Segments in Stats Endpoints

Apply a segment to any stats endpoint with the segment parameter:

GET /stats/pages?site_id=my-site&segment=paid-spain

You can reference segments by:

  • Name: segment=paid-spain
  • ID: segment=seg_abc123

Combining Segment with Explicit Filters

When you use a segment AND explicit filter parameters:

GET /stats/pages?site_id=my-site&segment=paid-spain&utm_campaign=spring_sale

The segment filters are applied first, then explicit parameters are added (AND logic).


Error Codes

HTTPError CodeDescription
403forbiddenEditor permission required
403cannot_modify_systemSystem segments cannot be modified
404not_foundSegment not found
409conflictSegment name already exists

Code Examples

Python - Create and Use Segment

import requests

API_KEY = "sm_your_api_key"
BASE_URL = "https://api.sealmetrics.com/api/v1"
ACCOUNT_ID = "my-site"

def create_segment(name, display_name, conditions, color=None):
"""Create a new segment."""
response = requests.post(
f"{BASE_URL}/segments",
headers={"X-API-Key": API_KEY},
params={"site_id": ACCOUNT_ID},
json={
"name": name,
"display_name": display_name,
"filters": {"conditions": conditions},
"color": color
}
)
response.raise_for_status()
return response.json()["data"]


def get_stats_with_segment(segment_name, period="30d"):
"""Get stats using a saved segment."""
response = requests.get(
f"{BASE_URL}/stats/overview",
headers={"X-API-Key": API_KEY},
params={
"site_id": ACCOUNT_ID,
"period": period,
"segment": segment_name
}
)
return response.json()["data"]


# Create a segment for high-value EU traffic
segment = create_segment(
name="eu-converters",
display_name="EU Converters",
conditions=[
{"field": "country", "operator": "in", "value": ["ES", "FR", "DE", "IT"]},
{"field": "utm_medium", "operator": "in", "value": ["cpc", "email"]}
],
color="#10B981"
)

print(f"Created segment: {segment['id']}")

# Use the segment
stats = get_stats_with_segment("eu-converters", "7d")
print(f"Conversions: {stats['conversions']}")
print(f"Revenue: €{stats['revenue']}")

JavaScript - List and Apply Segments

const API_KEY = 'sm_your_api_key';
const BASE_URL = 'https://api.sealmetrics.com/api/v1';
const ACCOUNT_ID = 'my-site';

async function listSegments(includeSystem = true) {
const params = new URLSearchParams({
site_id: ACCOUNT_ID,
include_system: includeSystem
});

const response = await fetch(`${BASE_URL}/segments?${params}`, {
headers: { 'X-API-Key': API_KEY }
});

const { data } = await response.json();
return data;
}

async function getStatsForAllSegments(period = '30d') {
const segments = await listSegments();
const results = {};

for (const segment of segments) {
const params = new URLSearchParams({
site_id: ACCOUNT_ID,
period,
segment: segment.name
});

const response = await fetch(`${BASE_URL}/stats/overview?${params}`, {
headers: { 'X-API-Key': API_KEY }
});

const { data } = await response.json();
results[segment.display_name] = {
entrances: data.entrances,
conversions: data.conversions,
revenue: data.revenue
};
}

return results;
}

// Usage
const comparison = await getStatsForAllSegments('30d');
console.table(comparison);

Create Complex Segment with OR Logic

# Spanish mobile users OR French desktop users
complex_segment = create_segment(
name="es-mobile-or-fr-desktop",
display_name="ES Mobile OR FR Desktop",
filters={
"groups": [
{
"conditions": [
{"field": "country", "operator": "eq", "value": "ES"},
{"field": "device_type", "operator": "eq", "value": "mobile"}
]
},
{
"conditions": [
{"field": "country", "operator": "eq", "value": "FR"},
{"field": "device_type", "operator": "eq", "value": "desktop"}
]
}
]
}
)