Skip to main content

Pagination, Sorting & Advanced Filters

Complete reference for pagination, sorting, and advanced filtering across all API endpoints.


Pagination

List endpoints return paginated results to handle large datasets efficiently.

Request Parameters

ParameterTypeDefaultRangeDescription
pageinteger11+Page number (1-indexed)
page_sizeinteger501-1000Items per page
note

Some endpoints have a lower maximum page_size (100 instead of 1000). Check individual endpoint documentation.

Response Format

All paginated endpoints return a consistent response structure:

{
"data": [...],
"total": 250,
"page": 1,
"page_size": 50,
"has_next": true,
"has_prev": false
}
FieldTypeDescription
dataarrayArray of result items
totalintegerTotal count of items matching the query
pageintegerCurrent page number
page_sizeintegerItems per page
has_nextbooleantrue if more pages exist after this one
has_prevbooleantrue if pages exist before this one

Pagination Examples

First page (default):

GET /stats/pages?site_id=my-site&period=30d

Second page with 100 items:

GET /stats/pages?site_id=my-site&period=30d&page=2&page_size=100

Calculate total pages:

const totalPages = Math.ceil(response.total / response.page_size);

Sorting

Control the order of results with sort_by and sort_order parameters.

Request Parameters

ParameterTypeDefaultDescription
sort_bystringvariesField to sort by
sort_orderstringdescSort direction: asc or desc

Available Sort Fields

Traffic Endpoints

For /stats/pages, /stats/sources, /stats/campaigns, /stats/mediums, /stats/terms, /stats/contents, /stats/referrers, /stats/geo/countries:

FieldDescription
entrancesSession starts (default)
engaged_entrancesEngaged sessions (2+ pageviews)
page_viewsTotal page views
conversionsTotal conversions
revenueTotal revenue

Page Endpoints

For /stats/pages:

FieldDescription
page_viewsPage views (default)
entrancesEntry points to this page
engaged_entrancesEngaged entries
conversionsConversions on this page
revenueRevenue from this page

Conversion Endpoints

For /stats/conversions:

FieldDescription
countNumber of conversions (default)
revenueTotal revenue
avg_valueAverage conversion value

Microconversion Endpoints

For /stats/microconversions:

FieldDescription
countNumber of microconversions (default)

Sorting Examples

Top sources by revenue:

GET /stats/sources?site_id=my-site&sort_by=revenue&sort_order=desc

Lowest bounce rate pages:

GET /stats/pages?site_id=my-site&sort_by=engaged_entrances&sort_order=desc

Newest conversions first:

GET /stats/conversions?site_id=my-site&sort_by=count&sort_order=asc

Standard Filters

Most endpoints support these common filter parameters:

UTM Filters

ParameterDescriptionExample
utm_sourceTraffic sourcegoogle, facebook
utm_mediumTraffic mediumcpc, organic, email
utm_campaignCampaign namespring_sale
utm_termSearch term/keywordrunning shoes

Geographic Filters

ParameterDescriptionExample
countryISO 3166-1 alpha-2 codeES, US, FR

Content Filters

ParameterDescriptionExample
content_groupingContent group nameblog, products
path_filterURL path pattern/products/

Device Filters

ParameterDescriptionExample
device_typeDevice categorydesktop, mobile, tablet
browserBrowser nameChrome, Safari
osOperating systemWindows, iOS

Segment Filter

ParameterDescriptionExample
segmentSaved segment ID or namepaid-spain, mobile-users

Advanced Filters

The filters parameter enables complex filtering with operators.

Syntax

filters=field:operator:value,field2:operator:value2

Multiple filters are combined with AND logic.

Operators

OperatorDescriptionExample
eqEqualscountry:eq:ES
neNot equalscountry:ne:US
containsContains substringutm_source:contains:google
not_containsDoes not containpath:not_contains:admin
regexRegex matchpath:regex:^/products/
not_regexRegex not matchpath:not_regex:^/api/
inIn list (values separated by |)country:in:ES|FR|DE
not_inNot in listutm_medium:not_in:cpc|ppc

Field Reference

Available fields for advanced filtering:

FieldDescription
utm_sourceTraffic source
utm_mediumTraffic medium
utm_campaignCampaign name
utm_termSearch term
utm_contentAd content
countryCountry code
device_typeDevice type
browserBrowser name
osOperating system
pathPage URL path
referrerReferrer domain

Examples

Spanish traffic only:

GET /stats/pages?site_id=my-site&filters=country:eq:ES

EU countries excluding UK:

GET /stats/sources?site_id=my-site&filters=country:in:ES|FR|DE|IT|PT,country:ne:GB

Product pages from Google:

