Skip to main content

Third-party plugin integrations

Burst Statistics ships with built-in integrations for popular WordPress plugins. Each integration is loaded automatically when the corresponding plugin is detected. This document describes every supported integration, the goals each one provides, and how developers can register their own.


How integrations work

During plugin bootstrap (on plugins_loaded at priority 9) Burst iterates the integrations registry and checks whether each plugin is active by testing a constant, function, or class name. When a match is found, Burst loads the corresponding integration files from includes/Integrations/plugins/{plugin-slug}/. If the integration defines goals, those goals become available in the Goals UI.

Each integration is a directory containing one or more script files, split by execution context.

Detection versus enablement

Burst separates two questions with two dedicated methods on the Integrations class:

  • plugin_is_detected( array $details ) — is the plugin installed on this site? It tests the integration's constant_or_function (a constant, function, class, or theme name), ignoring any user setting.
  • is_integration_enabled( string $slug ) — has the site owner left the integration switched on? Every integration is enabled by default; it is disabled only when the enable_integration_{slug} option is explicitly set to a falsy value. When any of the integration's required_plugins parents are disabled, the child is treated as disabled too, so turning WooCommerce off cascades to WooCommerce Payments, WooCommerce Subscriptions and Subscriben without a separate write.

plugin_is_active( string $plugin ) combines both: the plugin must be installed, detected and enabled before its scripts and goals load.

Enabling and disabling integrations

Detected integrations are listed on the Settings → Integrations tab (registered by Integrations_Settings, spliced into the Settings menu immediately before Advanced). Each installed integration renders a row with a toggle backed by the enable_integration_{slug} option. Disabling a row stops that integration's scripts and goals from loading on the next request.

The per-integration option is a plain setting, so you can pre-configure it programmatically:

Show code
// Disable the Elementor integration without touching the plugin itself.
$options = get_option( 'burst_options_settings', [] );
$options['enable_integration_elementor'] = 0;
update_option( 'burst_options_settings', $options );

The installed-integration list is cached in the non-autoloaded burst_installed_integrations option and refreshed on admin_init, so the settings page can still render its rows on REST requests where other plugins are not loaded.

php_scripts schema

Integrations declare their PHP entry points via a php_scripts array with explicit admin_scripts and frontend_scripts keys. Burst loads admin scripts only when has_admin_access() is true and frontend scripts on all requests.

Show code
'php_scripts' => [
'admin_scripts' => [ 'admin.php' ],
'frontend_scripts' => [ 'frontend.php' ],
],

Each entry is a filename resolved relative to includes/Integrations/plugins/{plugin-slug}/. Dependent integrations (those with required_plugins) are loaded after their dependencies have been confirmed active.

Integrations without a php_scripts key are still detected for goal registration but no PHP files are loaded.

Registry metadata

Each integration definition can also carry presentation metadata used by the Integrations settings tab:

  • category — one of ecommerce, forms, page_builders, consent, performance or other
  • status — a stable status id describing what the integration does (e.g. tracks_sales_and_revenue), mapped to a translated label at display time
  • wporg_slug — the WordPress.org plugin slug used to fetch the plugin icon. Set it only for plugins that are actually hosted in the wp.org repository; premium-only plugins omit it so no icon request is fired and the settings tab falls back to a generic icon
  • wporg_icon — the icon file name on the wp.org CDN, for plugins whose icon is not the default icon-128x128.png (for example an icon-128x128.gif or icon-256x256.jpg variant)

Built-in integrations

Complianz GDPR/CCPA

Loaded from plugins/complianz/frontend.php. Registers Burst's tracking script with Complianz's blocked-scripts list so that consent is correctly requested and honoured.

  • When the WP Consent API (wp_has_consent) is present, Complianz defers entirely to it and the script-blocking logic is skipped.
  • When the privacy level is set to anything other than cookie, the script is never blocked regardless of consent state.
  • Any existing burst entry added by Complianz itself is removed and replaced with Burst's own entry to avoid duplicates.

Script categories registered: statistics Script URLs matched: assets/js/build/burst.js, assets/js/build/burst.min.js


Page builders

Elementor Website Builder

Goals available:

Goal IDTypeTrigger
elementor_pro_forms_form_submittedhookelementor_pro/forms/form_submitted
submit_button_clickclicks.elementor-field-type-submit .elementor-button

eCommerce plugins

WooCommerce

Loaded from plugins/woocommerce/frontend.php. Fires Burst's unified order and cart actions and resolves the checkout/products page IDs.

Goals available:

Goal IDTypeTrigger
woocommerce_add_to_carthookwoocommerce_add_to_cart
woocommerce_checkout_order_createdhookwoocommerce_checkout_order_created
woocommerce_payment_completehookwoocommerce_payment_complete
woocommerce_add_to_cart_clickclicks.add_to_cart_button
woocommerce_click_checkout_buttonclicks.wc-block-cart__submit-button

When an order is created (via the classic checkout or the Store API block checkout), Burst fires both burst_order_created and burst_woocommerce_order_created with a normalized data array. Cart changes (add, remove, restore, quantity update) fire burst_cart_updated.

WooCommerce Payments

Loaded from plugins/woocommerce-payments/frontend.php. Detected via WCPAY_PLUGIN_FILE. Requires WooCommerce to also be active. Applies the Stripe multi-currency exchange rate to WooCommerce order data via the burst_woocommerce_order_data filter.

