How does the connection to Autotask actually get made?
Your administrator creates an API-only user inside Autotask, assigns it the API user security level, and generates a username and secret. That user is also associated with an integration code — a tracking identifier for the application making the calls. Power Query sends the username, the secret and the integration code as headers on every request. There is no interactive sign-in, and nothing about the connection depends on a person who might leave.
Before any of that works you need the right address. Autotask tenants are distributed across numbered web-services zones, so the API base URL is specific to your database rather than shared across all customers. The zone information endpoint returns yours when queried with the API user name, and we resolve it at build time instead of pasting a zone from a forum thread. Requests are also paged, so a query returns a block of records plus a pointer to the next page; the extraction follows that pointer rather than assuming one call returns everything.
One more constraint shapes the design: Autotask meters API usage against an hourly threshold per database, so a naive full reload every hour is not a viable pattern. We page the history once, then request only records whose last-modified stamp has moved. That keeps a multi-year model inside both the refresh window and the request budget.
Which Autotask entities does the model need?
Fewer than most people expect. Almost every question an MSP asks — contract profitability, technician utilization, effective rate, SLA attainment — resolves to a combination of the same handful of entities. The table below maps each one to the job it does once the data is modelled rather than merely listed.
Autotask PSA entities and the role each one plays in the semantic model
| Entity |
What it holds |
Role in the model |
Tickets |
Queue, status, priority, issue and sub-issue type, company and assigned resource, create and complete stamps, SLA reference and response timestamps |
Fact table for ticket lifecycle, backlog and SLA measures |
TimeEntries |
Hours worked and hours to bill, billing code and role, resource, and the ticket, task or contract the time was charged against |
Fact table for labour — the backbone of utilization, cost and effective rate |
Contracts + ContractServices |
Contract type, period and dates, the services and units on a recurring agreement, and block-hour balances |
Contract dimension, and the structure margin is grouped by |
BillingItems |
Approved and posted billing lines by company, contract and period, covering labour, recurring services, charges and milestones |
Fact table for revenue actually billed, not revenue contracted |
Companies |
Client records, company type, territory, classification and parent relationships |
Client dimension — the key every fact table conforms to |
Resources + Roles |
Technicians and engineers, their departments, and the roles that carry billing and internal rates |
Resource dimension, joined to the cost rates you supply |
Projects + Tasks |
Project phases, estimated versus actual hours, and task-level assignment |
Second labour context, so project work is not mistaken for service desk work |
ConfigurationItems |
Managed devices and subscriptions per client, with contract association |
Denominator for cost and effort per endpoint or per seat |
Two structural details cause most of the rework. User-defined fields do not appear as columns — they come back inside a nested collection of name/value pairs on each record, which has to be expanded and pivoted before any slicer can use them. And a large share of the interesting fields are picklist integers rather than text, so status, priority, queue and issue type need their labels resolved from the entity's field metadata before a report reads as English. Both are cheap once, expensive if discovered late, and are the reason a copy-pasted Power Query snippet from a forum rarely survives contact with a real tenant.
REST API or the Autotask data warehouse?
There are two supported ways into the same data, and the right answer depends on what you already license and how much history you want. The REST API is universal and needs no add-on. The Autotask data warehouse is a SQL Server-backed copy of your database that Power BI can query directly, which changes the economics of a multi-year load considerably. Neither is automatically better.
Comparing the three routes from Autotask data to a Power BI report
| Consideration |
Autotask REST API |
Autotask data warehouse (SQL) |
Native LiveReports & widgets |
| Availability |
Every tenant, once an API user exists |
Where the add-on is licensed |
Included in the PSA |
| Multi-year history |
Workable, but a staged, paged load |
Cheapest route — set-based SQL, no paging |
Constrained by report and widget limits |
| Joins across entities |
Done in Power Query or in the model |
Done in the database before load |
Limited to what the report writer exposes |
| Unattended refresh |
Scheduled or incremental in your workspace |
Scheduled via gateway where the copy is private |
Refreshes on page reload, no wallboard mode |
| Labour costed at your rates |
Requires a cost-rate table you supply |
Requires the same table, joined in SQL |
Not possible — cost rates are not in the PSA |
| Where the logic lives |
A model file in your own tenant, versioned and owned by you |
Inside Autotask, tied to the subscription |
In practice a good number of MSPs end up using both data paths: the warehouse for the deep history that would take hours to page, and the API for the recent window that has to be current by the morning stand-up. That is a normal, supportable design rather than a compromise. The last column is the honest reason people go looking in the first place — native Autotask reporting is genuinely useful inside the PSA, but its widgets refresh when someone reloads the page, there is no TV or wallboard display mode for a service-desk screen, and it cannot cost a technician's hour because your cost rates were never in Autotask to begin with.
How are contract margin and utilization calculated?
In DAX, over a star schema, against a date table that spans the full history. The measures below are the ones that get argued about in every MSP engagement, because each one encodes a definition your leadership team has to agree with before the number means anything. We write them explicitly rather than hiding the logic in a query step.
Core DAX measures we build over the Autotask model
| Measure |
Definition |
Why it is written this way |
| Hours Worked |
SUM ( 'Time Entry'[Hours Worked] ) |
Everything downstream costs or divides from this, so it stays deliberately plain |
| Hours To Bill |
SUM ( 'Time Entry'[Hours To Bill] ) |
Autotask records both; the gap between them is written-off effort, which is the thing worth seeing |
| Utilization % |
DIVIDE ( [Hours To Bill], [Capacity Hours] ) |
Capacity comes from a resource-schedule table, because the PSA records time worked, not time available |
| Labour Cost |
SUMX ( 'Time Entry', 'Time Entry'[Hours Worked] * RELATED ( 'Resource'[Cost Rate] ) ) |
Row-level, so a rate change or a mixed-seniority ticket costs correctly |
| Contract Margin % |
DIVIDE ( [Billed Revenue] - [Labour Cost] - [Allocated Product Cost], [Billed Revenue] ) |
Revenue from billing items, not the contract header, which stops being true the first time services change |
| Effective Rate |
DIVIDE ( [Billed Revenue], [Hours Worked] ) |
Divides by hours worked, since unbilled effort on a recurring contract is exactly the problem being measured |
| SLA Attainment % |
DIVIDE ( [Tickets Meeting SLA], [Tickets With An SLA] ) |
Excludes tickets that never carried an SLA, so the rate is not quietly inflated by out-of-scope work |
Effective rate by contract is usually the measure that changes a conversation. It is arithmetically trivial and organisationally uncomfortable: it puts a number on the flat-fee agreements absorbing more labour than they price for, and it does it per contract rather than as an average that hides them. The gap between hours worked and hours to bill does the same job at resource level. 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.
What keeps the refresh healthy?
Three things, settled during the build rather than discovered on the first Monday. First, the gateway question: a cloud-only API pull normally refreshes without one, but a SQL warehouse copy inside your network needs Microsoft's on-premises data gateway (opens in new tab). Our walkthrough of Power BI gateway setup covers the install and data-source registration step by step.
Second, dynamic data sources. Following a paged API means building request URLs in code, and the Power BI service refuses to refresh a query whose data source it cannot determine in advance. The fix is to keep the base address fixed and vary only the relative path and query parameters, which keeps the source statically analysable. Third, cadence and volume: refresh frequency follows Microsoft's documented data refresh limits (opens in new tab), and for multi-year ticket and time history we configure incremental refresh (opens in new tab) so only a recent window is re-pulled each cycle — which also keeps you comfortably inside Autotask's hourly request budget.
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, backlog and SLA reporting plus technician utilization from a single Autotask instance usually fits a Starter block. Full contract profitability — cost rates, product allocation, billing-item reconciliation across several contract types — typically needs Growth, because agreeing the allocation rules takes discussion as well as development.
Most tasks ship within 3–5 business days of scope approval. You get a written scope and hours estimate before anything starts, and hours are deducted 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 Autotask PSA with enough history to trend and no in-house data engineer — typically the point where someone exports to Excel every month and nobody quite trusts the result. Owners, service delivery managers and finance leads are the people who usually get in touch, often just after a renewal conversation went badly.
If your PSA is ConnectWise rather than Autotask, the ConnectWise Power BI dashboard page covers that platform's own API, schema and gateway questions — a different PSA with a genuinely different integration. And if you want the commercial picture across your whole toolset rather than the Autotask plumbing, start with Power BI dashboards for MSPs, which stays at the industry level on the KPIs themselves. Contact is form-only — send your request and we'll reply with a scope estimate.