Skip to main content

Data endpoints

GET burst/v1/data/{type} is the primary read API for pulling analytics data out of Burst Statistics. Use it to build external dashboards, feed data pipelines or power AI workflows.

Prerequisites

  • Burst Statistics (Free or Pro)
  • WordPress user with view_burst_statistics capability, or an Application Password for that user
  • See Authentication for setup

Route

GET /wp-json/burst/v1/data/{type}
GET /wp-json/burst/v1/data/datatable/{id}
GET /wp-json/burst/v1/data/ecommerce/datatable/{id}

Permission: view_burst_statistics (datatable and standard types). Ecommerce datatables additionally require the view_sales_burst_statistics capability.

The {type} path segment selects the data shape returned. Accepted characters: [a-z_-]+.

The {id} path segment selects a specific datatable. Accepted characters: [a-z_-]+. See Granular datatable endpoints below.

:::caution Breaking change Changed in v3.4.2: the generic data/datatable and data/ecommerce/datatable endpoints now return HTTP 403 for all callers. Switch every datatable request to the granular data/datatable/{id} or data/ecommerce/datatable/{id} routes. The granular routes enforce a per-datatable metric allow-list — metrics not in the allow-list are silently dropped from the response. :::

Request parameters

ParameterTypeDefaultDescription
date_startstring (YYYY-MM-DD)Start of the requested period. Normalized to 00:00:00 in the WordPress timezone
date_endstring (YYYY-MM-DD)End of the requested period. Normalized to 23:59:59 in the WordPress timezone
date_rangestringOptional named range. Accepted values include today, yesterday, last-7-days, last-30-days, last-90-days, week-to-date, month-to-date, year-to-date and all-time
filtersarray / JSON string[]Filter payload. Accepts arrays, JSON-encoded arrays/objects or comma-separated strings. Empty strings are removed; 0 is preserved
metricsarray / stringvaries by typeMetric names to include. A single string value is normalized to a single-element array. For datatable endpoints, values are intersected with the per-datatable allow-list
group_byarray / stringvaries by typeGrouping fields. A single string value is normalized to a single-element array
goal_idint0Goal identifier. Required for goals and live-goals types
isOnboardingboolfalseUsed by the live-visitors onboarding flow; has no effect on other types
chart_modestringrevenueValue mode for subscriptions-revenue-chart. Accepts revenue or sales
distribution_viewstringgatewaysBreakdown dimension for subscriptions-distribution. Accepts gateways, currencies or countries
product_idint0Optional product filter for subscriptions-retention
idstringDatatable identifier. Equivalent to using the data/datatable/{id} path segment and useful when calling the AJAX fallback. Must be one of the granular datatable IDs
is_ecommerceboolfalseRoutes the request through the ecommerce permission gate. Set automatically when the data/ecommerce/datatable/{id} route is used

Changed in v3.4.0: the all-time value is now accepted by date_range. New arguments chart_mode, distribution_view and product_id were added for the subscriptions data types, and id is now a recognised datatable argument.

Changed in v3.4.2: id is now mandatory whenever a datatable response is requested. The new is_ecommerce flag is forwarded to the permission layer when the ecommerce datatable route is invoked through the AJAX fallback.

Filter keys

The filters parameter accepts an object where each key maps to a value or array of values. Accepted keys depend on the user's role and whether Burst Pro is active.

All authenticated users (strict mode — viewer role):

KeyTypeDescription
page_typestring / arrayPost type (e.g. post, page)
page_idint / arrayWordPress post ID
page_urlstring / arrayFull or partial page URL
referrerstring / arrayReferrer hostname
devicestring / arrayDevice category: desktop, tablet, mobile, other
browserstring / arrayBrowser name
platformstring / arrayOperating system name

Admin users (non-strict mode — additional keys):

KeyTypeDescription
goal_idintFilter sessions that converted a specific goal
bouncesbool / int1 for bounced sessions only, 0 for non-bounced
new_visitorbool / int1 for first-time visitors only
device_idint / arrayInternal device lookup ID
browser_idint / arrayInternal browser lookup ID
platform_idint / arrayInternal platform lookup ID
time_per_sessionstringTime-on-site range (e.g. 0-30)

Burst Pro (additional keys, all roles):

KeyTypeDescription
country_codestring / arrayISO 3166-1 alpha-2 country code
citystring / arrayCity name
statestring / arrayState or province name
continentstring / arrayContinent name
continent_codestring / arrayTwo-letter continent code
sourcestring / arrayUTM source
mediumstring / arrayUTM medium
campaignstring / arrayUTM campaign
termstring / arrayUTM term
contentstring / arrayUTM content