WooCommerce Subscriptions

Detected via the WC_Subscriptions class. Requires WooCommerce to also be active. Loads plugins/woocommerce-subscriptions/admin.php on admin requests and plugins/woocommerce-subscriptions/event-listener.php on all requests.

The event listener translates WooCommerce Subscriptions lifecycle events (creation, status changes, renewals, date updates) into a single burst_subscription_update_today action so that the subscriptions aggregation engine can refresh today's numbers.

Pro - BusinessAvailable in the Business tier

Subscription integrations surface in the Subscriptions dashboard tab, which requires the Business tier. Learn more about revenue & sales tracking

Easy Digital Downloads

Loaded from plugins/easy-digital-downloads/frontend.php. Fires Burst's unified order and cart actions and resolves the checkout/products page IDs. Stripe-gateway orders are handled via edds_order_complete instead of edd_complete_purchase to avoid double-counting.

Goals available:

Goal IDTypeTrigger
edd_complete_purchasehookedd_complete_purchase
edd_add_to_cartclicks.edd-add-to-cart
edd_go_to_checkoutclicks.edd_go_to_checkout
edd_click_purchaseclicks#edd-purchase-button

Easy Digital Downloads Pro

Loaded from plugins/easy-digital-downloads-pro/frontend.php, which re-requires the core EDD integration file. The slug differs because EDD Pro is a separate plugin install that must be detected independently.

Easy Digital Downloads – Multi Currency

Loaded from plugins/edd-multi-currency/frontend.php. Detected via EDD_MULTI_CURRENCY_FILE. Requires Easy Digital Downloads to also be active. Applies the EDD multi-currency exchange rate to EDD order data via the burst_edd_order_data filter.

Easy Digital Downloads – Recurring Payments

Integration slug: edd-recurring. Loads both an admin and an event-listener file. Detected via EDD_RECURRING_VERSION. Requires Easy Digital Downloads to also be active.

Goals available:

Goal IDTypeTrigger
edd_subscription_post_createhookedd_subscription_post_create
edd_subscription_cancelledhookedd_subscription_cancelled

The event listener forwards subscription create, renew, cancel, expire, complete and status-change hooks to burst_subscription_update_today.

Subscriben

Detected via SUBSCRIBEN_VERSION. Requires WooCommerce to also be active. Loads plugins/subscriben/admin.php on admin requests and plugins/subscriben/event-listener.php on all requests. The event listener forwards Subscriben lifecycle events (meta save, payment applied, status change, renewal order created, failed payment) to burst_subscription_update_today.

Give – Donation Plugin

Goals available:

Goal IDTypeTrigger
give_click_donation_open_modalclicks.givewp-donation-form-modal__open
give_click_donationclicks.givewp-donation-form__steps-button-next
give_donation_hookhookgive_process_donation_after_validation

Contact form plugins

Contact Form 7

Goal IDTypeTrigger
wpcf7_submithookwpcf7_submit
wpcf7_submit_clickclicks.wpcf7-submit

WPForms

Goal IDTypeTrigger
wpforms_process_completehookwpforms_process_complete
wpforms_click_submitclicks.wpforms-submit

Fluent Forms

Goal IDTypeTrigger
fluentform_submission_insertedhookfluentform/submission_inserted
fluentforms_click_submitclicks.ff-btn-submit

Happyforms

Goal IDTypeTrigger
happyforms_submission_successhookhappyforms_submission_success

WS Form

Goal IDTypeTrigger
wsf_submithookwsf_submit

Gravity Forms

Goal IDTypeTrigger
gform_post_submissionhookgform_post_submission
gform_click_submitclicksinput[type="submit"].gform_button

Formidable Forms

Goal IDTypeTrigger
frm_submit_clickedclicks.frm_button_submit

Ninja Forms

Goal IDTypeTrigger
ninja_forms_after_submissionhookninja_forms_after_submission

Form submission tracking

Beyond the click and hook goals listed above, Burst Pro records full form submissions from supported form plugins into the burst_forms table and surfaces them in a dedicated Forms datatable on the Engagement tab. Each submission is linked to the visitor's most recent statistic so submissions can be attributed to a session.

ProAvailable in Burst Pro

Form submission tracking and the Forms datatable are a Burst Pro feature. Compare plans

Supported plugins and the hook each one listens on:

PluginProvider slugHook
Contact Form 7contact-form-7wpcf7_submit (only when status is mail_sent)
WPFormswpformswpforms_process_complete
Fluent Formsfluentformfluentform/submission_inserted
Happyformshappy-formshappyforms_submission_success
WS Formws-formwsf_submit_post_complete
Gravity Formsgravity_formsgform_after_submission
Ninja Formsninja-formsninja_forms_after_submission
Elementorelementorelementor_pro/forms/new_record

The Forms datatable reports submissions, the site-wide unique-visitor count used as the conversion denominator (returned under the pageviews key) and a conversion_rate, each with a previous-period comparison value (previous_submissions, previous_pageviews, previous_conversion_rate). The datatable id forms is registered with the view_burst_statistics capability, maps to the Engagement tab for shared-viewer access control and is also queryable through the burst/data ability.

Form-plugin tables (fluentform_forms, wsf_form, gf_form, nf3_forms, e_submissions) are added to Burst's table allowlist when the corresponding plugin is active, so form titles can be resolved for display.


