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 ID | Notes |
|---|---|
statistics | Free + Pro |
sources | Pro |
sales | Pro (Business tier) |
story | Reserved 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:
| Parameter | Type | Default | Description |
|---|---|---|---|
expiration | string | 7d | Token lifetime: never, 24h, 7d or 30d |
view_url | string | '' | 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 |
permissions | object | {} | Permission flags — filtered via burst_share_permissions. Valid keys: can_change_date, can_filter |
shared_tabs | array | [] | Tab IDs to expose: statistics, sources, sales. Other values are dropped during sanitization |
initial_state | object | {} | Pre-selected state: date_range.start, date_range.end, filters (key/value pairs) |
report_id | int | 0 | Attach 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:
| Parameter | Type | Description |
|---|---|---|
token | string | The 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.
Report share links
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:
| Parameter | Type | Description |
|---|---|---|
token | string | The 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:
| Field | Type | Description |
|---|---|---|
id | int | Report ID |
name | string | Report name |
format | string | Report format identifier |
enabled | bool | Whether the report is active |
content | array | Report content blocks |
reportDateRange | string | Date range for the report |
fixedEndDate | string | Fixed 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:
| Value | Description |
|---|---|
ready_to_share | Report is not scheduled; ready to be shared via link. Changed in v3.3.0 from ready_to_send |
sent | Report was successfully sent |
failed | Last 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
Share::tokens->get_share_links()
:::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:
| Parameter | Type | Default | Description |
|---|---|---|---|
$type | string | '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 |
$token | string | '' | Optional: filter by a specific token value |
$report_id | int | 0 | Optional: 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:
| Parameter | Type | Description |
|---|---|---|
$defaults | array | Default permissions: [ 'can_change_date' => false, 'can_filter' => false ] |
$raw_permissions | array | Raw 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 );
burst_share_link_permissions
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:
| Parameter | Type | Description |
|---|---|---|
$permissions | array | Current permissions array (empty by default when no valid token is present) |
When a valid token is present, the array contains:
| Key | Type | Description |
|---|---|---|
can_change_date | bool | Whether the viewer may change the date range |
can_filter | bool | Whether the viewer may apply filters |
is_shareable_link_viewer | bool | Whether 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;
} );
burst_verify_nonce (share link context)
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:
| Parameter | Type | Description |
|---|---|---|
$nonce_is_valid | bool | Whether the nonce passed standard WordPress verification |
$nonce | string / null | The nonce value from the request |
$action | string | The nonce action string (e.g. burst_nonce) |
burst_menu (share link context)
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.