Prefix a filter value with ! to exclude it (e.g. "device": "!mobile" excludes mobile sessions).

Keys outside the allowed list for the current role are silently ignored.

Response envelope

All successful responses follow this structure:

Show code
{
"data": {},
"request_success": true,
"success": true
}

On failure, success is false and a message field or empty data is returned with an appropriate HTTP status code.

Types

live-visitors

Returns the current count of active visitors on the site. The live window is approximately 10 minutes with configurable offsets.

Extra parameters: isOnboarding (bool) — enables a simplified count path used during the plugin's onboarding flow.

Response:

Show code
{
"data": {
"visitors": 12
},
"request_success": true,
"success": true
}

live-traffic

Returns the most recent traffic rows within the live window (max 100 rows). Use this to build a real-time activity feed.

Response — data is an indexed array of row objects:

FieldTypeDescription
uidstringAnonymous visitor identifier
page_urlstringURL of the page visited
timeintUnix timestamp of the hit
time_on_pageintSeconds spent on the page
active_timeintActive (non-idle) seconds
utm_sourcestringSession referrer or UTM source
entryboolWhether this is the session's entry page
checkoutboolWhether a checkout event was recorded
exitboolWhether this is the session's exit page
Show code
{
"data": [
{
"uid": "a1b2c3d4",
"page_url": "/shop/product-name/",
"time": 1714000000,
"time_on_page": 45,
"active_time": 30,
"utm_source": "google",
"entry": true,
"checkout": false,
"exit": false
}
],
"request_success": true,
"success": true
}

today

Returns the summary metrics shown in the Burst "Today" card. Accepts date_start and date_end to query any period, not just today.

Response — data fields:

FieldTypeDescription
live{ value, tooltip }Current live visitor count
today{ value, tooltip }Unique visitors for the period
mostViewed{ title, value, tooltip }Most viewed page title and view count
referrer{ title, value, tooltip }Top referrer hostname and session count
pageviews{ title, value, tooltip }Total pageview count
timeOnPage{ title, value, tooltip }Average time on page (formatted string)
Show code
{
"data": {
"live": { "value": "12", "tooltip": "Live visitors" },
"today": { "value": "348", "tooltip": "Unique visitors" },
"mostViewed": { "title": "Most viewed", "value": "/blog/", "tooltip": "124 views" },
"referrer": { "title": "Top referrer", "value": "google.com", "tooltip": "87 sessions" },
"pageviews": { "title": "Pageviews", "value": "512", "tooltip": "" },
"timeOnPage": { "title": "Avg. time on page", "value": "1:24", "tooltip": "" }
},
"request_success": true,
"success": true
}

goals

Returns goal statistics for the selected period. Requires goal_id.

Extra parameters: goal_id (int, required)

Response — data fields:

FieldTypeDescription
goalIdintThe requested goal ID
statusstringGoal status
dateCreatedstringISO date the goal was created
dateStartstringPeriod start date
dateEndstringPeriod end date
today{ value, title, tooltip }Conversions today
total{ value, title, tooltip }Total conversions in the period
topPerformer{ value, title, tooltip }Top converting page
conversionMetric{ value, title, tooltip }Primary conversion metric
conversionPercentage{ value, title, tooltip }Conversion rate for the period
bestDevice{ value, title, tooltip, icon }Device with the highest conversion rate

live-goals

Returns the live conversion count for a single goal. Requires goal_id.

Extra parameters: goal_id (int, required)

Response:

Show code
{
"data": {
"goals_count": 3
},
"request_success": true,
"success": true
}

insights

Returns time-series chart data for the selected period. This is the data behind the main insights graph.

Extra parameters:

ParameterNotes
metricsDefault: ["pageviews", "visitors"]. Pass additional metric names to include extra datasets
group_byControls the time interval. Accepts hour, day, week, month or auto. auto selects an interval based on the date range

Changed in v3.4.0: the response no longer returns a pre-formatted labels array. Instead it returns raw timestamps, the resolved interval and a spans_multiple_years flag so the client can format dates with Intl.DateTimeFormat (or any server-side formatter) and decide whether to include the year.

Response — data fields:

FieldTypeDescription
timestampsint[]UTC Unix timestamps, one per period bucket
intervalstringResolved interval: hour, day, week or month
spans_multiple_yearsboolWhether the range crosses a year boundary
datasetsarrayOne object per metric (see below)

Each dataset object:

FieldTypeDescription
labelstringHuman-readable metric name
datanumber[]One value per timestamp bucket
backgroundColorstringHex colour for the chart fill
borderColorstringHex colour for the chart line
fillboolWhether to fill the area under the line
Show code
{
"data": {
"timestamps": [1714521600, 1714608000, 1714694400],
"interval": "day",
"spans_multiple_years": false,
"datasets": [
{
"label": "Pageviews",
"data": [512, 489, 601],
"backgroundColor": "#ECF4ED",
"borderColor": "#2B8133",
"fill": true
},
{
"label": "Visitors",
"data": [348, 312, 401],
"backgroundColor": "#FFF8DC",
"borderColor": "#FFDA4A",
"fill": false
}
]
},
"request_success": true,
"success": true
}

compare

Returns aggregated metrics for the current period alongside the same metrics for the previous period of equal length. Useful for period-over-period comparisons.

When goal_id is set in filters, the response switches to goal-specific metrics.

Response — standard (no goal):

Show code
{
"data": {
"current": {
"pageviews": 512,
"sessions": 280,
"visitors": 348,
"first_time_visitors": 210,
"avg_time_on_page": 84,
"bounced_sessions": 112,
"bounce_rate": 40.0
},
"previous": {
"pageviews": 489,
"sessions": 265,
"visitors": 312,
"bounced_sessions": 104,
"bounce_rate": 39.2
}
},
"request_success": true,
"success": true
}

Response — goal variant (goal_id present in filters):

Show code
{
"data": {
"current": {
"pageviews": 512,
"visitors": 348,
"sessions": 280,
"first_time_visitors": 210,
"conversions": 42,
"conversion_rate": 15.0
},
"previous": {
"pageviews": 489,
"visitors": 312,
"sessions": 265,
"conversions": 38,
"conversion_rate": 14.3
}
},
"request_success": true,
"success": true
}

The previous period is calculated automatically as the same-length window immediately before date_start. To supply a custom comparison window, pass compare_date_start and compare_date_end via the burst_get_data_request_args filter — see Filters reference.

devicestitleandvalue

Returns visitor counts broken down by device category.

Response:

Show code
{
"data": {
"all": { "count": 348 },
"desktop": { "count": 210 },
"mobile": { "count": 98 },
"tablet": { "count": 30 },
"other": { "count": 10 }
},
"request_success": true,
"success": true
}

all is the sum of the named categories. Additional device names from the internal lookup table may appear as extra keys.

devicessubtitle

Returns secondary detail (OS, browser, internal ID) for each device category. Intended to power the sub-row display under the devices panel.

Response — data keys are device names (desktop, tablet, mobile, other):

Show code
{
"data": {
"desktop": {
"os": "Windows",
"browser": "Chrome",
"device_id": 1
},
"mobile": {
"os": "iOS",
"browser": "Safari",
"device_id": 2
},
"tablet": {
"os": "Android",
"browser": "Chrome",
"device_id": 3
},
"other": {
"os": "",
"browser": "",
"device_id": 0
}
},
"request_success": true,
"success": true
}

datatable

Tabular data is returned by the granular data/datatable/{id} and data/ecommerce/datatable/{id} routes. The {id} segment selects the datatable; metrics, group_by and filters then refine the rows.

Common parameters:

ParameterNotes
metricsArray of metric column names. Values are intersected with the datatable's allow-list; unknown metrics are dropped
group_byField to group rows by (e.g. page_url, referrer, device)
filtersStandard filter object; all filter keys from the filter keys section apply
idDatatable identifier when calling through the AJAX fallback. Ignored when the {id} path segment is used
is_ecommerceSet internally when the data/ecommerce/datatable/{id} route is used. Pass true when calling the ecommerce datatables via the AJAX fallback

Changed in v3.4.0: the burst_datatable_pre_data filter runs before the default SQL query and can short-circuit the result set. Providers that return an array from this filter fully replace the rows that Burst would have calculated from the statistics table, which is how the subscription_products and dummy_data datatables are served.

Response:

FieldTypeDescription
columnsarrayColumn definitions (see below)
dataarrayRow objects, keyed by metric/column name
metricsarrayResolved list of metric names included in the response after allow-list filtering

Each column object:

FieldTypeDescription
namestringDisplay label
idstringColumn key used in row objects
sortableboolWhether the column can be sorted client-side
rightboolWhether to right-align the column
Show code
{
"data": {
"columns": [
{ "name": "Page", "id": "page_url", "sortable": true, "right": false },
{ "name": "Pageviews", "id": "pageviews", "sortable": true, "right": true },
{ "name": "Visitors", "id": "visitors", "sortable": true, "right": true }
],
"data": [
{ "page_url": "/blog/", "pageviews": 124, "visitors": 98 },
{ "page_url": "/shop/", "pageviews": 87, "visitors": 72 }
],
"metrics": ["pageviews", "visitors"]
},
"request_success": true,
"success": true
}

Granular datatable endpoints

Added in v3.4.2.

Each granular endpoint maps to a single datatable and enforces a per-datatable metric allow-list. Metrics not listed for the requested datatable are silently dropped before the SQL is built, so attempting to request an unrelated metric never leaks data from another datatable.

Free-tier datatable IDs (registered by core):

IDRouteDescription
statistics_pagesdata/datatable/statistics_pagesTop pages and posts with visitor/session metrics
statistics_parametersdata/datatable/statistics_parametersURL parameter breakdown
statistics_referrersdata/datatable/statistics_referrersReferrer breakdown
dummy_datadata/datatable/dummy_dataRandomised preview rows used for demo/screenshot UIs (see dummy_data below)

Pro datatable IDs (registered when Burst Pro is active):

IDRouteDescriptionRequired tier
sources_referrersdata/datatable/sources_referrersDetailed referrer breakdown for the Sources tabPro
sources_countriesdata/datatable/sources_countriesCountry / state / city breakdownPro
sources_campaignsdata/datatable/sources_campaignsUTM campaign breakdownPro
sales_productsdata/ecommerce/datatable/sales_productsPer-product sales metricsBusiness
subscription_productsdata/ecommerce/datatable/subscription_productsPer-product subscription metricsBusiness

Unknown IDs respond with HTTP 404 and a message of Unknown datatable endpoint..

statistics_pages

Allowed metrics: page_url, pageviews, visitors, sessions, bounce_rate, avg_time_on_page, entrances, exit_rate, conversions, conversion_rate, sales, revenue, sales_conversion_rate, page_value.

Show code
curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
--get "https://example.com/wp-json/burst/v1/data/datatable/statistics_pages" \
--data-urlencode "date_start=2026-04-01" \
--data-urlencode "date_end=2026-04-15" \
--data-urlencode "metrics[]=pageviews" \
--data-urlencode "metrics[]=visitors" \
--data-urlencode "metrics[]=bounce_rate"

statistics_parameters

Allowed metrics: parameter, parameters, visitors, sessions, bounce_rate, avg_time_on_page, conversions, sales, revenue, page_value.

statistics_referrers

Allowed metrics: referrer, visitors, sessions, bounce_rate, conversions, sales, revenue, page_value.

sources_referrers

Pro - CreatorAvailable in the Creator tier

Requires Burst Pro. See Referral source analysis.

Mirrors statistics_referrers but is the route the Sources tab calls into. Same allowed metrics as statistics_referrers.

sources_countries

Pro - CreatorAvailable in the Creator tier

Requires Burst Pro for Geo-IP resolution. See Geographic insights.

Allowed metrics: country_code, state, city, continent, visitors, sessions, bounce_rate, conversions, sales, revenue, sales_conversion_rate, avg_order_value.

sources_campaigns

Pro - CreatorAvailable in the Creator tier

Requires Burst Pro for UTM tracking. See UTM campaign tracking.

Allowed metrics: campaign, source, medium, term, content, visitors, bounce_rate, conversions, conversion_rate, sales, revenue, sales_conversion_rate, page_value.

sales_products

Pro - BusinessAvailable in the Business tier

Requires the Business tier with an active WooCommerce or EDD integration. See Revenue and sales tracking.

Allowed metrics: product, adds_to_cart, sales, revenue.

Show code
curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
--get "https://example.com/wp-json/burst/v1/data/ecommerce/datatable/sales_products" \
--data-urlencode "date_start=2026-04-01" \
--data-urlencode "date_end=2026-04-15" \
--data-urlencode "metrics[]=product" \
--data-urlencode "metrics[]=sales" \
--data-urlencode "metrics[]=revenue"

subscription_products

Pro - BusinessAvailable in the Business tier

Subscription datatables and metrics require the Business tier with an active subscriptions integration. See Revenue and sales tracking.

Allowed metrics: plan, active_subscribers, canceled_subscribers, trialling_subscribers, monthly_recurring_revenue, product_churn_value.

Rows are keyed by a product identifier and expose subscription-specific metrics rather than pageview metrics.