Caching plugins

WP Rocket

Loaded from plugins/wp-rocket/frontend.php. Excludes Burst's inline JavaScript from WP Rocket's combine/minify pass and excludes timeme and burst JS files from minification. This prevents Burst's tracking code from being broken by asset optimization.

No goals are registered for this integration.


Remote-management integrations

MainWP

Exposes a single REST endpoint (burst/v1/mainwp-auth) that the MainWP dashboard calls during a full page load. The handler verifies the asymmetric signature sent by the dashboard, resolves the admin user named in the request, issues (or reuses) a WP Application Password for that user and returns the token, a REST root URL and the localization payload needed to bootstrap the dashboard React app.

Because the MainWP dashboard aggregates ecommerce and subscription data across child sites, any authenticated MainWP request forces Burst's eCommerce and subscription feature sets to load regardless of which integrations are detected on the child site. This guarantees the dashboard receives sales and subscription metrics even when the child site would not otherwise initialize those features. A MainWP request is identified through is_mainwp_request(), which requires the X-BURSTMAINWP: 1 header and a valid dashboard signature or Application Password.

The MainWP integration is opt-in. Set the enable_mainwp_integration option to true (under Settings → Advanced → Scripts) before the proxy will initialize. When the option is off, the MainWP_Proxy class is never constructed and no REST routes are registered.

update_option( 'burst_enable_mainwp_integration', true );

The enable_mainwp_integration settings field is rendered conditionally. When the MainWP Child plugin (mainwp-child/mainwp-child.php) is not present in WP_PLUGIN_DIR, the field type is forced to hidden so the toggle does not appear in the Burst UI. The option itself remains writable via update_option(), which lets headless or programmatic setups pre-enable the integration before MainWP Child is installed.

A setup-reminder task surfaces in the Burst dashboard when MainWP Child is active on the site but enable_mainwp_integration is empty. The condition is driven by Tasks::should_show_mainwp_integration_task(), which returns true only when all of the following hold:

  • The file WP_PLUGIN_DIR/mainwp-child/mainwp-child.php exists.
  • MainWP Child is active for the current site, or active network-wide on multisite.
  • burst_options_settings['enable_mainwp_integration'] is empty.

The task exposes burst_option_enable_mainwp_integration as its fix handler, so dismissing or actioning it enables the integration option. The task is dismissible.

if ( \Burst\Admin\Tasks::should_show_mainwp_integration_task() ) {
// MainWP Child is installed and active, but the Burst integration is off.
}

Security model:

  • The dashboard holds an RSA private key; the child site stores the matching public key in the mainwp_child_pubkey option.
  • Every request is signed over $function|$nonce|$user. Dashboards must sign the pipe-delimited triple.
  • Nonces are 32-character cryptographically random hex strings generated by the dashboard per request and consumed atomically server-side via add_option(). A second request reusing the same nonce is rejected even when the signature is still mathematically valid.
  • The dashboard must include a nonce_issued_at Unix timestamp alongside the nonce. Nonces older than 300 seconds (5 minutes) are rejected regardless of cryptographic validity, so captured request bodies cannot be replayed once the window closes. Consumed nonce records are purged via a scheduled burst_purge_mainwp_nonce event shortly after the TTL expires.
  • Requests authenticated via the dashboard path must send the X-BURSTMAINWP: 1 header. The custom header forces a CORS preflight that a cross-origin browser request cannot pass without an explicit allow, providing structural CSRF protection for the dashboard call. Cookie-authenticated admins calling the same endpoint must instead present a valid burst_nonce, and Application Password / HTTP Basic Auth callers are admitted on the credential alone.
  • Application Passwords issued for this integration are named Burst MainWP and the plain-text token is cached for one hour via a transient — the token itself is never stored long-term.

No goals are registered. Integrators that want to gate REST routes for the MainWP dashboard can call MainWP_Proxy::is_mainwp_authenticated() inside a permission_callback.


Smart update timing

Burst can time WordPress plugin updates to your quietest traffic period. A weekly cron scans the last 28 days of statistics, finds the four-hour window with the fewest distinct visitors and stores its start hour (site timezone) in the autoloaded burst_low_traffic_time option. Two independent toggles on the Settings → Integrations → Smart update timing tab drive the feature; both are plain settings, so you can pre-configure them programmatically.

OptionTypeDefaultDescription
plugin_update_suggestionsbooltrueAdds a timing hint to every available-update notice on the Plugins screen, telling the admin whether now is a quiet moment or how many hours remain until the low-traffic window, with the current live-visitor count polled every 20 seconds
plugin_update_schedulingboolfalseReschedules plugins that already have WordPress auto-updates enabled so they run during the low-traffic window; it never enables auto-updates for a plugin that did not already have them on
Show code
$options = get_option( 'burst_options_settings', [] );
$options['plugin_update_suggestions'] = 1;
$options['plugin_update_scheduling'] = 1;
update_option( 'burst_options_settings', $options );

With scheduling off, admins can still opt individual plugins in from the auto-updates column on the Plugins screen; those opt-ins are stored in the autoloaded burst_low_traffic_auto_update_plugins option. An hourly check (burst_every_hour) triggers the WordPress auto-updater once per day inside the window, and the auto_update_plugin filter confines the managed plugins' automatic updates to that window. Enabling either toggle schedules the initial window calculation if it never ran, so the timing hints have data on their first render.

