How does authentication against the Manage REST API work?
You create an API member inside ConnectWise — a member record that exists only for integrations, with its own security role — and generate a public/private key pair against it. Requests then authenticate over HTTPS using that key pair alongside your company identifier, with a registered client ID sent as a header on every call. There is no interactive sign-in and no OAuth consent screen to click through.
Two things matter here beyond getting a 200 back. First, scope: we ask for a read-only security role, because a reporting credential has no business being able to modify a ticket. Second, ownership: the key pair belongs to your instance and is provisioned by your administrator, so nothing about the connection depends on us continuing to exist. If you later take the model in-house, the credential is already yours.
Which endpoints does the model actually need?
Six or seven, in practice. Everything an MSP asks for — margin, utilization, effective rate, SLA detail — resolves to some combination of tickets, time entries, agreements, invoices, companies and members. The table below maps each endpoint to the role it plays once the data is modelled rather than listed.
ConnectWise PSA endpoints and the role each one plays in the semantic model
| Endpoint |
What it holds |
Role in the model |
service/tickets |
Board, status, type, priority, company and member references, entered and closed timestamps, SLA status |
Fact table for ticket lifecycle and SLA measures |
time/entries |
Actual hours, billable option, work type and work role, member, and the ticket or agreement the time was charged to |
Fact table for labour — the backbone of both utilization and cost |
finance/agreements |
Agreement header, type, bill cycle, start and end dates, plus additions carrying seat and unit changes |
Dimension for contract, and the structure margin is grouped by |
finance/invoices |
Invoiced amounts by company, agreement and period, including one-off and project billing |
Fact table for revenue actually recognised, not contracted |
company/companies |
Client records, company types, territories, status and site structure |
Client dimension — the key every fact table conforms to |
system/members |
Technicians and engineers, default work role, location and team |
Member dimension, joined to the cost rates you supply |
procurement/products |
Product and licence lines sold against tickets, projects and agreements |
Cost input for margin once allocated to the agreement it serves |
Two structural details cause most of the rework. Reference objects — company, member, agreement, board — arrive nested inside each record rather than as flat foreign keys, so they have to be expanded and conformed into the star schema before any relationship exists. And cost rates are not sitting in the API waiting to be read; they come from you, usually as a small maintained table, which is a conversation worth having in scoping rather than at the end.
How are agreement margin and utilization calculated?
In DAX, over a star schema, against a date table that covers the full history. The measures below are the ones that get argued about in every MSP engagement, because each embeds a definition your leadership team has to agree with before the number means anything. We write them explicitly rather than burying the logic in a query.
Core DAX measures we build over the ConnectWise model
| Measure |
Definition |
Why it is written this way |
| Logged Hours |
SUM ( 'Time Entry'[Actual Hours] ) |
Everything downstream divides or costs from this, so it stays deliberately plain |
| Billable Hours |
CALCULATE ( [Logged Hours], 'Time Entry'[Billable Option] = "Billable" ) |
Filters on the billable flag rather than inferring intent from work type |
| Utilization % |
DIVIDE ( [Billable Hours], [Capacity Hours] ) |
Capacity comes from a member-schedule table, because the PSA reports time logged, not time available |
| Labour Cost |
SUMX ( 'Time Entry', 'Time Entry'[Actual Hours] * RELATED ( 'Member'[Cost Rate] ) ) |
Row-level so a rate change or a mixed-seniority ticket costs correctly |
| Agreement Margin % |
DIVIDE ( [Invoiced Revenue] - [Labour Cost] - [Allocated Product Cost], [Invoiced Revenue] ) |
Revenue from invoices, not the agreement header, which drifts the moment an addition changes |
| Effective Rate |
DIVIDE ( [Invoiced Revenue], [Logged Hours] ) |
Divides by logged hours, since unbillable time on a fixed-fee agreement is exactly the problem being measured |
Effective rate by agreement is usually the measure that changes a conversation. It is arithmetically simple and organisationally uncomfortable: it puts a number on the flat-fee contracts absorbing more labour than they price for, and it does it per agreement rather than as an average that hides them. The modelling discipline underneath — conformed dimensions, one date table, measures instead of calculated columns — is the same craft described on our Power BI data modeling and DAX page.
Do you need an on-premises data gateway?
Sometimes, and it is worth settling before the build rather than discovering it on the first scheduled refresh. A partner-hosted or on-premises ConnectWise instance needs Microsoft's on-premises data gateway (opens in new tab), and so does any staged SQL copy sitting inside your network. Cloud-hosted instances normally refresh without one. Our walkthrough of Power BI gateway setup covers the install and data-source registration in detail.
The exception catches people out. Paging a REST API means building request URLs in code, and the Power BI service refuses to refresh a query whose data source it cannot determine ahead of time. The fix is to keep the base address constant and vary only the relative path and query parameters, or to register the source through a gateway configured to skip the connection test. Either way, refresh cadence then follows Microsoft's documented data refresh limits (opens in new tab), and for multi-year ticket and time history we usually configure incremental refresh (opens in new tab) so only a recent window is re-pulled each cycle.
Where does BrightGauge stop and a custom model start?
BrightGauge is a capable product and ConnectWise has owned it since 2019, so the integration is close. It is built for live gauges, scorecards and client-facing dashboards over its own ConnectWise-shaped datasets, and for that it is a reasonable answer. What it is not is a semantic modelling tool, and the questions MSPs bring us are almost always modelling questions.
Gauge-and-scorecard reporting compared with a custom Power BI semantic model
| What you are trying to do |
Dataset-driven gauge tooling |
Custom Power BI model |
| Live ticket and SLA scorecards |
Its core strength — prebuilt and fast to stand up |
Also straightforward, but you build it rather than pick it |
| Margin including labour at cost |
Needs cost rates the PSA does not hold |
Cost table joined to members and costed row by row |
| Vendor and licence spend allocated per client |
Sits outside the PSA dataset entirely |
Modelled as an additional fact with agreed allocation rules |
| Multi-year trend across restructured agreements |
Constrained by how the dataset is scoped |
Slowly changing dimension keeps history comparable |
| Custom time intelligence and cohorts |
Limited to what the metric builder exposes |
Any DAX you can justify, versioned and documented |
| Where the logic lives |
Inside the vendor's platform |
In a model file in your own tenant, which you own outright |
The practical answer is often both. Keep the gauge wall for the service desk, and build the model for the numbers that decide pricing, staffing and which renewals to reprice. If what you actually want is the wider operational and commercial picture across your whole toolset rather than the ConnectWise plumbing, start with Power BI for MSPs and IT services instead — this page is deliberately the technical half.
What does the build cost, and how long does it take?
Prepaid Flex hours that never expire: Starter 20 hours at $125/hr ($2,500), Growth 40 hours at $115/hr ($4,600), Power 80 hours at $100/hr ($8,000), with hourly work from $100/hour on the largest block. A first build covering ticket and SLA reporting plus technician utilization from a single ConnectWise instance usually fits a Starter block. Full agreement profitability — cost rates, product allocation, invoice reconciliation — typically needs Growth, because the allocation rules take discussion as well as development.
Most tasks ship within 3–5 business days of scope approval. You get a scope and hours estimate before anything starts, and hours deduct only for work you approve. Our guide to Power BI dashboard development cost covers what moves the number, and how prepaid Flex hours work explains the model in full.
Who is this for?
MSPs running ConnectWise PSA with enough history to trend and no in-house data engineer — typically the point where someone is exporting to Excel monthly and nobody trusts the result. Owners, service delivery managers and finance leads are the people who usually get in touch, often after an agreement renewal went badly.
If your delivery work runs through a project tool as well as the service desk, the Jira Power BI dashboard page covers modelling that source alongside a PSA, and accounting-side joins for cost and revenue are described on our QuickBooks Power BI dashboard page. Contact is form-only — send your request and we'll reply with a scope estimate.