Show code
{
"data": {
"columns": [
{ "name": "Plan", "id": "plan", "sortable": true, "right": false },
{ "name": "Active subs", "id": "active_subscribers", "sortable": true, "right": true },
{ "name": "MRR", "id": "monthly_recurring_revenue", "sortable": true, "right": true }
],
"data": [
{
"product_id": 42,
"plan": "Pro monthly",
"active_subscribers": 128,
"monthly_recurring_revenue": { "currency": "USD", "value": 2560.00 }
}
],
"metrics": ["plan", "active_subscribers", "monthly_recurring_revenue"]
},
"request_success": true,
"success": true
}

dummy_data

Returns a fixed-size set of randomised rows that match the statistics_pages schema. Use this in demo screens, onboarding flows or screenshots where production data is not available. Rows are generated in PHP and never touch the statistics table.

Allowed metrics: identical to statistics_pages.

Show code
curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
--get "https://example.com/wp-json/burst/v1/data/datatable/dummy_data" \
--data-urlencode "metrics[]=page_url" \
--data-urlencode "metrics[]=pageviews" \
--data-urlencode "metrics[]=visitors"

Extending the allow-list

The per-datatable allow-list is exposed through the burst_datatable_metric_allow_list filter. Use it to register a custom datatable or to expose an additional metric for an existing one.

Show code
add_filter(
'burst_datatable_metric_allow_list',
static function ( array $allow_list ): array {
$allow_list['statistics_pages'][] = 'my_custom_metric';

$allow_list['team_dashboard'] = [
'page_url',
'pageviews',
'visitors',
'my_custom_metric',
];

return $allow_list;
}
);

A new datatable ID also needs a row provider — register one via burst_datatable_pre_data to short-circuit the default SQL query and return rows directly.

subscriptions

Pro - BusinessAvailable in the Business tier

Requires the Business tier with an active subscriptions integration (WooCommerce Subscriptions, EDD Recurring or Subscriben). See the Business plan.

Returns the subscription summary cards (MRR, active/canceled subscriptions, revenue churn, average lifetime value) with current/previous period values and rate-of-change.

Response — data fields:

FieldTypeDescription
monthly_recurring_revenue{ label, currency, current, previous, rate_change }Current and previous MRR plus active subscription counts
active_subscriptions{ label, current, previous, rate_change }Active subscription totals
canceled_subscriptions{ label, current, previous, rate_change }Canceled subscription totals
revenue_churn{ label, current, previous, rate_change }Churn percentage, churned MRR and counts
average_lifetime_value{ label, currency, current, previous, rate_change }Average lifetime value with lifetime revenue totals
Show code
{
"data": {
"monthly_recurring_revenue": {
"label": "Monthly Recurring Revenue",
"currency": "USD",
"current": { "mrr": 2560.00, "count": 128 },
"previous": { "mrr": 2310.00, "count": 118 },
"rate_change": 10.82
},
"active_subscriptions": {
"label": "Active Subscriptions",
"current": 128,
"previous": 118,
"rate_change": 8.47
},
"revenue_churn": {
"label": "Revenue Churn",
"current": {
"churned_percentage": 2.15,
"churned_mrr": 49.99,
"count": 3,
"previously_active_count": 118
},
"previous": {
"churned_percentage": 1.84,
"churned_mrr": 42.50,
"count": 2
},
"rate_change": 16.85
}
},
"request_success": true,
"success": true
}

subscriptions-revenue-chart

Pro - BusinessAvailable in the Business tier

Requires the Business tier with an active subscriptions integration. See the Business plan.

Returns bucketed data for the new vs renewal subscriptions chart.

Extra parameters:

ParameterNotes
group_byBucket size. Accepts day, week, month or auto
chart_moderevenue (default) or sales to switch between revenue amounts and subscription counts

Response — data fields:

FieldTypeDescription
intervalstringResolved bucket interval (day, week or month)
spans_multiple_yearsboolWhether the range crosses a year boundary
modestringrevenue or sales, matching the request
currencystringBase store currency (only meaningful when mode is revenue)
rowsarrayBucketed rows with timestamp, label, newValue and renewalValue
Show code
{
"data": {
"interval": "day",
"spans_multiple_years": false,
"mode": "revenue",
"currency": "USD",
"rows": [
{ "timestamp": 1714521600, "label": "Apr 1", "newValue": 199.00, "renewalValue": 399.00 },
{ "timestamp": 1714608000, "label": "Apr 2", "newValue": 0.00, "renewalValue": 99.00 }
]
},
"request_success": true,
"success": true
}

