Knowledge base WordPress plugins Embedding
Embedding Power BI Reports in WordPress
The [o365_powerbi] shortcode: the attributes it reads, the token it needs before it renders anything, and the error strings it prints when one of those is missing.
Published 12 August 2026
The Office 365 Power Bi plugin (o365-powerbi, version 4.5) registers one shortcode,
[o365_powerbi], which renders a Power BI report or dashboard tile into a page using
Microsoft’s powerbi-client library (v2.11.0 is bundled with the plugin).
Everything below is drawn from the plugin’s own source. Where the plugin prints a particular string on failure, that string is quoted exactly — searching this page for the message you are seeing is the fastest way to find the cause.
Before the shortcode will render anything
The shortcode checks three things, in this order, and stops at the first one that fails. They have to be done in the same order.
1. The o365 base plugin must be active. Activation of the Power BI plugin calls
is_plugin_active('o365/o365.php'). If the base plugin is not active, activation is
aborted and WordPress dies with “This plugin requires o365 base plugin.” If the base
plugin’s own o365_base_plugin_is_verify option is 0, activation instead dies with
“ERROR: This plugin needs to be configured on the settings page >> General tab, before
proceeding.”
2. The licence key must be activated. On successful activation the plugin sets
o365_powerbi_verify_auth to false, and the shortcode refuses to do anything while that
option is false or empty — it prints:
Error: Please enter the Office 365 Powerbi Plugin activation key.
An admin notice with a link to wp-admin/admin.php?page=o365_license says the same thing.
Enter the key on that page against Office 365 Powerbi and press Activate. The key
is checked against https://api.wpintegrate.com/check_key_updates.php; on a bad key the
field shows “Please enter valid key.” On success the key is stored in o365_powerbi_lcode
and o365_powerbi_verify_auth becomes yes.
3. A Power BI access token must exist. Without one, the shortcode prints:
Error: Power BI access token required.
Getting that token is the next section.
Getting the Power BI access token
The plugin reads the Azure application credentials from the base plugin’s o365_settings
option — the client_id and client_secret keys — so the app registration is configured
on the base plugin’s settings page, not here.
The Power BI plugin adds its own row, Office 365 Power BI Report, to the token manager
on wp-admin/admin.php?page=o365_settings. Press Get Access Token there and the
browser is sent to:
https://login.microsoftonline.com/common/oauth2/authorize
?client_id=<your client id>
&redirect_uri=<your site>/wp-admin/
&response_type=code%20id_token
&scope=openid%20profile
&response_mode=form_post
&state=o365_powerbi_state
&nonce=<generated>
&resource=https://analysis.windows.net/powerbi/api
Three things in that URL matter when you register the Azure application:
- The resource is
https://analysis.windows.net/powerbi/api— this is the v1.0 endpoint, which asks for a resource rather than a scope list. The only scope requested at the authorize step isopenid profile; the Power BI permissions themselves come from the permissions granted to the app registration in Azure. - The redirect URI is
admin_url('/')— your site’s/wp-admin/URL, exactly as WordPress generates it. It must be registered on the Azure app or Microsoft will reject the sign-in before the plugin ever sees it. Note that it is/wp-admin/, not a plugin-specific callback. - The response mode is
form_post, so the authorization code comes back as a POST to/wp-admin/. The plugin picks it up on theinithook, and only when the postedstateequalso365_powerbi_state.
The code is then exchanged at https://login.microsoftonline.com/common/oauth2/token and
you are redirected back to the settings page with “Successfully get Azure access token”
or, if the response contained no access_token, “Error while getting access token”.
The token, its expiry and the refresh token are stored as three WordPress options:
o365_power_bi_access_token, o365_power_bi_access_token_expires and
o365_power_bi_refresh_token. On every init, if a token exists and expires within the
next 300 seconds, the plugin silently exchanges the refresh token for a new one. Once a
token exists the button on the settings page becomes Revoke Token.
While no token exists, every admin page carries the notice “Office 365 Power Bi Plugin doesn’t have an access token.” with a link to the token manager.
The shortcode
The plugin’s own settings screen documents the minimum form as:
[o365_powerbi groupid="" reportid="" width="" height="" parameters="&temp1=state&temp2=counutry"]
with Group ID and Report ID listed as the compulsory attributes. groupid is the Power
BI workspace ID; omit it and the shortcode prints “Error: Group ID missing from shortcode.
Please contact to site administrator.”
Attributes
| Attribute | Default | What it does |
|---|---|---|
groupid | — | Power BI workspace (group) ID. Required. |
reportid | — | Report ID. Used as the embed id, as the bookmark storage key, and in the export URL. |
dashboardid + tileid | — | Set both to embed a dashboard tile instead of a report. |
width | 100% | Applied as width on the embed iframe. |
height | 300px | Applied as min-height on the embed iframe. |
parameters | — | Appended verbatim to the embed URL, e.g. &temp1=state&temp2=country. |
filterpane | no | yes sets filterPaneEnabled. |
navpane | no | yes sets navContentPaneEnabled. |
fullscreen | yes | Shows the expand/contract buttons in the top bar. |
print | no | yes shows a print button, which calls the client library’s print(). |
bookmark | no | yes shows the bookmarks panel. |
export | no | yes shows the export button. Requires expapiurl as well. |
expapiurl | — | Base URL of your export API. The download link is built as <expapiurl>?reportId=…&groupId=…. |
pages | — | Comma-separated Power BI page names. Each name that matches a real page is appended to the export URL as &pages=<name>. The whole attribute value is also passed straight through as the embed’s pageName, which expects a single page name — so use one value if you are relying on that. |
exportpreloader | — | yes shows a spinner while the export runs. |
preloadertext | Downloading... | Text beside that spinner. |
preloader | — | URL of an image shown as a loading overlay until the report fires its loaded event. |
hidesysreport | — | Hides report bookmarks whose display name contains this string. |
style | — | Raw CSS injected into the .o365_powerbi_report_container iframe rule. |
What the rendered page loads
Rendering the shortcode injects, per instance: jQuery 3.5.1 from ajax.googleapis.com,
the Office UI Fabric core stylesheet from cdn.jsdelivr.net, the plugin’s
jquery.fullscreen.min.js and powerbi_custom.css, and the bundled powerbi.js. If your
site blocks third-party CDNs, the icons in the top bar and the fullscreen behaviour are
the parts that break.
Bookmarks
With bookmark="yes" the shortcode renders a collapsible BOOKMARKS panel with two
lists: Report bookmarks, read from the report itself through the client library’s
bookmarksManager, and Personal bookmarks, which only appear for a logged-in user.
Personal bookmarks are saved through the o365_save_powerbi_user_bookmarks admin-ajax
action into user meta under the key powerbi_bookmarks-<reportid>-<blogid> — so they are
per user, per report and per site on multisite. The panel’s rename, delete and share
actions all go through the same endpoint.
Share builds a link by truncating the current URL at its last / and appending
?bookmarkname=<bookmark name>. On load, the shortcode reads that same bookmarkname
query parameter and applies the matching bookmark’s state, so a shared link opens on the
shared view.
Troubleshooting
“Error: Please enter the Office 365 Powerbi Plugin activation key.” — o365_powerbi_verify_auth
is false or empty. Activate the licence key on the o365_license page. Note that
deactivating the plugin deletes both o365_powerbi_lcode and o365_powerbi_verify_auth,
so a deactivate/reactivate cycle always requires re-entering the key.
“Error: Group ID missing from shortcode.” — groupid is absent or empty. This check is
on groupid only; a missing reportid does not produce its own message.
“Error: Power BI access token required.” — o365_power_bi_access_token is empty. Either
you have never fetched a token, or a refresh failed. The refresh path writes nothing when
the response contains no access_token and reports nothing to the screen, so a silently
expired credential presents as this message appearing one day on a page that worked
yesterday. Re-run Get Access Token.
“cURL Error #: …” — the call to https://api.powerbi.com/v1.0/myorg/groups/<groupid>/reports/
failed at the transport level. The message printed is the raw cURL error. Firewalls and
outbound-request blocks show up here.
“Something went wrong or API has no results. Please contact to site administrator.” — the
same call returned an empty body. In practice this is an authorization failure against the
workspace, or a groupid that does not exist.
The wrong report renders. This is the one to know about. For a report embed the plugin
lists all reports in the workspace and takes the embed URL of the first one returned,
while passing your reportid as the embed’s id. In a workspace with one report the two
agree. In a workspace with several they may not, and the symptom is a report that loads but
is not the one you asked for. The reliable fix is one workspace per embedded report; there
is no attribute that overrides the chosen embed URL.
The export button downloads nothing. The download URL is only built when export and
expapiurl are both set. With export="yes" and no expapiurl the button renders with
an empty link. Note also that expapiurl points at an export API you host — the plugin
builds and links the URL, it does not perform the export.
hidesysreportbyname has no effect. The attribute is parsed but the parsed list is not
the array handed to the browser; the array that reaches the bookmark-filtering code is
always empty. Only hidesysreport, which filters on a substring of the bookmark’s display
name, actually removes anything.
A single personal bookmark does not appear in the list. The personal list is only built when more than one bookmark is stored for that report; with exactly one saved, the panel renders empty until a second is added.
Updates
The plugin checks https://api.wpintegrate.com/plugins_update_api_conn.php for its own
updates, so an activated licence also keeps the plugin current through the normal WordPress
updates screen. Version 4.5 declares a minimum of WordPress 5.0 and is tested to 5.9.1.
Read next
-
WordPress plugins · Getting started
Setting up the Office 365 Microsoft Booking plugin
Base plugin, Azure token, licence, then a shortcode — the order the plugin actually enforces, with every [msb_booking] attribute and its default.
-
WordPress plugins · Getting started
SharePoint Calendar Display: setup, shortcodes and room booking
Installing Office 365 SharePoint Calendar Display, the order the plugin requires, every attribute of [o365_sp_events] and [o365_sp_booking], and what each failure message means.
-
WordPress plugins · Authentication and access
Connecting the Office 365 plugin to an Azure app registration
The four fields on the Office 365 base plugin's General tab, what the Save button actually does with them, and why an unverified connection silently deactivates every add-on.