burst_low_traffic_window_start

Filters the start hour (0–23, site timezone) of the low-traffic window before any consumer reads it. The timing hints, the auto_update_plugin filter and the daily trigger scheduling all resolve the window through this filter, so it shifts the whole feature coherently. Use it to pin or shift the window without waiting for the weekly recalculation, for example from a staging snippet.

Parameters:

ParameterTypeDescription
$start_hourintThe calculated window start hour, 0–23 in the site timezone.

Example:

Show code
// Shift the detected window earlier by 17 hours, wrapping around midnight.
add_filter( 'burst_low_traffic_window_start', function( int $start_hour ): int {
return ( $start_hour - 17 + 24 ) % 24;
} );

Google Search Console

Burst can connect to Google Search Console and show search-query data (queries, clicks, impressions, click-through rate and average position) alongside your on-site statistics. The connection uses a PKCE OAuth flow brokered by the Burst relay, so no client secret ever touches your site, and all query data is stored locally in the burst_search_terms table and read from there — the Search Console API is never called on dashboard load.

Prerequisites

  • A Google account with access to the Search Console property for this site
  • The enable_search_console option switched on
  • Outbound HTTPS to the Burst relay for the OAuth handshake and token refresh

Enabling

Toggle "Enable Google Search Console" in the Search Console group on the Settings → Integrations tab, or set the option programmatically:

update_option( 'burst_enable_search_console', true );

When the option is off, no Search Console code runs: the connect/disconnect/status actions are not registered and the daily sync does not schedule. The enable toggle and connect field are always registered so the settings form's field set stays constant across saves; the connect UI only becomes visible once the option is actually saved on.

How the connection works

The connect action mints a PKCE verifier and a single-use CSRF nonce, stores them server-side for five minutes, and opens the relay's /start endpoint in a popup. Google redirects back to admin-post.php?action=burst_gsc_callback, where Burst verifies the nonce, exchanges the authorization code for tokens through the relay, and fires the burst_gsc_connected action. The callback is wired up for every admin request (not behind the capability gate) because the popup returns without the login cookie as its only trust anchor; the handler still requires manage_burst_statistics on top of the OAuth nonce.

Both the access and refresh tokens are encrypted at rest with libsodium in the non-autoloaded burst_gsc_tokens option and never exposed to the browser — only the connection state (connected, disconnected, needs-reconnect) is. The encryption key is derived from BURST_GSC_ENCRYPTION_KEY when defined, otherwise from AUTH_KEY, falling back to the auth salt with a logged warning.

How the sync works