subscriptions-distribution

Pro - BusinessAvailable in the Business tier

Requires the Business tier with an active subscriptions integration. See the Business plan.

Returns a distribution breakdown of subscription signups and renewals in the selected period.

Extra parameters:

ParameterNotes
distribution_viewOne of gateways (default), currencies or countries

Response — data is an indexed array of row objects:

FieldTypeDescription
idstringSanitized row identifier
labelstringHuman-readable label
countintNumber of events (signups + renewals) attributed to this row
valuefloatShare of the total, expressed as a percentage
Show code
{
"data": [
{ "id": "stripe", "label": "Stripe", "count": 140, "value": 68.29 },
{ "id": "paypal", "label": "PayPal", "count": 48, "value": 23.41 },
{ "id": "manual", "label": "Manual", "count": 17, "value": 8.30 }
],
"request_success": true,
"success": true
}

subscriptions-retention

Pro - BusinessAvailable in the Business tier

Requires the Business tier with an active subscriptions integration. See the Business plan.

Returns cohort retention data for subscription signups in the selected period.

Extra parameters:

ParameterNotes
product_idOptional product filter. Use 0 for all products

Response — data fields:

FieldTypeDescription
rowsarrayOne row per cohort with id, signup_count and a data array of retention points
productsarrayAvailable product filter options (id, label, is_yearly)
intervalstringCohort bucket unit (month, quarter or year)
max_offsetintMaximum offset index used across the cohorts
Show code
{
"data": {
"rows": [
{
"id": "Mar 2026 (42)",
"signup_count": 42,
"data": [
{ "x": "M+0", "y": 100, "count": 42 },
{ "x": "M+1", "y": 83.33, "count": 35 },
{ "x": "M+2", "y": 71.43, "count": 30 }
]
}
],
"products": [
{ "id": 42, "label": "Pro monthly", "is_yearly": false }
],
"interval": "month",
"max_offset": 2
},
"request_success": true,
"success": true
}

Abilities API

Added in v3.4.1.

The Abilities API exposes the most common read paths as WordPress abilities under the burst-statistics category. Use it from AI agents, automation tools or any client that consumes the WordPress abilities registry instead of calling REST routes directly. Abilities are read-only, rate-limited and resolve to the same data the REST endpoints return.

Prerequisites

  • WordPress build that ships the Abilities API (the wp_register_ability function must exist)
  • enable_abilities_api option turned on under Settings → Advanced (off by default)
  • Authenticated user with the manage_burst_statistics capability

When the Abilities API is unavailable or the option is off, no abilities are registered and existing REST endpoints are unaffected.

Rate limits

Each ability enforces a per-user rate limit of 30 calls per 60-second window. Adjust both via filters:

FilterDefaultDescription
burst_abilities_rate_limit_window60Window length in seconds
burst_abilities_rate_limit_max30Maximum calls allowed per window
Show code
add_filter(
'burst_abilities_rate_limit_max',
static function ( int $max, string $ability ): int {
return $ability === 'data' ? 60 : $max;
},
10,
2
);

Exceeding the limit returns burst_abilities_rate_limited with HTTP 429.

Available abilities

AbilityDescription
burst/live-visitorsCurrent live visitor count
burst/live-trafficRecent live traffic rows
burst/today-summarySummary metrics for a date range
burst/dataInsights time-series or datatable rows
burst/sales-dataEcommerce sales metrics (Burst Pro only)
burst/subscriptions-dataSubscription metrics (Burst Pro only)
burst/tasksCurrent Burst task list
burst/tracking-statusTracking transport status and last test time
burst/license-noticesLicense state and notices

All abilities are registered with show_in_rest = true and the read-only / non-destructive / idempotent annotations.

burst/live-visitors

Input: none

Output:

FieldTypeDescription
visitorsintCurrent live visitor count (clamped to 0 minimum)

burst/live-traffic

Input:

FieldTypeDefaultDescription
limitint100Number of rows to return, clamped to the range 1100

Output:

FieldTypeDescription
itemsarrayRows from the live traffic feed
totalintTotal number of rows available before the limit is applied

Each row in items:

FieldTypeDescription
uidstringAnonymous visitor identifier
page_urlstringURL of the page visited
timeintUnix timestamp of the hit
time_on_pageintSeconds spent on the page
active_timefloatActive (non-idle) seconds
entryboolWhether this is the session's entry page
checkoutboolWhether a checkout event was recorded
exitboolWhether this is the session's exit page

burst/today-summary

Input:

FieldTypeDefaultDescription
date_startintUnix timestamp marking the start of the period
date_endintUnix timestamp marking the end of the period

Output:

FieldTypeDescription
liveintCurrent live visitors
todayintUnique visitors for the period
most_viewed{ title, value }Top page title and view count
top_referrer{ title, value }Top referrer hostname and session count
pageviewsintTotal pageviews
avg_time_on_pageintAverage seconds on page

This is the agent-shaped equivalent of the REST today type. Field names use snake_case and numeric values are returned as integers, not formatted strings.

burst/data

Returns either an insights time-series or a datatable, depending on the type input.

Input:

FieldTypeDefaultDescription
typestringRequired. Either insights or datatable
datatable_idstringRequired when type is datatable. One of statistics_pages, statistics_parameters, statistics_referrers, sources_countries, sources_campaigns, sales_products, subscription_products or sources_referrers
date_startint0Unix timestamp for the start of the period
date_endint0Unix timestamp for the end of the period
intervalstringautoInsights-only bucket override. One of auto, hour, day, week or month
metricsstring[]["pageviews"]Metrics to retrieve. For datatable requests, values are intersected with the allow-list for datatable_id
filtersobject[][]Filter objects (only honoured for datatable)
group_bystring[]["page_url"]Grouping columns (only honoured for datatable)
limitint0 (no limit)Maximum number of rows returned

Changed in v3.4.2: datatable_id is now required for type=datatable and is validated against the registered datatable allow-list. Unknown values respond with burst_abilities_unknown_datatable (HTTP 404). The new interval field replaces group_by for insights — if interval is omitted, the first value of group_by is read as a backward-compatible interval hint. If no requested metric is valid for the chosen datatable, the ability falls back to the datatable's default metrics; if none of those resolve either, it responds with burst_abilities_invalid_metrics (HTTP 400).

utm_source is normalized to source in group_by.

Output — type=insights:

FieldTypeDescription
typestringAlways "insights"
intervalstringResolved bucket interval (hour, day, week, month or auto)
spans_multiple_yearsboolWhether the range crosses a year boundary
seriesarrayOne entry per requested metric with id, label and points
point_countintNumber of points per series

Each points entry has timestamp (int) and value (float).

Output — type=datatable:

FieldTypeDescription
typestringAlways "datatable"
dimensionsarrayOne entry per group_by column with id and label
metricsarrayOne entry per metric column with id and label
rowsarrayRow objects keyed by metric/dimension name
row_countintNumber of rows in rows

burst/sales-data and burst/subscriptions-data

Pro - BusinessAvailable in the Business tier

Both abilities require Burst Pro with an active ecommerce or subscriptions integration. They return burst_abilities_pro_required with HTTP 503 on Free installs. See Revenue and sales tracking.

Input:

FieldTypeDefaultDescription
date_startint0Unix timestamp for the start of the period
date_endint0Unix timestamp for the end of the period
metricsstring[]variesMetrics to retrieve. For burst/sales-data the default is ["product", "sales", "revenue"]; for burst/subscriptions-data it is ["plan", "active_subscribers", "canceled_subscribers", "trialling_subscribers", "monthly_recurring_revenue", "product_churn_value"]
filtersobject[][]Additional filter objects appended to the implicit purchase/subscription filter
group_bystring[]variesGrouping columns. Default for burst/sales-data is ["product"]; for burst/subscriptions-data it is ["plan"]
limitint100Maximum number of rows returned, clamped to the range 1500

Changed in v3.4.2: both abilities now accept filters and limit, target the sales_products and subscription_products granular datatables and enforce their metric allow-lists. Metrics outside the allow-list fall back to the defaults above.

Output: identical shape to burst/data with type=datatable.

burst/sales-data filters the result set to purchase events; burst/subscriptions-data filters to subscription events.

Error responses

Abilities return WP_Error objects which the WordPress REST layer translates to JSON with the matching HTTP status:

CodeHTTPWhen
burst_abilities_forbidden403User is not logged in or lacks manage_burst_statistics
burst_abilities_invalid_input400Required input is missing or has the wrong type
burst_abilities_invalid_metrics400No requested metric is valid for the chosen datatable, and no default metric resolves either
burst_abilities_unknown_datatable404datatable_id is not registered in the allow-list
burst_abilities_rate_limited429Per-user rate limit exceeded
burst_abilities_pro_required503Pro-only ability called on a Free install
burst_abilities_unavailable503Burst admin services failed to bootstrap
burst_abilities_execution_failed500Underlying data fetch threw an exception

