Skip to main content

Share links

Pro - CreatorAvailable in the Creator tier

The share link system is only available in Burst Pro.

Share links allow read-only, password-free access to the Burst dashboard for external viewers. A share token is created by an admin, embedded in a path-based URL (/burst-dashboard/{tab}/?burst_share_token={token}), and the recipient opens the dashboard without logging in.

Internally, the system logs in a system user (burst_statistics_viewer) with the burst_viewer role for the duration of the session. REST requests from that session send the token via the X-Burst-Share-Token header.

Share link operations are surfaced through the generic do_action and get_action endpoints.

:::caution Breaking change Changed in v3.4.2: share link URLs moved from hash-based (/burst-dashboard/?burst_share_token={token}#/statistics) to path-based (/burst-dashboard/statistics/?burst_share_token={token}). Old hash-based URLs continue to work — the plugin serves a minimal upgrader page that reads the legacy hash fragment in the browser and redirects to the new path-based equivalent. Newly created tokens always return path-based URLs. :::

Token format

32-character lowercase hexadecimal, generated as bin2hex( random_bytes( 16 ) ). Any value not matching /^[a-f0-9]{32}$/ is rejected without further processing.

Shareable tabs

The list of tab IDs that may appear in shared_tabs is restricted by an internal whitelist:

Tab IDNotes
statisticsFree + Pro
sourcesPro
salesPro (Business tier)
storyReserved for report share links — assigned automatically when report_id > 0. Not selectable through shared_tabs

:::caution Breaking change Changed in v3.4.2: dashboard and subscriptions were removed from the shareable tab whitelist. Any value passed in shared_tabs that is not in the whitelist above is silently dropped during sanitization. Update existing client code that previously requested those tabs. :::

REST operations

Create or renew a token

Action: do_action/get_share_token Permission: manage_burst_statistics

Body parameters:

ParameterTypeDefaultDescription
expirationstring7dToken lifetime: never, 24h, 7d or 30d
view_urlstring''Dashboard URL the share link should open. The path segment determines the initial tab; any legacy hash fragment is parsed and converted to query parameters
permissionsobject{}Permission flags — filtered via burst_share_permissions. Valid keys: can_change_date, can_filter
shared_tabsarray[]Tab IDs to expose: statistics, sources, sales. Other values are dropped during sanitization
initial_stateobject{}Pre-selected state: date_range.start, date_range.end, filters (key/value pairs)
report_idint0Attach the token to a specific report. Reuses an existing token for the same report ID if one exists

Changed in v3.4.2: view_url is now interpreted as a path-based dashboard URL. Legacy hash routes in the form #/{tab}?{params} are still accepted — the tab segment is moved to the URL path and any query parameters are merged into the real query string of the generated share URL.

Response:

Show code
{
"share_token": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"share_url": "https://example.com/burst-dashboard/statistics/?burst_share_token=a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
}

Revoke a token

Action: do_action/revoke_share_link Permission: manage_burst_statistics

Body parameters:

ParameterTypeDescription
tokenstringThe 32-character hex token to revoke

Response:

Show code
{
"success": true,
"share_links": []
}

List active tokens

Action: do_action/list_share_links Permission: manage_burst_statistics

:::caution Breaking change Changed in v3.4.1: this operation moved from get_action/get_share_links to do_action/list_share_links. The burst_get_action handler for share links was removed and the lookup is now performed inside do_rest_action. Update any custom client code calling the previous endpoint. :::

Returns all active (non-expired) share links and the list of shareable dashboard tabs.

Response:

Show code
{
"share_links": [
{
"token": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"url": "https://example.com/burst-dashboard/statistics/?burst_share_token=a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"expires": 1712000000,
"created": 1711913600,
"report_id": 0,
"permissions": { "can_change_date": false, "can_filter": false },
"shared_tabs": ["statistics"],
"initial_state": { "date_range": { "start": "", "end": "" }, "filters": {} }
}
],
"shareable_tabs": [
{ "id": "statistics", "title": "Statistics" }
]
}

The share_links array is always sequentially indexed — filtered results are reindexed before being returned, so JSON encoders emit a true array rather than an object.

When a token is created with a non-zero report_id, the generated share URL targets the dedicated story route (/burst-dashboard/story/?burst_share_token={token}) and the corresponding report's to_array() response is scoped to fields safe for external viewers. Scheduling and recipient metadata are withheld.

Changed in v3.4.2: report share URLs use the path-based /burst-dashboard/story/ route instead of the legacy hash fragment #/story.

Story report data endpoint

The dedicated get_action/story-report-data endpoint returns the scoped report payload for the current share token.

:::caution Breaking change Changed in v3.4.2: the previous get_action/report-data endpoint was renamed to get_action/story-report-data. The handler now also validates the supplied token against validate_share_token() before returning anything and returns an empty array when the token is missing or invalid. Update any custom client code calling the previous endpoint. :::

Body parameters:

ParameterTypeDescription
tokenstringThe 32-character hex share token tied to the report

Block-level access control

Report share links enforce a per-block resource map. A request from a report share session is only honored when the resolved REST endpoint or datatable ID is listed under one of the blocks present in the report. Filters defined on a block are also forced onto the request arguments, so a viewer cannot widen the dataset by sending a different filters payload.

The mapping is internal and not filterable. Blocks not in the map have no allowed endpoints, so they cannot be exposed through a share link even if they appear in a report.

Field set returned to share link requests:

FieldTypeDescription
idintReport ID
namestringReport name
formatstringReport format identifier
enabledboolWhether the report is active
contentarrayReport content blocks
reportDateRangestringDate range for the report
fixedEndDatestringFixed end date if set

The following admin-only fields are omitted from share link responses: frequency, weekOfMonth, dayOfWeek, sendTime, lastEdit, scheduled, recipients, lastSendStatus, lastSendMessage.

If the report is disabled (enabled = false), to_array() returns an empty array [] for share link requests — the report is not exposed.

lastSendStatus values:

ValueDescription
ready_to_shareReport is not scheduled; ready to be shared via link. Changed in v3.3.0 from ready_to_send
sentReport was successfully sent
failedLast send attempt failed

Legacy URL upgrade

When a request hits /burst-dashboard/?burst_share_token={token} without a tab segment in the path, the plugin returns a small HTML upgrader page instead of loading the React app. That page reads the legacy hash fragment (#/{tab}?{query}) in the browser, validates the tab against the shareable whitelist, and replaces the URL with the path-based equivalent before the dashboard boots.

Old share URLs distributed to recipients therefore continue to work without server-side rewrites — there is no need to manually reissue tokens to existing viewers when upgrading to v3.4.2.

Viewer hardening

Application Passwords disabled for the viewer role

Changed in v3.4.2: WordPress Application Passwords are unconditionally disabled for the burst_viewer user. A share link recipient is briefly authenticated as the burst_statistics_viewer system user; without this guard, that recipient could call POST /wp-json/wp/v2/users/me/application-passwords using the cookie and nonce attached to the shared dashboard page and create a Basic Auth credential that would survive share-token revocation or expiry.

The check is implemented as a filter on wp_is_application_passwords_available_for_user and applies to every request, including REST calls. On upgrade, any existing Application Passwords on the burst_statistics_viewer account are removed via WP_Application_Passwords::delete_all_application_passwords().

Viewer session cleanup

A daily cron (burst_daily) destroys every session token belonging to burst_statistics_viewer so viewer sessions never exceed 24 hours regardless of cookie lifetime.

PHP API

:::caution Breaking change Changed in v3.4.2: get_share_links() moved from the Share class to the new Share_Tokens service and is now reached through the tokens property on a Share instance. The method signature is unchanged, but the previous accessor ($share->get_share_links( ... )) was removed and will produce a fatal error. :::

Show code
// Before v3.4.2 (instance method on Share).
$share = new \Burst\Admin\Share\Share();
$links = $share->get_share_links( 'link' );

// v3.4.2 and later (accessed via the tokens service).
$share = new \Burst\Admin\Share\Share();
$links = $share->tokens->get_share_links( 'link' ); // only dashboard share links
$links = $share->tokens->get_share_links( 'report', '', 42 ); // links for report ID 42
$links = $share->tokens->get_share_links( 'all' ); // all tokens

Parameters:

ParameterTypeDefaultDescription
$typestring'all''all' — all tokens; 'link' — dashboard share links (report_id === 0); 'report' — report tokens (report_id !== 0). When $type is 'report' and $report_id > 0, a token is auto-generated if none exists
$tokenstring''Optional: filter by a specific token value
$report_idint0Optional: filter by report ID

Changed in v3.4.2: auto-generated report tokens now use the path-based view_url /burst-dashboard/story/ instead of /burst-dashboard/#story.

Changed in v3.4.1: filtered results are now passed through array_values() before being returned, so the array is always sequentially indexed regardless of which entries were dropped by the filter. Code that iterated with foreach is unaffected; code that relied on the original numeric keys must be updated.

Filters

burst_share_permissions

Filters the permissions array applied to a share token before it is stored or returned.

Parameters:

ParameterTypeDescription
$defaultsarrayDefault permissions: [ 'can_change_date' => false, 'can_filter' => false ]
$raw_permissionsarrayRaw permissions received from the REST request body
Show code
add_filter( 'burst_share_permissions', function( array $defaults, array $raw_permissions ): array {
// Merge raw permissions into defaults, keeping only known keys.
return array_merge( $defaults, array_intersect_key( $raw_permissions, $defaults ) );
}, 10, 2 );

Returns the resolved permission set for the currently active share link, keyed from the burst_share_token query parameter or X-Burst-Share-Token header in the current request.

Parameters:

ParameterTypeDescription
$permissionsarrayCurrent permissions array (empty by default when no valid token is present)

When a valid token is present, the array contains:

KeyTypeDescription
can_change_dateboolWhether the viewer may change the date range
can_filterboolWhether the viewer may apply filters
is_shareable_link_viewerboolWhether the current user holds the burst_viewer role
Show code
add_filter( 'burst_share_link_permissions', function( array $permissions ): array {
// Always allow date changes for share link viewers.
if ( ! empty( $permissions['is_shareable_link_viewer'] ) ) {
$permissions['can_change_date'] = true;
}
return $permissions;
} );

Share link authentication hooks into burst_verify_nonce to treat a valid X-Burst-Share-Token header as equivalent to a valid WordPress nonce for burst_viewer users. You can use the same filter to add custom token verification:

Show code
add_filter( 'burst_verify_nonce', function( bool $nonce_is_valid, ?string $nonce, string $action ): bool {
if ( $action === 'burst_nonce' && my_verify_custom_token() ) {
return true;
}
return $nonce_is_valid;
}, 10, 3 );

Parameters:

ParameterTypeDescription
$nonce_is_validboolWhether the nonce passed standard WordPress verification
$noncestring / nullThe nonce value from the request
$actionstringThe nonce action string (e.g. burst_nonce)

During share link sessions, burst_menu is applied a second time (at PHP_INT_MAX priority) to strip menu items the token does not grant access to. Only items with 'shareable' => true whose id appears in the token's shared_tabs list are kept.

See Hooks & filters for the full burst_menu documentation.