The sync is hooked to burst_every_hour. It resolves the Search Console property that matches your site URL, then backfills history (from the plugin install date, capped at Search Console's ~16-month retention) a chunk of days per hourly run. Once caught up it pulls only the latest missing day, at most once per day. Search Console data lags roughly two days, so the most recent day requested is always today minus two.

Each day is stored idempotently per property: a re-sync deletes that day's rows for the property and re-inserts the full result set, so repeated runs never duplicate.

wp-config constants

ConstantPurpose
BURST_GSC_SITE_URLOverrides home_url() as the site matched against the account's properties, so a local or staging install can fetch data for the real site
BURST_GSC_ENCRYPTION_KEYDedicated 32-byte secret used to encrypt the stored tokens; preferred over AUTH_KEY
BURST_GSC_RELAY_URLOverrides the relay base URL for testing against a local relay

Search Console datatable

The stored terms are exposed as the read-only search_console datatable, registered through App::get_datatable_config() with the view_burst_statistics capability and mapped to the sources tab for shared-viewer access control. Rows come from burst_search_terms for the matched property over the requested range: clicks and impressions are summed, click-through rate is recomputed from the summed totals as a percentage, and position is the impression-weighted average.

burst_gsc_connected (action)

Fired once the OAuth code exchange succeeds and tokens are stored. The sync listens on it to resolve the matching property and schedule a near-immediate first fetch.

Example:

add_action( 'burst_gsc_connected', function (): void {
// React to a successful Search Console connection.
} );

Database table schema

burst_sessions

The following columns on burst_sessions are the authoritative source for per-session device and visitor attributes.

ColumnTypeDefaultDescription
browser_idint0Foreign key into burst_browsers.
browser_version_idint0Foreign key into browser versions lookup.
platform_idint0Foreign key into burst_platforms.
device_idint0Foreign key into burst_devices.
first_time_visittinyint01 if this is the visitor's first ever session.
bouncetinyint11 if the session contained only one pageview.

Indexes are created for browser_id, platform_id, device_id, first_time_visit, and bounce.

burst_statistics

The columns browser_id, browser_version_id, platform_id, device_id, first_time_visit, and bounce are not stored on burst_statistics. Custom queries that need these values must join burst_sessions on burst_statistics.session_id = burst_sessions.ID.

Show code
$wpdb->get_results(
$wpdb->prepare(
"SELECT sess.browser_id, sess.device_id, sess.first_time_visit, sess.bounce
FROM {$wpdb->prefix}burst_statistics AS st
INNER JOIN {$wpdb->prefix}burst_sessions AS sess ON st.session_id = sess.ID
WHERE st.time > %d",
$start
)
);

The INSERT statement for new pageviews does not include first_time_visit, bounce, browser_id, browser_version_id, platform_id, or device_id. These values are written exclusively to burst_sessions at session-creation time.

Archive / restore (Burst Pro)

Pro - CreatorAvailable in the Creator tier

The archive export (Archive_Pro) joins burst_sessions when building the CSV so that the session-level columns (browser_id, browser_version_id, platform_id, device_id, first_time_visit, bounce, referrer) are preserved alongside each statistics row.

On restore, those session columns are split out from the CSV and applied to the corresponding burst_sessions row via UPDATE. If the session row no longer exists it is re-created via INSERT. Learn more about data management


Filters and actions reference

burst_integrations

Filters the complete integrations registry before Burst processes it. Use this to add, remove, or modify integrations.

Parameters:

ParameterTypeDescription
$integrationsarray<string, array>Associative array of integrations keyed by plugin slug.

Example:

Show code
add_filter( 'burst_integrations', function( array $integrations ): array {
$integrations['my-plugin'] = [
'constant_or_function' => 'MY_PLUGIN_VERSION',
'label' => 'My Plugin',
'category' => 'forms',
'status' => 'tracks_form_submissions',
'php_scripts' => [
'admin_scripts' => [],
'frontend_scripts' => [ 'frontend.php' ],
],
'goals' => [
[
'id' => 'my_form_submitted',
'type' => 'hook',
'hook' => 'my_plugin_form_submitted',
],
],
];
return $integrations;
} );

burst_integration_path

Filters the file path Burst resolves for an integration before requiring it. Useful when shipping an integration file in your own plugin.

The resolved path points to a specific file inside the plugin directory (for example plugins/my-plugin/frontend.php). Custom callbacks must return the correct per-script path.

Parameters:

ParameterTypeDescription
$pathstringAbsolute path to the integration PHP file.
$pluginstringThe plugin slug being loaded.

Example:

Show code
add_filter( 'burst_integration_path', function( string $path, string $plugin ): string {
if ( 'my-plugin' === $plugin ) {
return plugin_dir_path( __FILE__ ) . 'integrations/burst-my-plugin.php';
}
return $path;
}, 10, 2 );

burst_rest_api_optimizer_keep_plugins

Filters which plugins stay active while Burst serves an optimized REST request. The REST API optimizer disables most plugins during Burst's own REST calls for performance; plugins returned here are exempted. The value is an array with two keys: partial_match (a plugin is kept when its path contains the given substring) and exact_match (a plugin is kept only when its basename matches exactly).

Parameters:

ParameterTypeDescription
$plugins_to_keeparray{partial_match: string[], exact_match: string[]}Plugins to keep active, grouped by matching strategy.

Default partial_match entries:

  • all-in-one-wp-security-and-firewall — AIOS dynamically changes salts, which breaks nonces
  • permalink-manager-for-woocommerce — excluding Permalink Manager can cause 404 pages
  • ai-provider-for-

Default exact_match entries:

  • ai/ai.php
  • ai-provider-for-anthropic/plugin.php
  • ai-provider-for-google/plugin.php
  • ai-provider-for-openai/plugin.php

Example:

Show code
add_filter( 'burst_rest_api_optimizer_keep_plugins', function( array $plugins_to_keep ): array {
// Keep a custom plugin active during optimized Burst REST requests.
$plugins_to_keep['exact_match'][] = 'my-plugin/my-plugin.php';
return $plugins_to_keep;
} );

burst_load_ecommerce_integration

Filters whether Burst should activate its eCommerce feature set. By default this returns true when any integration that has load_ecommerce_integration => true is active. Authenticated MainWP requests always enable the eCommerce feature set regardless of this default detection, so the MainWP dashboard can read sales metrics from the child site.

Parameters:

ParameterTypeDescription
$should_loadbooltrue to enable eCommerce features, false to disable.

Example:

add_filter( 'burst_load_ecommerce_integration', '__return_true' );

The combined tracking JS file bakes a should_load_ecommerce flag whose value depends on which eCommerce plugin is active, so the file must be regenerated whenever an eCommerce integration plugin is activated or deactivated. Burst detects the change with \Burst\burst_loader()->integrations->is_ecommerce_integration_plugin( $plugin_file ), which returns true when the (de)activated plugin file maps to an integration whose registry entry sets load_ecommerce_integration => true. On a match Burst schedules a single burst_create_js_file cron event ten seconds later, so the file is rebuilt from the settled plugin state rather than the stale in-request state.


burst_subscription_integrations_enabled

Filters whether Burst should treat at least one subscription integration as active. WooCommerce Subscriptions, EDD Recurring and Subscriben all return true from their admin-side integration files, which enables the Subscriptions dashboard tab and the subscription aggregation engine. Authenticated MainWP requests always treat subscription integrations as active so the dashboard can read subscription metrics from the child site.

Parameters:

ParameterTypeDescription
$enabledbooltrue when at least one subscription integration is active. Defaults to false.

Example:

add_filter( 'burst_subscription_integrations_enabled', '__return_true' );

The companion helper \Burst\burst_loader()->integrations->has_subscription_integrations_enabled() returns the filtered value and is the canonical way to check for active subscription integrations from your own code.


burst_abilities_rate_limit_window

Filters the rate-limit window (in seconds) used by the WordPress Abilities API integration. Defaults to 60.

Parameters:

ParameterTypeDescription
$windowintLength of the rate-limit window in seconds.
$abilitystringAbility name without the burst/ prefix, e.g. 'live-visitors'.

Example:

add_filter( 'burst_abilities_rate_limit_window', function( int $window, string $ability ): int {
return $ability === 'live-traffic' ? 30 : $window;
}, 10, 2 );

burst_abilities_rate_limit_max

Filters the maximum number of ability calls allowed per rate-limit window. Defaults to 30.

Parameters:

ParameterTypeDescription
$maxintMaximum number of calls allowed in the current window.
$abilitystringAbility name without the burst/ prefix.

Example:

add_filter( 'burst_abilities_rate_limit_max', function( int $max, string $ability ): int {
return $ability === 'data' ? 10 : $max;
}, 10, 2 );

burst_checkout_page_id

Filters the page ID Burst treats as the checkout page. WooCommerce and EDD both hook into this to return their configured checkout page.

Parameters:

ParameterTypeDescription
$page_idintThe current checkout page ID.

Example:

add_filter( 'burst_checkout_page_id', function( int $page_id ): int {
return (int) get_option( 'my_plugin_checkout_page_id', $page_id );
} );

burst_products_page_id

Filters the page ID Burst treats as the main products/shop page. WooCommerce and EDD both hook into this to return their configured shop page.

Parameters:

ParameterTypeDescription
$page_idintThe current products page ID.

Example:

add_filter( 'burst_products_page_id', function( int $page_id ): int {
return (int) get_option( 'my_plugin_shop_page_id', $page_id );
} );

burst_base_currency

Filters the store's base currency code. WooCommerce returns get_woocommerce_currency(); EDD returns edd_get_currency(). Both also invalidate a burst_base_currency transient when their currency option changes.

Parameters:

ParameterTypeDescription
$currencystringISO 4217 currency code, e.g. 'USD'.

Example:

add_filter( 'burst_base_currency', function( string $currency ): string {
return 'EUR';
} );

burst_woocommerce_order_data

Filters the normalized order data array before Burst fires burst_order_created for a WooCommerce order.

Parameters:

ParameterTypeDescription
$dataarrayNormalized order data (see structure below).
$orderWC_OrderThe WooCommerce order object.

$data structure:

KeyTypeDescription
currencystringISO 4217 currency code.
totalfloatOrder subtotal before tax.
taxfloatTotal tax amount.
platformstringAlways 'WC'.
productsarrayArray of {product_id, amount, price} entries.

Example:

Show code
add_filter( 'burst_woocommerce_order_data', function( array $data, WC_Order $order ): array {
$data['custom_field'] = $order->get_meta( '_my_field' );
return $data;
}, 10, 2 );

burst_edd_order_data

Filters the normalized order data array before Burst fires burst_order_created for an Easy Digital Downloads order.

Parameters:

ParameterTypeDescription
$dataarrayNormalized order data (see structure below).
$order_idintThe EDD payment/order ID.
$paymentEDD_PaymentThe EDD payment object.

$data structure:

KeyTypeDescription
currencystringISO 4217 currency code.
totalfloatOrder subtotal before tax.
taxfloatTotal tax amount.
platformstringAlways 'EDD'.
productsarrayArray of {product_id, amount, price} entries.

Example:

Show code
add_filter( 'burst_edd_order_data', function( array $data, int $order_id, EDD_Payment $payment ): array {
$data['license_key'] = get_post_meta( $order_id, '_license_key', true );
return $data;
}, 10, 3 );

burst_order_created (action)

Fired whenever any supported eCommerce plugin creates a completed order. Both WooCommerce and EDD fire this action with the same normalized structure, making it platform-agnostic.

Parameters:

ParameterTypeDescription
$dataarrayNormalized order data. See burst_woocommerce_order_data / burst_edd_order_data for the full structure.

Example:

Show code
add_action( 'burst_order_created', function( array $data ): void {
// $data['platform'] is 'WC' or 'EDD'.
error_log( 'Order created. Total: ' . $data['total'] . ' ' . $data['currency'] );
} );

burst_woocommerce_order_created (action)

Fired specifically when a WooCommerce order is created, in addition to burst_order_created. Provides the same $data array.

Parameters:

ParameterTypeDescription
$dataarrayNormalized WooCommerce order data.

Example:

add_action( 'burst_woocommerce_order_created', function( array $data ): void {
// WooCommerce-specific handling.
} );

burst_edd_order_created (action)

Fired specifically when an Easy Digital Downloads order is created, in addition to burst_order_created. Provides the same $data array.

Parameters:

ParameterTypeDescription
$dataarrayNormalized EDD order data.

Example:

add_action( 'burst_edd_order_created', function( array $data ): void {
// EDD-specific handling.
} );

burst_cart_updated (action)

Fired when the cart changes in any supported eCommerce plugin (item added, removed, restored, or quantity updated). Both WooCommerce and EDD fire this action.

Parameters:

ParameterTypeDescription
$dataarrayCart data containing an items key.

$data['items'] entries:

KeyTypeDescription
product_idintProduct or download ID.
quantityintCurrent quantity in cart.
pricefloatUnit price excluding tax.
added_atstringMySQL timestamp of when the item was added (EDD only).

Example:

Show code
add_action( 'burst_cart_updated', function( array $data ): void {
foreach ( $data['items'] as $item ) {
error_log( 'Cart item: product #' . $item['product_id'] . ' qty ' . $item['quantity'] );
}
} );

burst_subscription_update_today (action)

Fired by the subscription integration event listeners (WooCommerce Subscriptions, EDD Recurring, Subscriben) whenever a subscription lifecycle event occurs. Burst Pro listens to this action to refresh today's subscription aggregates through a debounced cron event.

Parameters:

ParameterTypeDescription
$plugin_sourcestringIntegration identifier, e.g. 'woocommerce_subscriptions', 'edd_recurring', 'subscriben'.

Example:

Show code
add_action( 'burst_subscription_update_today', function( string $plugin_source ): void {
// Invalidate your own subscription cache when Burst detects a change.
wp_cache_delete( 'my_subscription_summary_' . $plugin_source );
} );

Adding a custom integration

Step 1 — register the integration

Use the burst_integrations filter to add your plugin to the registry.

Show code
add_filter( 'burst_integrations', function( array $integrations ): array {
$integrations['my-crm'] = [
// Required. A constant, function, or class name that indicates the plugin is active.
'constant_or_function' => 'MY_CRM_VERSION',

// Required. Human-readable label shown in the Burst UI.
'label' => 'My CRM Plugin',

// Optional. Category and status id shown on the Integrations settings tab.
'category' => 'other',
'status' => 'tracks_form_submissions',

// Optional. Per-context script filenames.
'php_scripts' => [
'admin_scripts' => [ 'admin.php' ],
'frontend_scripts' => [ 'frontend.php' ],
],

// Optional. Load Burst's eCommerce feature set when this integration is active.
'load_ecommerce_integration' => false,

// Optional. Other integration slugs that must also be active.
'required_plugins' => [],

// Optional. Goals this integration contributes.
'goals' => [
[
// Unique goal identifier.
'id' => 'my_crm_form_submitted',
// 'hook' goals fire when a WordPress action fires server-side.
'type' => 'hook',
'hook' => 'my_crm_form_submitted',
],
[
'id' => 'my_crm_submit_click',
// 'clicks' goals fire when the user clicks a matching DOM element.
'type' => 'clicks',
'selector' => '.my-crm-submit',
],
],
];

return $integrations;
} );

Step 2 — provide integration files (optional)

If your integration needs to run custom PHP (e.g. to hook into server-side events), ship one file per execution context and point Burst to the directory with burst_integration_path:

Show code
add_filter( 'burst_integration_path', function( string $path, string $plugin ): string {
if ( 'my-crm' === $plugin ) {
// $path ends in the requested script filename, e.g. 'admin.php' or 'frontend.php'.
return plugin_dir_path( __FILE__ ) . 'integrations/my-crm/' . basename( $path );
}
return $path;
}, 10, 2 );

Each file is included with require_once during plugin bootstrap (plugins_loaded priority 9) when the plugin is detected as active. Admin scripts only load when the current user can manage Burst; frontend scripts load on every request. No class structure is required — add your hooks directly.

Integration registry schema

KeyTypeRequiredDescription
constant_or_functionstringYesConstant name, function name, or class name used to detect whether the plugin is active.
labelstringYesDisplay label shown in the Burst dashboard.
categorystringNoOne of ecommerce, forms, page_builders, consent, performance or other. Used for grouping on the Integrations settings tab.
statusstringNoStable status id describing what the integration does, mapped to a translated label at display time.
wporg_slugstringNoWordPress.org plugin slug used to fetch the plugin icon. Set it only for plugins hosted on wp.org; premium-only plugins omit it, so no icon request is made and the settings tab falls back to a generic icon.
wporg_iconstringNoIcon file name on the wp.org CDN, for plugins whose icon is not the default icon-128x128.png (for example icon-128x128.gif or icon-256x256.jpg).
php_scriptsarrayNoPer-context script filenames resolved inside includes/Integrations/plugins/{plugin-slug}/. See schema below.
load_ecommerce_integrationboolNoWhen true and the plugin is active, Burst's eCommerce feature set is enabled. Default false.
required_pluginsstring[]NoIntegration slugs (keys in the registry) that must also be active for this integration to load. Disabling a listed parent cascades to this integration.
goalsarrayNoGoals made available in the Goals UI. See goal schema below.

php_scripts schema:

KeyTypeDescription
admin_scriptsstring[]Filenames loaded only when has_admin_access() is true.
frontend_scriptsstring[]Filenames loaded on every request where the detected plugin is active.

Goal schema

KeyTypeRequiredDescription
idstringYesUnique identifier for the goal.
typestringYesEither 'hook' (server-side WordPress action) or 'clicks' (client-side DOM click).
hookstringYes (hook type)The WordPress action hook name to listen on.
selectorstringYes (clicks type)CSS selector for the element whose clicks trigger the goal.
caution

Goals must be triggerable by the site visitor (i.e. they must fire during a normal page request or user interaction). Goals that fire only during background processes or WP-CLI commands cannot be attributed to a visitor session and will not be recorded.


Burst registers itself with the WP Consent API during Integrations::init() via the wp_consent_api_registered_{plugin} filter. When the WP Consent API is present, all consent routing is handled by it and plugin-specific consent bridges (e.g. the Complianz script-blocking logic) are bypassed automatically.

When the WP Consent API or Complianz is active, Burst surfaces a dismissible task in the dashboard warning that a cookie banner configured to request consent for the statistics category will stop Burst from tracking any visitor who has not been flagged as having statistics consent. The condition is driven by Tasks::is_wp_consent_api_active(), which returns true when any of the following hold:

  • The WP_Consent_API class exists
  • The CMPLZ_VERSION constant is defined
  • The cmplz_version constant is defined

The task links to the WP Consent API integration documentation, raises a plusone counter and is dismissible.

if ( \Burst\Admin\Tasks::is_wp_consent_api_active() ) {
// WP Consent API or Complianz is active; a cookie banner may gate tracking by consent.
}

WordPress Abilities API

Burst registers a burst-statistics ability category and a set of read-only abilities for use with AI agents and automation tools that consume the WordPress Abilities API. The integration is opt-in and exposes only data the calling user is already allowed to view through the Burst dashboard.

Prerequisites

  • WordPress with the Abilities API available (wp_register_ability function present)
  • The enable_abilities_api Burst option set to true
  • A logged-in user with the view_burst_statistics capability — anonymous and lower-privileged callers receive burst_abilities_forbidden (HTTP 403)

Enabling

The integration is disabled by default. Toggle "Enable Abilities API (for AI agents and automation)" under Settings → Advanced → Scripts, or set the option programmatically:

update_option( 'burst_enable_abilities_api', true );

When the option is off, no category or abilities are registered, and the action hooks are never attached.

Registered abilities

Every ability is registered in the burst-statistics category, declared readonly, idempotent, and non-destructive, and gated by a per-user, per-ability rate limit (default 30 calls per 60-second window).

AbilityDescription
burst/live-visitorsCurrent number of live visitors
burst/live-trafficActive visitors and pages from the live traffic feed; accepts an optional limit (1–100)
burst/today-summaryToday's live, pageviews, top page, top referrer and average time on page; accepts optional date_start and date_end Unix timestamps
burst/tasksCurrent Burst task list with id, label, status, icon and optional URL
burst/tracking-statusTracking transport status and last test timestamp
burst/license-noticesLicense state and notices for Burst Pro; returns license_status: "unavailable" when Burst Pro is not installed
burst/dataInsights timeseries or datatable rows for arbitrary metrics, filters, group_by and limit. Requires a type of "insights" or "datatable"
burst/sales-dataEcommerce sales metrics (Burst Pro only)
burst/subscriptions-dataEcommerce subscriptions metrics (Burst Pro only)

Pro-only abilities return a burst_abilities_pro_required error with HTTP 503 when called from Burst free.

Pro - BusinessAvailable in the Business tier

The burst/sales-data and burst/subscriptions-data abilities surface ecommerce metrics that require the Business tier. Learn more about revenue & sales tracking

Error codes

CodeHTTP statusMeaning
burst_abilities_forbidden403Caller lacks the Burst view capability or is unauthenticated
burst_abilities_invalid_input400The input payload failed validation (wrong type, missing required type parameter, etc.)
burst_abilities_rate_limited429Per-user rate limit exceeded for this ability
burst_abilities_pro_required503Ability requires Burst Pro and the constant BURST_PRO is not defined
burst_abilities_unavailable503Burst admin services could not be bootstrapped for this request
burst_abilities_execution_failed500The underlying statistics call threw an exception

Adjusting rate limits

Both the window length and the call ceiling are filterable per ability. See burst_abilities_rate_limit_window and burst_abilities_rate_limit_max in the filters reference above.

AI chat availability

The Burst dashboard can surface an AI chat that runs on top of the abilities above. The chat is reported as available only when every one of the following holds:

  • The Abilities API is enabled (enable_abilities_api)
  • The WordPress AI plugin is installed and active. Burst checks both runtime signals (the AI client classes/functions are loaded) and the plugin's active state in active_plugins, or in the network-activated plugins on multisite. The plugin basename defaults to ai/ai.php and falls back to WPAI_PLUGIN_FILE when that constant is defined
  • At least one AI provider connector has an API key configured
  • When the WordPress AI connector-approval feature is enabled (wpai_features_enabled and wpai_feature_connector-approval_enabled), Burst, the WordPress AI plugin and the active provider connector must each be approved for that provider

Burst exposes these signals as raw flags through Abilities_Api::get_chat_availability() so the dashboard assembles the user-facing message itself.

FlagTypeDescription
enabledbooltrue only when chat is fully available.
abilities_enabledboolThe enable_abilities_api option state.
ai_client_loadedboolThe WordPress AI plugin is active and its client is loaded.
has_configured_providerboolAt least one provider has an API key present.
missing_approvalsstring[]Names of callers still awaiting connector approval, e.g. Burst, WordPress AI, OpenAI Provider.

Burst never loads provider plugin files itself. It registers only the provider classes already in memory (AnthropicProvider, OpenAiProvider, GoogleProvider), so installing and activating the relevant provider plugin is what makes a provider available.

When the REST API optimizer is active, the WordPress AI plugin (ai/ai.php) and the AI provider connector plugins (ai-provider-for-anthropic, ai-provider-for-google, ai-provider-for-openai) are kept active during Burst REST requests so that chat availability is evaluated correctly. The optimizer matches the AI plugin and its connectors through both partial and exact matching: any plugin path containing ai-provider-for- is matched partially, while the AI plugin itself and each named provider connector are matched exactly. Without them, the AI client would appear unloaded during the optimized REST call and chat would be reported as unavailable. The keep list is filterable through burst_rest_api_optimizer_keep_plugins (see the filters reference above).