Calling an ability

Show code
if ( ! function_exists( 'wp_get_ability' ) ) {
return;
}

$ability = wp_get_ability( 'burst/data' );
if ( ! $ability ) {
return;
}

$result = $ability->execute(
[
'type' => 'datatable',
'datatable_id' => 'statistics_pages',
'date_start' => strtotime( '2026-04-01 00:00:00' ),
'date_end' => strtotime( '2026-04-15 23:59:59' ),
'metrics' => [ 'pageviews', 'visitors' ],
'group_by' => [ 'page_url' ],
'limit' => 25,
]
);

if ( is_wp_error( $result ) ) {
// Inspect $result->get_error_code() / get_error_message().
return;
}

$rows = $result['rows'];

Code examples

Basic request with a date range

curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
"https://example.com/wp-json/burst/v1/data/today?date_start=2026-04-01&date_end=2026-04-15"

Granular datatable with filters

Show code
curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
--get "https://example.com/wp-json/burst/v1/data/datatable/statistics_pages" \
--data-urlencode "date_start=2026-04-01" \
--data-urlencode "date_end=2026-04-15" \
--data-urlencode "group_by=page_url" \
--data-urlencode "metrics[]=pageviews" \
--data-urlencode "metrics[]=visitors" \
--data-urlencode 'filters={"device":["desktop","mobile"],"country_code":"US"}'

Subscription products datatable

Show code
curl -u "wp_user:xxxx xxxx xxxx xxxx xxxx xxxx" \
--get "https://example.com/wp-json/burst/v1/data/ecommerce/datatable/subscription_products" \
--data-urlencode "date_start=2026-04-01" \
--data-urlencode "date_end=2026-04-15" \
--data-urlencode "metrics[]=plan" \
--data-urlencode "metrics[]=active_subscribers" \
--data-urlencode "metrics[]=monthly_recurring_revenue"

PHP request via wp_remote_get

Show code
$response = wp_remote_get(
add_query_arg(
[
'date_start' => '2026-04-01',
'date_end' => '2026-04-15',
'group_by' => 'page_url',
'metrics' => [ 'pageviews', 'visitors' ],
],
rest_url( 'burst/v1/data/datatable/statistics_pages' )
),
[
'headers' => [
'Authorization' => 'Basic ' . base64_encode( 'wp_user:xxxx xxxx xxxx xxxx xxxx xxxx' ),
],
'timeout' => 15,
]
);

if ( is_wp_error( $response ) ) {
// Handle connection error.
return;
}

$body = json_decode( wp_remote_retrieve_body( $response ), true );

if ( empty( $body['success'] ) ) {
// Handle API-level error.
return;
}

$rows = $body['data']['data'];

Troubleshooting

HTTP 401 — missing authentication Application Passwords require the WordPress REST API to be publicly accessible. If a security plugin blocks REST API access for unauthenticated users, allowlist the burst/v1 namespace or use nonce authentication from within WordPress.

HTTP 403 — Generic datatable endpoints are not allowed The generic data/datatable and data/ecommerce/datatable endpoints were removed in v3.4.2. Switch to data/datatable/{id} or data/ecommerce/datatable/{id} and pass the specific datatable ID in the path.

Requested metric is missing from the response Each granular datatable enforces an allow-list. Metrics that are not registered for the datatable are silently dropped before the SQL query runs. Inspect the metrics array returned in data.metrics to see which metrics were actually resolved, and use the burst_datatable_metric_allow_list filter to expose additional metrics.

Empty data array despite a valid date range Burst stores hits in a staging table and flushes them to the main statistics table on a cron schedule. Hits from the last few minutes may not yet appear. Live types (live-visitors, live-traffic) always reflect real-time data.

Subscription types return empty data Subscription endpoints require an active subscriptions integration and an up-to-date aggregation table. New installs backfill historical data in the background; until that completes, some periods may return zeroed counts. The insights response also changed shape in v3.4.0 — clients that still read labels should switch to timestamps + interval before upgrading.

Abilities API returns 404 or the abilities are not registered The Abilities API only registers when wp_register_ability is available and the enable_abilities_api option is on. Check Settings → Advanced and confirm WordPress core (or the Abilities API plugin) provides the registry function. If the option is hidden in the UI, the running WordPress build does not yet ship the Abilities API.

Abilities API returns 403 for a viewer user v3.4.2 raised the abilities permission requirement from view_burst_statistics to manage_burst_statistics. Use a user with the manage capability for ability calls, or fall back to the REST endpoints for read-only viewers.