Browse · Help archive
Getting Started
Account & Security
Billing & Plans
Organization & Roles
QA-QC
Project Matrix
File Management
Project Members
Access Requests
Project Setup
Attribute Extract
Attribute Import
Scheduled Jobs
Power BI Analytics
Foreman Assistant
Permissions Graph

Draft · This article is being updated. Content may change.

  1. Archive
  2. /
  3. Power BI Analytics
  4. /
  5. Connecting Power BI to Foreman

Connecting Power BI to Foreman

Learn how to connect Power BI to Foreman using the on-premises data gateway or Power BI Desktop, configure API tokens, and access analytics endpoints for reporting.


Architecture at a glance

Power BI Service ──► On-prem Gateway ──► HTTPS ──► Foreman API
                                                       │
                                          Authorization: Bearer tmac_…
                                                       │
                                                       ▼
                                       JSON: { rows, nextCursor, schemaVersion }

You install the Microsoft on-premises data gateway on a VM that can reach your Foreman deployment, paste your Foreman API token into the gateway's data source configuration, and Power BI Service pulls through that gateway on a schedule.

For ad-hoc development or smaller setups, Power BI Desktop can connect directly without a gateway.

Prerequisites

  • Tenant on the Business plan or above.
  • An analytics token (see Issuing & Revoking Analytics Tokens).
  • Power BI Desktop (latest version) for authoring; Power BI Service + on-premises data gateway for scheduled refresh.

Available endpoints

All endpoints share the same base path. Replace your-foreman-host with your tenant's domain (the same one you use to sign in).

Endpoint Description
https://your-foreman-host/api/analytics/v1/access-requests Access request rows
https://your-foreman-host/api/analytics/v1/access-request-activities Activity log per request
https://your-foreman-host/api/analytics/v1/access-request-forms Form definitions (dimension)
https://your-foreman-host/api/analytics/v1/qa-check-runs QA check runs with totals
https://your-foreman-host/api/analytics/v1/qa-check-results One row per violation
https://your-foreman-host/api/analytics/v1/qa-rules Rule dimension
https://your-foreman-host/api/analytics/v1/qa-rule-sets Rule set dimension

The exact URLs for your tenant are listed in the Setup panel of Organization → Power BI Analytics with copy buttons.

Connect from Power BI Desktop (development)

  1. Get Data → Web
    From the home ribbon, click Get Data, search for Web, and pick the Web connector.

  2. Choose "Advanced"
    In the dialog, switch to the Advanced tab so you can set HTTP headers.

  3. Paste a dataset URL
    For the URL, use one of the endpoints above with ?pageSize=1000.

  4. Add the Authorization header
    Header name: Authorization
    Value: Bearer tmac_<your-token-here>

  5. Click OK and inspect
    Power BI shows the JSON response. Expand the rows column, then convert to a table and expand the record fields.

This loads the first page only (up to 1,000 rows). For full datasets, use the paginator below.

Paginating with M

Drop this into a blank query (Home → Get Data → Blank Query → Advanced Editor). Replace BASE_URL and TOKEN:

let
    BaseUrl = "https://your-foreman-host/api/analytics/v1/access-requests",
    Token   = "tmac_REPLACE_ME",
    Headers = [
        #"Authorization" = "Bearer " & Token,
        #"Accept"        = "application/json"
    ],

    GetPage = (cursor as nullable text) as record =>
        let
            qs = if cursor = null
                 then [pageSize="2000"]
                 else [pageSize="2000", cursor=cursor],
            resp = Json.Document(Web.Contents(BaseUrl, [
                Headers              = Headers,
                Query                = qs,
                ManualStatusHandling = {429, 401, 403}
            ])),
            rows = if Record.HasFields(resp, "rows") then resp[rows] else {},
            next = if Record.HasFields(resp, "nextCursor") then resp[nextCursor] else null
        in
            [ rows = rows, nextCursor = next ],

    Pages = List.Generate(
        () => GetPage(null),
        each _[rows] <> null,
        each if _[nextCursor] = null
             then [rows = null, nextCursor = null]
             else GetPage(_[nextCursor])
    ),

    AllRows  = List.Combine(List.Transform(Pages, each _[rows])),
    AsTable  = Table.FromList(AllRows, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    Expanded = Table.ExpandRecordColumn(AsTable, "Column1", Record.FieldNames(AllRows{0}))
in
    Expanded

This walks every page in order until nextCursor returns null. For a tenant with hundreds of thousands of QA check results, expect the initial load to take 1–2 minutes.

Make the M query a function that takes a URL and returns a table, and you can reuse the same paginator for every dataset. Saves a lot of duplication.

Connect from Power BI Service (production)

For scheduled refresh, install the on-premises data gateway on a server that can reach your Foreman deployment over HTTPS.

  1. Download the gateway from Microsoft's gateway docs and run the installer.
  2. In Power BI Service, go to Settings → Manage gateways.
  3. Add a Web data source, point it at one of the analytics endpoints, and set authentication to Web API (or Anonymous if your gateway version doesn't support Web API — the bearer token in the M header still authenticates the call).
  4. In your dataset settings, enable gateway connection and pick the gateway you just registered.
  5. Configure scheduled refresh — hourly is plenty for most reporting use cases.

Incremental refresh

Once the dataset is loading from end to end, switch to incremental refresh so you don't re-pull the entire history every hour. Power BI uses two date parameters, RangeStart and RangeEnd, that you pass to the modifiedSince query parameter:

let
    Since = DateTime.ToText(RangeStart, "yyyy-MM-ddTHH:mm:ssZ"),
    qs    = if cursor = null
            then [pageSize="2000", modifiedSince=Since]
            else [pageSize="2000", modifiedSince=Since, cursor=cursor]
    // ...rest of the paginator
in
    ...

Recommended dataset settings: store the last 2 years, refresh the last 7 days. The first refresh is full; every subsequent refresh only pulls rows whose updated_at_utc is in the recent window.

Troubleshooting

Symptom Likely cause Fix
401 Unauthorized Token expired or revoked Issue a new one; update the gateway data source
403 Forbidden, "Feature not available" Tenant tier doesn't include PowerBiAnalytics Upgrade to Business or higher
403 Forbidden, "wrong scope" Token isn't an Analytics token (legacy MCP token) Issue a new analytics token from the admin page
429 Too Many Requests More than 600 requests in 15 minutes for one token Slow refresh frequency or split datasets across multiple tokens
Power BI prompts repeatedly for credentials Stale credential cache File → Options → Data source settings → Clear permissions for the URL
Refresh fails silently in Service Token expired between refreshes Set up Power BI refresh-failure email alerts at the dataset level

See also

You're offline — some actions may not work.

Connection lost

Attempting to reconnect to Foreman...

Connection lost

Retrying in --s Attempt - of -

Connection interrupted

Retrying in --s Attempt - of -