GET /stats/pages?site_id=my-site&filters=path:contains:/products/,utm_source:eq:google

Non-branded organic traffic:

GET /stats/campaigns?site_id=my-site&filters=utm_medium:eq:organic,utm_campaign:not_contains:brand

Mobile users from social:

GET /stats/pages?site_id=my-site&filters=device_type:eq:mobile,utm_medium:in:social|social-media

Blog pages with regex:

GET /stats/pages?site_id=my-site&filters=path:regex:^/blog/2025/

Saved Segments

Segments are pre-saved filter combinations that can be reused.

Using Segments

Apply a segment with the segment parameter:

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

Segments can be referenced by ID or name.

Segment + Explicit Filters

When you combine a segment with explicit filter parameters:

  1. Segment filters are applied first
  2. Explicit parameters override segment values
  3. Additional filters are ANDed together

Example:

If segment paid-traffic has utm_medium=cpc, and you add country=ES:

GET /stats/pages?site_id=my-site&segment=paid-traffic&country=ES

This applies: utm_medium=cpc AND country=ES


Filter Combinations

Standard + Advanced Filters

You can combine standard parameters with advanced filters:

GET /stats/pages?site_id=my-site&utm_medium=cpc&country=ES&filters=path:contains:/products/

This applies:

  • utm_medium = cpc (standard)
  • country = ES (standard)
  • path LIKE '%/products/%' (advanced)

Priority

  1. Saved segment filters (lowest priority)
  2. Standard filter parameters
  3. Advanced filters (highest priority)

If the same field appears in multiple places, the higher priority wins.


Response with Filters

The response includes filter metadata when applicable:

{
"data": [...],
"total": 45,
"page": 1,
"page_size": 50,
"has_next": false,
"has_prev": false,
"comparison": {
"entrances": 420,
"engaged_entrances": 336,
"page_views": 1250,
"conversions": 15,
"revenue": 1200.00
}
}

The comparison object (when compare is used) contains totals for the comparison period using the same filters.


Best Practices

Pagination

  1. Use reasonable page sizes - 50-100 items is optimal for most cases
  2. Don't skip pages - Iterate sequentially for complete data
  3. Cache total count - The total rarely changes during pagination

Filtering

  1. Start broad, then narrow - Add filters incrementally
  2. Use segments for reusable filters - Avoid repeating complex filter strings
  3. Use in for multiple values - More efficient than multiple requests

Sorting

  1. Default sort is usually optimal - Most endpoints default to the most useful sort
  2. Secondary sorting not supported - Results with equal values have undefined order
  3. Ascending for "worst" analysis - Use asc to find lowest performers

Code Examples

Python - Paginate All Results

import requests

def get_all_pages(site_id, period="30d"):
"""Fetch all pages with pagination."""
all_data = []
page = 1

while True:
response = requests.get(
"https://api.sealmetrics.com/api/v1/stats/pages",
headers={"X-API-Key": API_KEY},
params={
"site_id": site_id,
"period": period,
"page": page,
"page_size": 100,
"sort_by": "entrances",
"sort_order": "desc"
}
)
data = response.json()
all_data.extend(data["data"])

if not data["has_next"]:
break
page += 1

return all_data

JavaScript - Advanced Filter Builder

class FilterBuilder {
constructor() {
this.filters = [];
}

equals(field, value) {
this.filters.push(`${field}:eq:${value}`);
return this;
}

contains(field, value) {
this.filters.push(`${field}:contains:${value}`);
return this;
}

in(field, values) {
this.filters.push(`${field}:in:${values.join('|')}`);
return this;
}

notEquals(field, value) {
this.filters.push(`${field}:ne:${value}`);
return this;
}

build() {
return this.filters.join(',');
}
}

// Usage
const filters = new FilterBuilder()
.in('country', ['ES', 'FR', 'DE'])
.equals('utm_medium', 'cpc')
.contains('path', '/products/')
.build();

// Result: "country:in:ES|FR|DE,utm_medium:eq:cpc,path:contains:/products/"

PHP - Sorted and Filtered Request

<?php
$params = http_build_query([
'site_id' => 'my-site',
'period' => '30d',
'filters' => 'country:in:ES|FR,utm_medium:eq:organic',
'sort_by' => 'revenue',
'sort_order' => 'desc',
'page' => 1,
'page_size' => 50
]);

$response = file_get_contents(
"https://api.sealmetrics.com/api/v1/stats/sources?{$params}",
false,
stream_context_create([
'http' => [
'header' => "X-API-Key: {$apiKey}"
]
])
);

$data = json_decode($response, true);
foreach ($data['data'] as $source) {
echo "{$source['utm_source']}: €{$source['revenue']}\n";
}