How does Power BI actually get data out of UKG?
Through routes your tenant already publishes, because Power BI Desktop ships no first-party UKG connector and there is no supported way to point it at the application database. Most builds use two or three routes together: Reports-as-a-Service from the business intelligence layer inside UKG Pro, the documented UKG Pro service APIs for structured worker and employment data, and the separate UKG Pro WFM API for anything to do with time.
Reports-as-a-Service is the route worth understanding first, because it is the one that decides how much cleanup the rest of the build inherits. A report saved in the BI layer can be exposed as a URL an authorised caller requests on a schedule, returning the same output the report produces on screen. That makes any field a report can reach extractable — including fields no endpoint returns — and it means the report definition, not the API, is where you control the shape of the extract.
UKG extraction routes and when each one is the right choice
| Route |
What it gives you |
When we use it |
| Reports-as-a-Service from UKG Pro BI |
Any output the business intelligence layer can produce, requested on a schedule by an authorised caller instead of downloaded by hand |
The workhorse for UKG Pro data, and the only route to fields that exist in a report but not in an API response |
| UKG Pro service APIs |
Worker, employment, job and status records as structured, typed, keyed responses |
Wherever the documented endpoints genuinely cover the fields you report on — always cleaner than parsing report output |
| UKG Pro WFM API |
Timecards and punches, schedules, accrual balances, hours by pay code, and labor account assignment |
Everything on the time and scheduling side — a separate application, with its own credentials and its own identifiers |
| Scheduled exports to storage you control |
The same extracts written on a fixed cadence to a location in your own tenant |
Backfilling years of history, and tenants where interactive requests are restricted or throttled |
| An existing warehouse copy |
UKG data already landed in Azure SQL, Microsoft Fabric, Snowflake or Databricks by an internal pipeline |
Always our first question — faster to refresh, cheaper to model, and trivially joinable to the general ledger |
Whichever routes apply, the extracts land in a store you own rather than being queried live behind the report. A dashboard asks historical questions, and the fastest refresh is a local read of rows already collected.
Why does report output from a Cognos-based BI layer fight a star schema?
Because the two are built for opposite purposes. UKG Pro’s embedded business intelligence is built on IBM Cognos Analytics, and Cognos is very good at producing something a person reads: groups printed once, subtotals in context, hours as 8:30, a column per pay period. A semantic model wants the opposite — narrow rows at one stated grain, every key repeated, numbers typed as numbers, and totals computed rather than stored.
This is the single most productive hour of a UKG build: rewriting the source report so the extract is already model-shaped. It follows Microsoft’s star schema modeling guidance (opens in new tab), and the general craft is covered on our star schema guide.
Cognos-shaped report output and how we land it instead
| What the report does on the page |
What it does to the model |
How we land it instead |
| Grouped sections with the group value printed once |
Blank cells wherever the group repeats, so a straightforward load loses the key on every row but the first |
A flat list at one grain, with the grouping column repeated on every row |
| Subtotal and total rows inside the body |
Silent double counting — totals load as facts and every measure reads high |
No totals in the extract at all; totals become DAX measures over the fact table |
| Periods spread across columns |
A new column appears each pay period and the refresh breaks on a schema nobody changed |
Period as a column value, or unpivoted in Power Query (opens in new tab) to one row per period |
| Durations formatted for reading (8:30, not 8.5) |
Hours will not aggregate, and a locale or format change silently shifts the parse |
Decimal hours from the source where available, converted once on load where not |
| Display labels shown instead of the underlying code |
Two pay codes sharing a label collapse into one, and a renamed label breaks last year |
Code and description both, with the code as the key |
| Row caps and paged output on large reports |
A truncated extract that looks complete and reconciles to nothing |
Chunked by pay period or date range, with row counts reconciled against a control total every run |
One clarification worth making early: this is a vendor-hosted BI layer, so you do not hold a Framework Manager project or a Cognos server of your own. If you do also run a self-managed IBM estate that leadership wants retired, that is a different engagement — our Cognos to Power BI migration page covers the package, determinants and report-by-report rebuild that comes with owning the metadata layer.
What about Platform Configuration Fields and other API gaps?
They decide scope, so they get checked first. UKG publishes what each endpoint covers, and Platform Configuration Fields — the configurable, client-defined values UKG Pro holds in platform configuration — are the documented gap: visible in the platform, absent from the API response. On a build where three of the fields finance wants sit in that gap, the extraction plan changes entirely.
The fix is unglamorous and reliable. We take your required field list, walk it against the published coverage and your own tenant, and split it: fields an endpoint returns cleanly, fields that have to come out through a RaaS report, and fields that are reference data better maintained as a mapping table you control. Nothing in the model depends on a field being available until we have seen it arrive.
How do UKG Pro and UKG Pro WFM come together in one model?
By conforming both sides onto one worker dimension and one calendar, then keeping each fact at its own grain. UKG Pro supplies who the person is and what their employment says; UKG Pro WFM supplies what they were scheduled for, what they actually worked, which pay codes those hours landed on, and which labor account was charged. The join between the two is established from your identifier mapping and validated on every run.
How UKG concepts land in the Power BI semantic model
| UKG concept |
What it carries |
Role in the model |
| Employee record (UKG Pro) |
Identity, employment status, hire and termination dates with reason, department and location |
Worker dimension — the single conformed key both applications are joined on |
| Job and pay group assignment (UKG Pro) |
Job code, FTE status, pay group and pay period pattern |
Attributes on the worker dimension, and the roll-up path manager views use |
| Timecard punches and totals (UKG Pro WFM) |
In and out punches, edits and approvals, and hours by pay code per day |
Hours fact at employee, day and pay code grain — the grain the whole time side depends on |
| Schedules (UKG Pro WFM) |
Planned shifts by employee, job and labor account, as published and as amended |
Scheduled-hours fact — the other half of schedule-versus-actual variance |
| Accrual balances (UKG Pro WFM) |
Vacation, sick and PTO grants, takings and balances as of a date |
Snapshot fact, captured on a cadence because a balance cannot be re-derived later |
| Pay codes and pay rules (UKG Pro WFM) |
Which hours count as regular, overtime, premium, holiday, on-call or unpaid, and the multipliers attached |
Pay code dimension — the mapping that decides what every hours measure means |
| Labor accounts and labor levels (UKG Pro WFM) |
The segmented account hours are charged to: location, department, job, project |
Flattened to levels and a path for roll-up, allocation and row-level security |
| Pay period and week calendar |
Pay group periods, week start day and the holiday calendar |
Period dimension beside a proper date table, so a WFM week and a UKG Pro pay period are both addressable |
The two grains are worth stating out loud, because mixing them is the most common modelling mistake on UKG data: hours are a daily fact and pay is a pay-period fact. Held separately against one date table they answer each other’s questions. Flattened into one table they produce a number nobody can reconcile.
Which measures does the dashboard carry?
The set below is what workforce, HR and finance teams consistently ask UKG for and end up assembling by hand across two exports. Each embeds a definition someone has to agree before the number means anything, so we write them as documented DAX measures over the star schema, then validate every total against a report your team already runs.
Core measures we build over the UKG model
| Measure |
How it is defined |
Why it is written this way |
| Headcount and FTE |
Active workers and full-time equivalents as of the selected date, by department, location and job |
Point-in-time, so a month-end figure never depends on the hour the extract happened to run |
| Turnover |
Terminations over average headcount for the period, split voluntary and involuntary, annualized |
UKG Pro carries a named termination reason — that is what makes the split defensible rather than assumed |
| Overtime hours and premium share |
Overtime hours by pay code, and the premium portion separated from straight time |
The premium is the part a scheduling change actually removes; a blended hourly cost hides it |
| Schedule-versus-actual variance |
Scheduled hours against worked hours by employee, day, job and labor account — netted and absolute |
Netting hides a site short one shift and long another; showing both is what makes it actionable |
| Coverage |
Scheduled hours against the comparable prior period or against demand, with unfilled shifts counted |
Answers the staffing question the overtime number only hints at |
| Accrual balance and liability |
Balance by accrual code from the snapshot history, valued at current rates |
A balance with no dollar figure beside it never reaches a finance conversation |
| Punch exceptions |
Missed, late and early punches, unapproved timecards and post-hoc edits, by supervisor and week |
The leading indicator of an overtime problem — visible days before the pay run, while it can still be fixed |
| Absence rate |
Unplanned absence hours over scheduled hours, by department and week |
Scheduled hours in the denominator is what makes the rate comparable across sites of different sizes |
Overtime deserves one caution. It is not a single rule: it is whatever your pay rules compute, sitting on top of the federal floor of time-and-a-half beyond 40 hours in a workweek described by the US Department of Labor’s Fair Labor Standards Act guidance (opens in new tab), plus state daily thresholds and whatever your agreements add. A dashboard should never recompute that from raw punches. It reads the pay codes WFM already produced, which is why the pay code mapping is agreed in scoping rather than inferred later. The discipline that keeps the rest defensible — one date table, conformed dimensions, measures rather than calculated columns — is described on our Power BI data modeling and DAX page.
Where does UKG’s own reporting stop?
UKG ships real reporting on both sides — the BI layer in UKG Pro, dataviews and reports in WFM — and for questions inside one application, in UKG’s own shape of the data, it is the right tool. The requests that reach us cross a boundary: across the two applications, into the general ledger and the labor budget, or onto a screen in front of people who have no UKG login and should not be given one.
Reporting inside UKG compared with a custom Power BI semantic model
| What you are trying to do |
Reporting inside UKG |
Custom Power BI model |
| Check a timecard or run a cycle |
Its core strength — live, in context, already secured |
Possible, but not a reason to build a model |
| Overtime read against the schedule that produced it |
Two applications, two reports, reconciled by hand |
Scheduled and worked hours at one grain, so variance and cost move together |
| Turnover in the departments carrying the hours |
People data and time data sit on different sides of the suite |
One worker dimension, so HR and workforce measures share a denominator |
| Labor hours against the GL and the budget |
Plan and accounting data live outside UKG entirely |
Budget modelled as a second fact against the same labor account and calendar |
| Accrual liability trended over years |
Balances are reported as of now |
Retained snapshots make the trend and the year-end position answerable |
| Where the logic lives |
Inside the vendor’s reporting layer |
In a model file in your own tenant, which you own outright |
The practical answer is usually both. Keep UKG reporting for running the operation, and build the model for the numbers that decide staffing plans, overtime policy and next year’s labor budget.
How are refresh and labor-account security set up?
The model is published to your Power BI workspace and refreshed on a cadence that matches how the data moves — for most employers a daily timecard and schedule pull with the worker extract behind it, inside Microsoft’s documented data refresh limits (opens in new tab). Punch-level history accumulates quickly, so where several years are in scope we configure incremental refresh (opens in new tab) and each cycle re-reads only an open window plus a short lookback for retroactive timecard edits.
Security is not an afterthought on workforce data. Visibility is handled with row-level security in the Power BI service (opens in new tab), driven from a mapping of viewers to labor accounts and evaluated against the flattened hierarchy, so a supervisor sees their own variance and exceptions, a regional lead sees their branch and HR and finance leadership see everything. Our guide to Power BI row-level security setup walks through the same configuration step by step. Individual-level detail gets the same care: where a team is small enough that one row identifies a person, we aggregate or suppress rather than publish it.
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 headcount, turnover, overtime and schedule variance from extracts your team can already produce usually fits a Starter block. Adding accrual liability, coverage against demand, several years of punch history, or a field list that turns out to need new RaaS reports typically needs Growth, because agreeing pay code and turnover definitions across HR, operations and finance takes discussion as well as development.
Most tasks ship within 3–5 business days of scope approval, and you get a scope and hours estimate before anything starts. Our guide to Power BI dashboard development cost covers what moves the number, how prepaid Flex hours work explains the model in full, and custom Power BI dashboard development describes the wider service this build sits inside.
Who is this for, and what is out of scope?
Employers running UKG Pro — usually with UKG Pro WFM beside it — who schedule and clock a real workforce and have no dedicated analytics engineer. Hospitals and clinics, manufacturers, retail and grocery groups, distribution and public-sector employers are the typical shape: somewhere between a few hundred and several thousand people, where a point of overtime is a budget line and a supervisor exports the same two reports every week.
Writing back to UKG is out of scope; this is a read-only reporting build, and timecard or schedule edits belong in the application that owns the rules. If your interest is the pay register rather than the hours behind it — gross-to-net, deduction categories, labor cost against budget, at any provider — our Power BI payroll dashboard page is the better starting point. Employers whose system of record is ADP or Paylocity should start from those pages, where the extraction routes differ completely, and enterprise HR estates on Workday are a different build again. Contact is form-only — send your request and we’ll reply with a scope estimate.