Advanced Stats Endpoints
Complete reference for advanced analytics endpoints including UTM hierarchy, landing pages, channels, and microconversions.
UTM Hierarchy
Sealmetrics organizes traffic data in a hierarchical UTM structure:
Medium (email, organic, paid, referral)
└── Source (google, facebook, newsletter)
└── Campaign (spring_sale, brand_awareness)
└── Term (running shoes, blue widget)
└── Content (banner_a, text_link)
Each level can be queried independently with filters from parent levels.
Traffic by Medium
GET /stats/mediums
Get traffic metrics grouped by UTM medium.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
site_id | string | required | Site ID (alias: account_id) |
period | string | - | Date period (see Periods) |
start_date | date | - | Custom start date (YYYY-MM-DD) |
end_date | date | - | Custom end date (YYYY-MM-DD) |
segment | string | - | Apply saved segment filters |
country | string | - | Filter by country code (ISO 2-letter) |
filters | string | - | Advanced filters (see Filtering) |
search | string | - | Case-insensitive search on utm_medium (max 200 chars) |
sort_by | string | entrances | Sort field (see Sort Fields) |
sort_order | string | desc | Sort order (asc/desc) |
page | integer | 1 | Page number |
page_size | integer | 50 | Items per page (1-100) |
compare | string | - | Comparison mode (previous/yoy) — adds top-level comparison totals |
include_totals | boolean | false | Add aggregated totals for the current period to the response |
Response:
{
"data": [
{
"utm_medium": "organic",
"entrances": 15420,
"engaged_entrances": 12336,
"page_views": 45780,
"conversions": 245,
"revenue": 18650.00,
"bounce_rate": 20.0
},
{
"utm_medium": "paid",
"entrances": 8750,
"engaged_entrances": 6125,
"page_views": 22400,
"conversions": 180,
"revenue": 14200.00,
"bounce_rate": 30.0
}
],
"total": 5,
"page": 1,
"page_size": 50,
"has_next": false,
"has_prev": false
}
Traffic by Source
GET /stats/sources
Get traffic metrics grouped by UTM source. Same query params as /stats/mediums, with one addition:
| Parameter | Type | Description |
|---|---|---|
utm_medium | string | Filter by specific medium |
search matches on utm_source instead of utm_medium.
Response:
{
"data": [
{
"utm_source": "google",
"entrances": 12500,
"engaged_entrances": 10000,
"page_views": 35000,
"conversions": 150,
"revenue": 12500.00,
"bounce_rate": 20.0
}
],
"total": 25,
"page": 1,
"page_size": 50
}
Top Sources
GET /stats/sources/top
Get top sources by entrances.
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 10 | Number of results (1-100) |
utm_medium | string | - | Filter by medium |
country | string | - | Filter by country |
Traffic by Campaign
GET /stats/campaigns
Get traffic metrics grouped by UTM campaign. Same query params as /stats/mediums, with these additions:
| Parameter | Type | Description |
|---|---|---|
utm_medium | string | Filter by medium |
utm_source | string | Filter by source |
search matches on utm_campaign.
Top Campaigns
GET /stats/campaigns/top
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 10 | Number of results (1-100) |
utm_medium / utm_source | string | - | UTM filters |
country | string | - | Filter by country |
Traffic by Term
GET /stats/terms
Get traffic metrics grouped by UTM term (search keywords). Same query params as /stats/mediums, with these additions:
| Parameter | Type | Description |
|---|---|---|
utm_medium | string | Filter by medium |
utm_source | string | Filter by source |
utm_campaign | string | Filter by campaign |
search matches on utm_term.
Top Terms
GET /stats/terms/top
Same params as /stats/campaigns/top, accepts utm_campaign filter.
Traffic by Content
GET /stats/contents
Get traffic by UTM content parameter (ad variations, link types). Same query params as /stats/mediums, with these additions:
| Parameter | Type | Description |
|---|---|---|
utm_medium | string | Filter by medium |
utm_source | string | Filter by source |
utm_campaign | string | Filter by campaign |
search matches on utm_content.
Top Contents
GET /stats/contents/top
Same params as /stats/campaigns/top, accepts utm_campaign filter.
Referrer Traffic
GET /stats/referrers
Get traffic from external referrer domains.
Response:
{
"data": [
{
"referrer": "facebook.com",
"entrances": 5420,
"engaged_entrances": 3254,
"page_views": 12500,
"conversions": 45,
"revenue": 3200.00,
"bounce_rate": 40.0
}
],
"total": 150,
"page": 1,
"page_size": 50
}
Top Referrers
GET /stats/referrers/top
Landing Pages
GET /stats/landing-pages
Get metrics for entry pages (first page of session). Backed by report_landing_pages, which carries conversion and engagement data per entry page.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
site_id | string | required | Site identifier |
start_date / end_date / period | date / string | - | Date range (see Date Periods) |
segment | string | - | Apply saved segment (ID or name) |
content_grouping | string | - | Filter by content group |
path_filter | string | - | Filter by path (LIKE search) |
country | string[] | - | Filter by country (ISO 2-letter, repeat for OR) |
utm_source / utm_medium / utm_campaign / utm_term | string[] | - | Filter by UTM (repeat for OR) |
device_type / browser / os | string[] | - | Filter by device dimension (repeat for OR) |
channel_group | string[] | - | Filter by channel group. Use "" for pre-migration rows |
include | string[] | - | Add dimensions to GROUP BY and response. Allowed: device, browser, os, channel_group |
filters | string | - | Advanced filters field:op:value,... (eq, ne, contains, not_contains, regex, in, not_in) |
sort_by | string | entrances | entrances, engaged_entrances, microconversions, conversions, revenue, bounce_rate |
sort_order | string | desc | asc or desc |
page | integer | 1 | Page number |
page_size | integer | 50 | Items per page (1-1000) |
compare | string | - | previous or yoy — adds comparison totals + per-row _prev fields |
include_totals | boolean | false | Add aggregated totals for the current period to the response |
include_utm | boolean | false | Group by UTM and include utm_* fields in each row |
Unknown include values return 422 Unprocessable Entity.
Response:
{
"data": [
{
"landing_page": "/products/running-shoes",
"content_grouping": "Products",
"entrances": 8500,
"engaged_entrances": 6800,
"bounce_rate": 20.0,
"microconversions": 1200,
"conversions": 85,
"conversion_rate": 1.0,
"revenue": 7650.00
}
],
"total": 450,
"page": 1,
"page_size": 50,
"has_next": true,
"has_prev": false
}
When include_utm=true, each row also includes utm_source, utm_medium, utm_campaign, utm_term, utm_content. When include is set, each row carries the requested dimension column(s). When compare is set, the response includes a top-level comparison object with previous-period totals and each row gets _prev metric fields. When include_totals=true, the response includes a totals object aggregating the current period.
Top Landing Pages
GET /stats/landing-pages/top
Top landing pages by entrances. Returns the same metric shape as /stats/landing-pages rows.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
site_id | string | required | Site identifier |
start_date / end_date / period | date / string | - | Date range |
utm_source / utm_medium | string | - | UTM filters (single value). utm_campaign and utm_term are not accepted on this endpoint — use /stats/landing-pages if you need to filter by them |
country | string | - | Filter by country |
content_grouping | string | - | Filter by content group |
filters | string | - | Advanced filters field:op:value,... |
limit | integer | 10 | Number of results (1-100) |
Response:
{
"data": [
{
"landing_page": "/products/running-shoes",
"content_grouping": "Products",
"entrances": 8500,
"engaged_entrances": 6800,
"bounce_rate": 20.0,
"microconversions": 1200,
"conversions": 85,
"conversion_rate": 1.0,
"revenue": 7650.00
}
]
}
Landing Pages by Content Group
GET /stats/landing-pages/by-content-group
Aggregate landing page metrics by content group. Returns one row per group with unique_pages count and the full engagement/conversion metric set.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
site_id | string | required |
start_date / end_date / period | date / string | Date range |
utm_source / utm_medium | string | UTM filters (single value) |
country | string | Filter by country |
Response:
{
"data": [
{
"content_grouping": "Products",
"unique_pages": 56,
"entrances": 24500,
"engaged_entrances": 19200,
"bounce_rate": 21.6,
"microconversions": 3400,
"conversions": 245,
"conversion_rate": 1.0,
"revenue": 21500.00
}
]
}
Channel Groups
GET /stats/channels
Get traffic by GA4-style channel grouping.
Sealmetrics automatically classifies traffic into channels based on UTM parameters:
| Channel | Classification |
|---|---|
| Direct | No referrer, no UTM |
| Organic Search | medium=organic, source is search engine |
| Paid Search | medium=cpc|ppc|paid |
| Display | medium=display|banner |
medium=email | |
| Social | Source is social network |
| Referral | Has referrer, no UTM |
| Affiliate | medium=affiliate |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
site_id | string | required | Site ID (alias: account_id) |
start_date / end_date / period | date / string | - | Date range |
segment | string | - | Apply saved segment |
country | string | - | Filter by country (ISO 2-letter) |
filters | string | - | Advanced filters |
search | string | - | Case-insensitive search on channel name (max 200 chars) |
sort_by | string | entrances | entrances, engaged_entrances, page_views, conversions, revenue |
sort_order | string | desc | asc or desc |
page | integer | 1 | Page number |
page_size | integer | 50 | Items per page (1-100) |
compare | string | - | previous or yoy — adds row-level _prev fields and top-level comparison |
include_totals | boolean | false | Include aggregated totals for the current period |
Response:
{
"data": [
{
"channel": "Organic Search",
"entrances": 25000,
"engaged_entrances": 20000,
"page_views": 75000,
"microconversions": 3400,
"conversions": 350,
"revenue": 28000.00,
"bounce_rate": 20.0
}
],
"total": 8,
"page": 1,
"page_size": 50,
"has_next": false,
"has_prev": false
}
Top Channels
GET /stats/top-channels
Top channels by entrances.
| Parameter | Type | Default | Description |
|---|---|---|---|
site_id | string | required | Site ID |
start_date / end_date / period | date / string | - | Date range |
country | string | - | Filter by country |
limit | integer | 10 | Number of results (1-50) |
Response: APIResponse<Channel[]> with the same metric shape as /stats/channels rows.
Microconversions
Microconversions track intermediate user actions (add to cart, form start, video play, etc.).
List Microconversions
GET /stats/microconversions
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
utm_source | string | Filter by source |
utm_medium | string | Filter by medium |
utm_campaign | string | Filter by campaign |
utm_term | string | Filter by term |
country | string | Filter by country (ISO 2-letter) |
device_type | string | Filter by device (desktop/mobile/tablet) |
browser | string | Filter by browser |
os | string | Filter by operating system |
conversion_type | string | Filter by specific type |
segment | string | Apply saved segment |
filters | string | Advanced filters |
sort_by | string | Sort by: count |
compare | string | Comparison mode |
Response:
{
"data": [
{
"conversion_type": "add_to_cart",
"count": 4520,
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "spring_sale"
},
{
"conversion_type": "newsletter_signup",
"count": 890,
"utm_source": "facebook",
"utm_medium": "social",
"utm_campaign": null
}
],
"total": 125,
"page": 1,
"page_size": 20
}
Microconversion Details
GET /stats/microconversions/{conversion_type}
Get detailed breakdown for a specific microconversion type.
Path Parameters:
| Parameter | Description |
|---|---|
conversion_type | Type of microconversion (e.g., add_to_cart) |
Response:
{
"success": true,
"data": {
"conversion_type": "add_to_cart",
"total_count": 4520,
"by_source": [
{"utm_source": "google", "count": 2500},
{"utm_source": "facebook", "count": 1200}
],
"by_country": [
{"country": "ES", "count": 2800},
{"country": "FR", "count": 950}
],
"by_device": [
{"device_type": "mobile", "count": 2700},
{"device_type": "desktop", "count": 1820}
],
"by_landing_page": [
{"path": "/products/shoes", "count": 1500},
{"path": "/sale", "count": 980}
]
}
}
Available Microconversion Types
GET /stats/microconversions-types
Get list of microconversion types with data in the selected period.
Response:
{
"success": true,
"data": [
"add_to_cart",
"newsletter_signup",
"video_play",
"form_start",
"wishlist_add"
]
}
Date Periods
All stats endpoints accept a period parameter with these values:
Relative Periods
| Value | Description |
|---|---|
today | Current day (midnight to now) |
yesterday | Previous complete day |
7d | Last 7 days including today |
30d | Last 30 days including today |
90d | Last 90 days including today |
12m | Last 12 months (365 days) |
Calendar Periods
| Value | Description |
|---|---|
this_week | Current week (Monday to today) |
last_week | Previous complete week (Mon-Sun) |
this_month | Current month (1st to today) |
last_month | Previous complete month |
this_quarter | Current quarter to today |
last_quarter | Previous complete quarter |
this_year | January 1st to today |
last_year | Previous complete year |
To-Date Aliases
| Value | Equivalent |
|---|---|
wtd | this_week |
mtd | this_month |
qtd | this_quarter |
ytd | this_year |
How "today" is resolved
Every preset is resolved with "today" in the account's timezone (accounts.timezone), not in UTC or in the caller's browser. This matches how the data is stored — the pixel-service pre-computes each hit's local date using the account's timezone — and mirrors what GA4, Plausible and Matomo call the "reporting timezone".
Consequences worth knowing:
- Two accounts in different timezones will see different windows for
todayeven at the exact same wall-clock instant. - Explicit
start_date/end_date(ISOYYYY-MM-DD) are also interpreted as local days in the account's timezone. - The stats and query endpoints (
/stats/*,/stats/query,/batch,/channel-groups/stats/*) all follow this rule. If you write your own tooling that pre-resolves a range client-side, use the account's timezone as your reference — don't use the server's UTC clock. - Changing a site's timezone in Settings takes effect on the API within ~5 min (the timezone cache TTL).
Period comparison
Set compare=previous (or yoy where supported) on any endpoint that accepts period to also fetch the equivalent prior window. See each endpoint's response shape for how comparison fields are laid out.
Sort Fields
Different endpoints support different sort fields:
Traffic Endpoints
/stats/sources, /stats/campaigns, /stats/mediums, etc.
| Field | Description |
|---|---|
entrances | Session starts (default) |
engaged_entrances | Engaged sessions |
page_views | Total page views |
conversions | Total conversions |
revenue | Total revenue |
Conversion Endpoints
/stats/conversions
| Field | Description |
|---|---|
count | Number of conversions (default) |
revenue | Total revenue |
avg_value | Average conversion value |
Microconversion Endpoints
/stats/microconversions
| Field | Description |
|---|---|
count | Number of microconversions (default) |
Code Examples
Get Top Sources by Revenue
import requests
response = requests.get(
"https://my.sealmetrics.com/api/v1/stats/sources",
headers={"X-API-Key": "sm_your_api_key"},
params={
"site_id": "my-site",
"period": "30d",
"sort_by": "revenue",
"sort_order": "desc",
"page_size": 10
}
)
for source in response.json()["data"]:
print(f"{source['utm_source']}: €{source['revenue']}")
Filter by Segment and Country
response = requests.get(
"https://my.sealmetrics.com/api/v1/stats/campaigns",
headers={"X-API-Key": "sm_your_api_key"},
params={
"site_id": "my-site",
"period": "7d",
"segment": "paid-traffic",
"country": "ES",
"compare": "previous"
}
)
Get Microconversion Funnel
# Get add_to_cart by source
carts = requests.get(
"https://my.sealmetrics.com/api/v1/stats/microconversions",
headers={"X-API-Key": "sm_your_api_key"},
params={
"site_id": "my-site",
"period": "30d",
"conversion_type": "add_to_cart"
}
).json()
for item in carts["data"]:
print(f"{item['utm_source']}: {item['count']} carts")