Power Apps Delegation Limits Don’t Throw an Error. They Just Give You the Wrong Answer.

Solution architect reviewing a data table dashboard on a large monitor, illustrating enterprise data query review

A finance team at a mid-size distributor built a canvas app to flag overdue receivables. It worked perfectly in every demo. Then it went into production against a SharePoint list that had grown past 4,000 rows, and the “overdue balance” total the app displayed started coming in a little low every week, never wildly wrong, just quietly off by a shrinking or growing margin depending on how the underlying data happened to sort. Nobody got an error message. Nobody got a warning banner in the running app. The gallery rendered, the total summed, and the number was simply incomplete, because Power Apps had silently stopped looking at the data after the first 500 records.

That is the practical shape of a delegation problem, and it is one of the more consequential gaps between how canvas apps behave in the maker’s testing environment and how they behave once real data volume shows up. Power Apps delegation limits determine whether a formula gets pushed down to the data source, which processes it server-side and returns only the matching rows, or whether Power Apps has to pull a bounded chunk of records locally and evaluate the formula against that chunk alone. When delegation fails and the underlying table is larger than the configured limit, the app does not stop working. It keeps working, on a subset of the data, without saying so.

Why Power Apps delegation limits fail silently instead of crashing

A crash gets fixed immediately because someone notices. A silently truncated query gets fixed only when someone happens to reconcile the app’s output against the source system and finds a discrepancy, which in the receivables example took several weeks. For a technical team supporting Dynamics 365 or Power Platform deployments, this is the argument for treating delegation as an architecture decision made at design time, not a performance tweak applied after a slow gallery gets noticed.

The default data row limit in a canvas app is 500 records, adjustable up to a hard ceiling of 2,000 in the app’s Settings under General. Raising that number is a common instinct and a bad one to rely on as a fix, because it just moves the cliff edge further out rather than removing it; a table with 50,000 rows behaves identically whether the limit is set to 500 or 2,000; it only changes how much data has to grow before someone notices something is wrong. Microsoft’s own guidance for this reason recommends the opposite move during development: set the limit down to 1 in a test environment, which forces every non-delegable formula to reveal itself immediately with obviously wrong results, rather than leaving that discovery to production data volume.

What actually gets delegated, and what does not

Power Fx delegates a meaningful set of operations against supported data sources, including Dataverse, SharePoint Online, SQL Server, and Salesforce. Filter, Search, LookUp, and First all delegate, as do the standard comparison operators, And, Or, Not, StartsWith, EndsWith, and the core aggregates: Sum, Average, Min, Max, CountRows, and Count. Sort and SortByColumns delegate as well, with an important caveat covered below for SharePoint. The In operator delegates too, but only against a column on the base table; the moment a formula tests In against a related or lookup column, delegation breaks and the query falls back to local evaluation.

Developer typing Power Fx formula logic on a laptop with a monitor showing abstract code in the background

The non-delegable list is longer and easier to trip over than most makers expect. FirstN, Last, and LastN do not delegate. Neither does If, which means embedding conditional logic inside a Filter predicate is a common way a formula that looks delegable quietly is not. String manipulation functions including Left, Mid, Len, Lower, and Upper are non-delegable, along with Concatenate and the & operator, GroupBy, Ungroup, and type-casting functions like Text and Value. Collect and ClearCollect are non-delegable by nature, since they materialize data locally rather than querying it. A formula like Filter(Fruit, Mid(FruitName, 1, 1) = “A”) looks reasonable and reads cleanly, but because Mid cannot be pushed to the data source, it only ever evaluates against the first page of records pulled locally, meaning a record named “Pineapple” sitting past row 500 will never match a search for names starting with “P,” not because the logic is wrong, but because the function never sees that row.

SharePoint makes this worse than Dataverse does

Anyone who has built canvas apps against both SharePoint lists and Dataverse tables has felt the difference in how forgiving each source is, and the gap is documented, not just anecdotal. SharePoint does not delegate relational comparison operators (less than, greater than, not-equal) on plain text fields at all, only equality. IsBlank does not delegate against text fields either, and the commonly suggested workaround, comparing to Blank() directly, does not behave identically for genuinely empty strings versus null values, which is a subtle correctness gap worth documenting in code review rather than discovering in production.

The bigger gap sits in SharePoint’s complex column types: Choice, Lookup, Person, Group, Task Outcome, Managed Metadata, and External Data. None of these support delegated sorting, so Sort or SortByColumns against a Choice or Person field will silently fall back to sorting only the locally retrieved page. StartsWith does not work against subfields of Choice or Lookup columns. Person and Group fields only delegate on their Email and DisplayName subfields, not on other properties. A set of SharePoint system fields, including ContentType, ModerationStatus, VersionNumber, and several path-related fields, do not delegate under any function at all. UpdateIf and RemoveIf against SharePoint are handled through a batching simulation bounded by the same 500/2,000 record limit rather than a true server-side delegated operation, which matters for any flow that bulk-updates list items from within the app rather than through Power Automate.

Dataverse does not eliminate delegation limits, but it closes most of these specific gaps: relational operators work against text columns, In delegates on base-table columns consistently, and sorting against lookup and choice columns behaves as makers expect. For any canvas app expected to scale past a few thousand records with complex filtering or sorting, that difference is a legitimate factor in the SharePoint-versus-Dataverse decision, not just a licensing or governance one.

Designing around it instead of hoping around it

The most reliable pattern is to push complexity toward the data source rather than the formula bar. Where a filter needs to test a derived value, calculated columns created in Dataverse (or, with more limitation, in SharePoint) let the comparison happen against a pre-computed, delegable field instead of a runtime string function the client has to evaluate locally. Where a search needs to match across multiple text fields, Search() itself delegates and is usually a better first attempt than a hand-built Filter with concatenated conditions, since it is one of the few functions built specifically to delegate substring matching.

For teams supporting these apps in production rather than just building them, the practical safeguard is process, not just formula discipline: run the app with the row limit forced to 1 during test cycles, review any gallery, dropdown, or KPI tile driven by a filter or sort against a table that could plausibly exceed a few hundred rows in production, and treat a yellow delegation warning triangle in Power Apps Studio as a defect ticket rather than a cosmetic nag to dismiss. The warning is not a suggestion about performance. It is Power Apps telling the maker, in the only language it has, that the number on screen may not represent all of the data.

We’ve walked enough Dynamics 365 and Power Platform clients through exactly this kind of discovery, usually during a post-go-live support engagement rather than a planned architecture review, to treat delegation as a first-week design conversation on every canvas app project involving a table that is expected to grow. It is a cheap conversation to have early and an expensive one to have after a finance report has been quietly wrong for a month.


#PowerApps #PowerFx #CanvasApps #Dataverse #SharePointOnline #EnterpriseArchitecture #LowCodeDevelopment

Your Field Service Techs Are Getting Blank Screens Offline. The Mobile Offline Profile Is Probably Why.

Field service technician reviewing a mobile app on a rugged tablet at a remote service site

A field technician pulls into a rural service site with one bar of signal, opens the Dynamics 365 Field Service mobile app to check the work order, and gets a blank booking screen. No linked asset. No contact history. No parts list. The dispatcher, sitting in an office with full connectivity, sees the record perfectly. By the time anyone traces the problem, three more technicians have hit the same wall in three different territories, and the rollout that was supposed to cut truck-roll callbacks is instead generating help desk tickets.

Nine times out of ten, this isn’t a connectivity problem. It’s an offline profile problem, and it’s almost always self-inflicted during setup rather than caused by anything Microsoft shipped broken. The mobile offline profile is the single control surface that decides what data a technician’s device downloads before it goes dark, and getting it wrong doesn’t throw an error message. It just quietly leaves data out.

What the Mobile Offline Profile Actually Controls

Every Field Service mobile deployment starts from a default profile, “Field Service Mobile – Offline Profile,” preloaded with the tables most implementations need: bookable resource bookings, work orders, and the handful of related entities technicians touch in the field. Each table in the profile carries its own filter and its own sync frequency, and the defaults are conservative on purpose. Bookings, for instance, are filtered out of the box to only those starting within the next seven days, which keeps the initial download small but also means a technician who needs to glance at next month’s schedule offline simply can’t.

The part that trips up most implementations isn’t the top-level filters. It’s item association: how child tables inherit scope from their parent. When a table is configured with a “related rows only” filter, it doesn’t get its own independent rule, it borrows whatever the parent table’s filter already decided. If a work order filter is scoped to status equals Scheduled, and the contact table beneath it is set to related rows only, technicians lose visibility into every contact tied to a work order that isn’t currently in Scheduled status, including ones they closed out an hour ago and now need to reference for a warranty callback. This is rarely intentional. It’s usually the byproduct of an admin extending the default profile with a new custom table, applying “related rows only” because it’s the fastest configuration path, and never testing what happens once a record moves out of the parent filter’s scope.

Where FetchXML Earns Its Place

Point-and-click filters cover a lot of ground, but they run out fast once the business logic gets specific: technicians who should only see assets under an active maintenance contract, or work orders filtered by a custom priority field that doesn’t map cleanly to the standard filter builder. That’s what the FetchXML editor built into the offline profile experience is for. It sits underneath the same table configuration screen as the standard filter UI, and it lets an admin or developer write the actual query logic that determines what gets pulled down, rather than settling for whatever combinations the visual filter builder happens to expose.

Two details matter here that don’t show up until you’re debugging a slow sync in production. First, table relationships in an offline profile are capped at fifteen linked tables, counting the downstream relationships each linked table pulls in, so a profile built by repeatedly adding “just one more related table” to solve an edge case will eventually hit a wall that has nothing to do with data volume and everything to do with query complexity. Second, several standard tables never make it into offline mode at all regardless of how the FetchXML is written, among them purchase orders, agreements, and return-to-vendor or return-merchandise-authorization records. If a workflow depends on a technician checking RMA status from a job site with no signal, that has to be redesigned around the platform’s boundaries rather than configured away.

The Update Trap Almost Nobody Reads About Until It Bites

Microsoft updates the default offline profile periodically as part of ongoing Field Service releases. That sounds like a convenience, and for tables you haven’t touched, it is: their sync filters get refreshed automatically, though the updated version lands unpublished, waiting for an admin to review and accept it rather than going live silently. The trap is on the other side. The moment you edit a table’s sync filter yourself, that table is permanently excluded from future automatic updates to its filter logic. Your customization sticks, which is usually what you want, but it also means nobody upstream is going to quietly fix a filter you configured eighteen months ago if Microsoft later improves the default logic for that table. Teams that treat the offline profile as a set-and-forget configuration item, rather than something reviewed on the same cadence as the rest of their Field Service solution, tend to find this out the hard way when a filter that was reasonable at go-live has quietly become wrong as the business changed around it.

Rugged tablet showing a sync status dashboard inside a field service van

Sync Behavior and the Conflict Question Nobody Asks Until It Happens

Sync intervals per table can be set anywhere from five minutes to a full day, and a related table with a shorter interval than its parent will pull the parent’s sync cadence down to match, which is a reasonable default but one worth knowing about before you tune a slow-changing table to sync once daily and then wonder why it’s still refreshing every few minutes. The conflict scenario that actually matters operationally is what happens when a technician edits a record offline while a dispatcher edits the same record online before the technician’s device reconnects. Dynamics resolves this at the table level, not the field level, meaning it can’t merge a technician’s parts-used update with a dispatcher’s status change on the same booking if both touched the record. By default, the technician’s offline change wins when the sync finally reconciles; that behavior can be flipped so the dispatcher’s online change takes precedence instead, but it’s a system setting, not something either side of that conflict controls in the moment. Organizations that run high-volume dispatch operations with technicians frequently going in and out of coverage should decide which side should win deliberately, rather than discovering the default behavior mid-incident.

Building a Profile That Holds Up in Production

The practical guidance that actually prevents the blank-screen scenario starts with resisting the urge to filter on “all records” for any table technicians don’t strictly need in full. A technician-scoped view like “my recent bookings” instead of the full bookings table, paired with tight date-range filters, keeps the initial download fast and avoids syncing data nobody in the field will use. For custom logic that needs to run without a network connection, offline-capable JavaScript on the form is the right tool, not a Power Automate flow, since cloud flows simply don’t execute until the device reconnects, which means any process depending on one won’t fire while the technician is actually offline. When custom commands query offline data directly, keeping concurrent database calls to two or three at a time avoids performance degradation on lower-end field devices, and using FetchXML paging with a page cookie rather than pulling an entire table in one request keeps large tables from stalling initial sync. Finally, testing a profile against a realistic data volume, not a clean sandbox with a handful of sample records, is what actually surfaces the fifteen-table ceiling and the related-row inheritance trap before a rollout, rather than after one.

None of this is exotic configuration. It’s closer to data modeling than app administration, and it rewards the same discipline: understand what each table’s filter actually inherits, know where the platform’s hard limits sit before you design around them, and revisit the profile as a living part of the solution rather than a one-time setup task. Teams we’ve worked with on Field Service rollouts consistently find that the offline profile, more than any other single configuration piece, determines whether the mobile app earns trust in the field or becomes the thing technicians route around.


#FieldServiceMobile #DynamicsFieldService #FetchXML #OfflineDataSync #EnterpriseMobility

Business Central Doesn’t Ship a Visual Production Scheduler. Manufacturers Need to Budget for One.

A production scheduler pointing at a large touchscreen displaying a colorful Gantt-style production schedule in a factory control room

A finance director at a contract manufacturer we spoke with recently put it plainly: her company had spent seven figures moving off an aging NAV instance and onto Business Central, and the go-live checklist covered chart of accounts mapping, inventory valuation, and tax setup in exhaustive detail. Nobody on the project had asked how the shop floor supervisor would actually build tomorrow’s schedule. Three weeks after cutover, that supervisor was back to a whiteboard and a spreadsheet, because the production order list Business Central shipped with told him what needed to happen, not when it would fit around the machines he actually had.

That gap catches a lot of SMB manufacturers off guard, and it is worth naming directly: Business Central does not ship a visual production scheduler. It has a capable manufacturing module underneath, with production orders, routings, work and machine centers, and both finite and infinite capacity calculations. What it does not have, out of the box, is a Gantt-style planning board where a scheduler can see every order across every work center at once and drag one into a different slot. For a make-to-order or configure-to-order shop where the schedule changes twice before lunch, that missing piece is not cosmetic. It is the difference between planning and reacting.

What Business Central Actually Gives You Natively

It helps to be precise about where the native functionality stops, because vendors on both sides of this conversation tend to blur the line. Business Central’s core manufacturing app calculates capacity using calendars assigned to work and machine centers, supports forward and backward finite loading, and will flag overloads through capacity planning worksheets. A planner can run a capacity availability report, look at a load percentage by resource, and reschedule a production order’s dates through the order card. All of that is real, and for a job shop running a handful of routings with predictable sequencing, it can be enough.

Where it breaks down is visualization and speed of adjustment. The native screens are list-based: rows of orders, rows of capacity figures, filtered views that require a planner to hold the whole picture in their head. There is no single canvas that shows Order 4021 sitting on the CNC line from 2:00 to 6:00 while Order 4033 is queued behind it, waiting on a changeover. When a rush order lands, or a machine goes down mid-shift, the planner is reconciling several list views rather than looking at one board and dragging a block. That reconciliation work is exactly what visual scheduling tools were built to remove, and it is why the category exists as a distinct add-on market inside the Business Central ecosystem rather than a feature Microsoft has folded into the base product.

Where a Visual Production Scheduler Actually Fits

Search AppSource for Business Central manufacturing extensions and you will find several purpose-built scheduling tools, the most established being Netronic’s Visual Production Scheduler and its more advanced sibling, Visual Advanced Production Scheduler, alongside other entrants like Graphical Scheduler and MxAPS. These are not replacements for Business Central’s manufacturing data model; they sit on top of it, reading and writing directly to the same production order and capacity tables so nothing has to be exported to Excel or re-entered anywhere. What they add is the missing visual layer: a Gantt-style board that typically splits into two views, one answering “will I hit my delivery dates” by laying out orders against the calendar, and a second showing utilization by work or machine center so a scheduler can spot an overloaded resource before it becomes a missed shipment.

A shop floor worker holding a tablet showing a drag-and-drop visual production schedule next to CNC machining equipment

The interaction model is the actual value. Instead of opening a production order, changing a date field, and re-running a capacity check, a scheduler drags an operation block to a new slot and sees the conflict, or the lack of one, immediately. Reassigning an order from one machine center to another equivalent one takes the same drag-and-drop motion. Vendors in this space report meaningful gains in on-time delivery from customers who adopt this pattern, though as with any vendor-published figure, it should be treated as directional rather than a guaranteed outcome for every shop floor, since the actual result depends heavily on how disciplined the underlying routing and work center data already is.

The Decision a CFO or IT Director Actually Has to Make

None of this means every Business Central manufacturer needs a scheduling add-on on day one. A shop with two or three work centers and a stable, low-mix production schedule may genuinely be fine with the native capacity worksheets, and adding a third-party module there would be solving a problem that does not yet exist. The decision point is usually mix and volume: once a plant is juggling more than a handful of concurrent orders across multiple resources, with routing changes, rework, or expedites showing up weekly rather than monthly, the native list-based tools stop scaling with the complexity of the floor.

The practical mistake we see during Business Central selection and implementation projects is treating visual scheduling as something to revisit after go-live, almost as an afterthought bolted on once the finance and inventory modules are stable. That ordering gets the cost and the change-management burden backwards. Licensing a scheduling add-on is a separate line item, typically priced per named user or per environment, and it needs its own implementation time to map routings and work centers correctly, since the visual tool is only as good as the underlying capacity data it renders. Building that into the original project budget and timeline, rather than treating it as a post-go-live patch, avoids a second wave of user training and a second change request against a system that finance already considers “done.”

There is also a governance dimension worth flagging to IT: because these add-ons write directly back into core manufacturing tables, they need the same change-management scrutiny given to any other extension touching production data, including how they behave during version upgrades and whether the vendor maintains compatibility with the current Business Central release cadence rather than lagging behind it.

What to Ask Before You Buy

For a decision-maker evaluating this category, a few questions cut through most of the vendor marketing. First, does the tool read and write directly to standard Business Central production order and capacity tables, or does it maintain a shadow schedule that has to be reconciled back into the ERP, since the latter reintroduces exactly the synchronization risk the tool is supposed to eliminate. Second, does it support both finite capacity visualization and the specific constraint types your floor actually deals with, such as sequence-dependent changeovers or shared tooling across machine centers, rather than a generic Gantt view that looks good in a demo but cannot represent your real constraints. Third, what does the implementation actually involve beyond installing the extension, since the value of any visual scheduler depends entirely on routing and work center data being accurate before the drag-and-drop layer goes on top of it.

Getting this right is less about picking the “best” scheduling tool in the AppSource marketplace and more about being honest, early in a Business Central project, about whether the plant’s actual scheduling complexity requires this layer at all. Routeget has walked several manufacturing clients through exactly this evaluation during Business Central selection, and the pattern holds: the shops that budget for scheduling visibility from the start avoid the whiteboard relapse that pulls a supervisor back to manual planning three weeks after a system they were told would solve this problem for them.


#BusinessCentral #ManufacturingERP #ProductionScheduling #ShopFloorVisibility #ERPImplementation #DigitalTransformation

IoT Intelligence Is Out in Dynamics 365 Asset Management. Sensor Data Intelligence Moves the Azure Bill to You.

IT operations manager reviewing an asset health and sensor monitoring dashboard in a manufacturing control room

An IT director running Dynamics 365 Supply Chain Management for a mid-size manufacturer recently got a message she wasn’t expecting: the IoT feature her maintenance team had been quietly piloting inside Asset Management was being replaced. Not patched, not extended. Replaced, with a new name, a new architecture, and a new owner for the Azure infrastructure underneath it. Microsoft’s own documentation is blunt about it: “Do not start any new projects based on the existing IoT Intelligence feature.” The successor, Sensor Data Intelligence, is where new work is supposed to go instead.

This isn’t a minor renaming exercise. It’s a genuine shift in who is responsible for the cloud plumbing behind predictive maintenance in Dynamics 365, and it lands squarely on any organization that has connected sensors, meters, or PLCs to Asset Management, or has been planning to. For CIOs and IT directors weighing whether to invest in condition-based maintenance on the Dynamics 365 platform, the mechanics of this transition matter more than the rebrand suggests.

What Actually Changed

IoT Intelligence was the original bridge between physical assets and Asset Management inside Dynamics 365 Supply Chain Management. Sensor readings, whether from a vibration monitor on a pump or a temperature probe on a cold-storage unit, flowed into Azure IoT Hub and then into Supply Chain Management, where they could trigger alerts, feed maintenance plans, or update asset condition records. Critically, Microsoft managed much of that Azure infrastructure on the customer’s behalf. It worked, but it was rigid: limited room to customize the data pipeline, and friction when a customer wanted to bring in sensor data from a system that wasn’t a clean fit for the prebuilt model.

Sensor Data Intelligence, now in preview and documented as an updated, renamed version of IoT Intelligence, rebuilds that pipeline with a different deployment philosophy. Instead of Microsoft hosting and managing the Azure components, the organization deploys them into its own Azure subscription. Setup runs through an onboarding wizard rather than the manual configuration in Lifecycle Services that IoT Intelligence required. On paper, that is a usability improvement. In practice, it also means the Azure resources involved, connecting sensors through Azure IoT Hub and the broader industrial IoT ingestion pattern Microsoft points customers toward, now belong to the customer’s tenant, not Microsoft’s.

Wireless industrial sensor mounted on factory equipment with a technician viewing vibration data on a tablet

Why Microsoft Restructured It This Way

The stated reasons are customization and integration. A Microsoft-managed pipeline is easy to stand up but hard to bend. Organizations that wanted to route sensor data through an existing Azure Digital Twins model, apply their own retention and encryption policies, or connect equipment from a vendor whose telemetry format didn’t match the built-in assumptions were working against the platform rather than with it. Moving deployment into the customer’s own subscription removes that ceiling. It also happens to align with a broader pattern across the Dynamics 365 and Power Platform ecosystem this year, where more of the underlying Azure footprint is being handed to customers to own and configure directly, rather than abstracted away entirely.

That tradeoff is worth naming plainly, because it changes who needs to be in the room for this decision. Adopting Sensor Data Intelligence is no longer purely a Dynamics 365 configuration project that a functional consultant can carry alone. It is an Azure architecture decision, and it needs a cloud engineering resource involved from the start, someone who can make calls about network isolation, subscription structure, and how sensor telemetry ingestion fits into the organization’s existing Azure governance model.

The Six Scenarios Sensor Data Intelligence Is Built Around

Microsoft’s documentation frames the preview around six specific business scenarios, and each one maps to a different maintenance or production pain point rather than being a generic “connect your sensors” pitch. Asset downtime tracking uses sensor readings to measure actual machine efficiency against expected performance, giving maintenance planners a real-time efficiency signal instead of relying on manually logged downtime events after the fact. Asset maintenance ties incoming sensor readings directly to the goal of reducing maintenance cost, which in practical terms means condition data can inform when a maintenance plan should actually trigger rather than running purely on a fixed calendar schedule. Machine status notifications alert production planners the moment equipment goes down, cutting the lag between a physical failure and a scheduling response. Product quality scenarios compare live sensor readings against defined quality thresholds, catching drift before it turns into a batch of rejected output. Production auto-reporting uses sensor thresholds to automatically report finished quantities, removing a manual data-entry step from the shop floor. And production delay tracking compares actual cycle time against planned cycle time, surfacing bottlenecks that would otherwise only show up after the fact in a variance report.

None of these six scenarios require a from-scratch build. They come as templates within the new model, which is a meaningful head start for organizations that don’t have the internal bandwidth to design an IoT-to-ERP data pipeline from first principles. But a template is not the same as a finished solution, and each one still needs to be mapped against the specific sensors, thresholds, and maintenance workflows already in place at a given plant.

What Belongs on a Decision-Maker’s Checklist

The preview status is the first thing worth sitting with. Microsoft’s own terms are explicit that preview features aren’t meant for production use and carry restricted functionality, so any organization currently relying on IoT Intelligence for live maintenance decisions is not looking at a drop-in replacement they can adopt today. They are looking at a migration to plan for, on a timeline Microsoft has not published in its formal deprecation schedule. Checking Microsoft’s removed and deprecated features documentation for Supply Chain Management shows plenty of other retired capabilities listed with version numbers and dates; IoT Intelligence, as of this writing, is not one of them. That gap between “don’t build new things on this” and an actual scheduled retirement date is exactly the kind of ambiguity that should push a cautious organization toward an early conversation with Microsoft or its implementation partner rather than a wait-and-see approach.

Budget conversations need to happen earlier than usual, too. When Microsoft manages the Azure components behind a feature, the cost of that infrastructure is effectively invisible to the customer, folded into the overall service. Once the deployment sits in the customer’s own subscription, IoT Hub throughput, storage, and any downstream compute for the sensor data pipeline become line items the organization has to provision, monitor, and pay for directly, governed by whatever cost management and tagging discipline already applies to the rest of its Azure estate. That is not necessarily a bad outcome. Full ownership of the infrastructure also means full visibility into what it costs and full control over where it runs, which matters for organizations with strict data residency or network segmentation requirements that a Microsoft-managed black box never let them satisfy cleanly.

Finally, this is a good moment to audit what IoT Intelligence usage already exists in the environment, even informally. A maintenance team that connected a handful of sensors as a proof of concept two years ago may not have flagged that project to IT as a dependency, and a preview migration is the wrong time to discover a shadow deployment that nobody owns.

The Bigger Pattern Behind the Rename

Sensor Data Intelligence is a small feature in the context of the broader Dynamics 365 Supply Chain Management platform, but it is a clear example of a decision Microsoft is making more often across the ecosystem: put the Azure infrastructure in the customer’s hands and trade managed simplicity for architectural control. That is generally the right long-term direction for organizations with mature cloud governance. It is a heavier lift for organizations that treated Dynamics 365 as a self-contained ERP system and never built out the Azure engineering capability to match. Teams at Routeget Technologies that have supported Asset Management deployments through platform transitions like this one typically start by mapping the existing sensor footprint and the target Azure subscription model before touching the Sensor Data Intelligence onboarding wizard itself, since getting that architecture right the first time avoids a second migration a year later.


#AssetManagement #SensorDataIntelligence #IoTinERP #PredictiveMaintenance #AzureGovernance #SupplyChainAutomation

Dataverse Plugin Packages Are Code-First Now. Your Azure DevOps Pipeline Still Has to Script Around Them.

Solutions architect and developer reviewing a Dataverse deployment pipeline diagram on an office monitor

A solutions architect on a mid-size D365 F&O implementation recently ran into a problem that had nothing to do with business logic. Her team had finally moved their plugin assemblies into proper NuGet-based Dataverse plugin packages, the newer code-first model that the Power Platform CLI now supports directly. The build worked. The package generated correctly. And then the pipeline stalled, because nobody could answer a simple question: how do you tell Azure DevOps to actually deploy the thing you just built, when Microsoft’s own build tools extension has no task for it?

That gap is worth understanding in detail, because it sits at the exact point where Dataverse plugin development is genuinely improving and where its ALM tooling has not caught up.

Solutions architect and developer reviewing a Dataverse deployment pipeline diagram on an office monitor

From Manual Registration to Code-First Packages

For most of the last decade, deploying a Dataverse plugin meant compiling a class library in Visual Studio, opening the Plugin Registration Tool, and manually selecting an assembly to register or update. It worked, but it kept plugin deployment outside the discipline that governs everything else in a mature ALM pipeline: predictable artifacts, versioned builds, and a repeatable path from commit to environment.

The Power Platform CLI changes that equation with two commands: pac plugin init, which scaffolds a plug-in class library project, and pac plugin push, which imports the resulting artifact into Dataverse. The output of a build is no longer a loose assembly file. It is a NuGet package, generated automatically in the bin\outputPackages folder on every build, containing the plugin assembly and its dependencies bundled together. That single change, treating the plugin as a proper package rather than a file you happen to compile, is what makes plugin code finally look like the rest of a modern .NET pipeline.

What Dataverse Plugin Packages Actually Solve

The practical win is dependency handling. Under the old model, any third-party or shared library your plugin referenced had to be merged into the assembly or registered separately, and both approaches created their own headaches around versioning and duplication across solutions. A plugin package bundles dependent assemblies inside the same NuGet artifact, so the whole thing deploys and updates as one unit.

Signing works differently here too, and it is worth getting the policy decision right early rather than discovering it mid-project. Microsoft’s own guidance is explicit that signing is all-or-nothing: if the primary plugin assembly is strong-name signed, every dependent assembly in the package must be signed as well. Most teams find this impractical once they start pulling in third-party libraries they do not control, which is why pac plugin init exposes a --skip-signing flag, and why it has effectively become the default choice for anyone using dependent assemblies rather than a single self-contained plugin.

The Immutability Trap

Here is where the model’s real character shows up, and where a team can get burned if nobody flags it in advance. Once a plugin package is created in Dataverse, its name and version are fixed. An attempt to change either afterward, including through the API, simply fails. Every build produces a package with a new version embedded in its filename, which means there is no such thing as “redeploy the same package again.” Each build is a new, uniquely identified artifact from Dataverse’s point of view, whether you intended that or not.

That has two consequences that matter for pipeline design. First, if a plugin update removes an assembly or a type that is still referenced by an active plugin step registration, Dataverse rejects the update outright. You have to go remove or repoint those step registrations first, then update the package, not the other way around. Second, you cannot unregister a package at all while any of its assemblies still have active step registrations attached to them. Both rules are sensible from a data-integrity standpoint, but they mean plugin retirement has to be sequenced deliberately: deregister the steps, confirm nothing else depends on the assembly, and only then remove or replace the package.

One independent practitioner account, documented on the .NET Dust blog in 2024, captured how disruptive the versioning behavior can be during ordinary iterative development, well before any pipeline is involved. Because pac plugin push has no built-in notion of “the current build,” the developer had to script around it: an MSBuild target increments the file version before compilation, a post-build event persists that value into the project file through a small helper utility, the NuGet package picks up the new version automatically, and only then does an automated pac CLI call push the exact resulting filename. What should be a single command turned into a four-step workaround, built by one engineer, to get a repeatable local deployment loop. That is a reasonable thing for an individual developer to solve on their own machine. It is not something you want reinvented independently by every team building a Dataverse ALM pipeline.

The Build Tools Gap

That last point is the one worth taking to whoever owns your ALM strategy. Microsoft’s Power Platform Build Tools extension, the standard toolkit for Dataverse pipelines in Azure DevOps and GitHub Actions, covers an extensive set of operations: importing, exporting, packing, and unpacking solutions, applying upgrades, managing environments, running the Power Platform Checker, and even a preview set of catalog-submission tasks. Reviewing the current task reference, plugin packages and pac plugin push are not among them. There is no first-class, Microsoft-supported pipeline task for deploying a plugin package, in contrast to the mature tooling that already exists for solutions.

In practice, that means every team adopting code-first plugin packages has to write its own pipeline stage: typically a script task that installs a pinned version of the PAC CLI, authenticates against the target environment (a service principal, not a personal login, for anything beyond a developer sandbox), locates the build output, and issues the push. None of that is exotic engineering. It is, however, unsupported custom scripting sitting next to a set of Microsoft-maintained tasks that get security updates, documentation, and predictable behavior across CLI versions. That asymmetry is easy to miss until a CLI update quietly changes an argument name and a script that nobody has looked at in eight months starts failing in production.

Developer typing on a laptop with a monitor showing an abstract NuGet package deployment graphic

Building This Into an ALM Pipeline Properly

A few decisions are worth making explicit rather than leaving to whichever developer happens to write the first plugin deployment script. Pin the PAC CLI version in the pipeline definition itself, not just on developer machines, so a CLI upgrade cannot silently change push behavior in production. Treat the plugin push step as its own reviewed pipeline stage with the same environment gating and approval flow as solution deployment, rather than a script someone bolted on during a sprint to unblock a release. Decide the assembly-signing policy at the team or center-of-excellence level, since the all-or-nothing signing rule effectively locks in a convention for every future package once dependent assemblies enter the picture.

Sequence retirements carefully. Before removing or consolidating an old plugin package, confirm which step registrations still point at it and clear those first, since Dataverse will otherwise block the change regardless of what your pipeline script assumes should happen. And build the versioning logic into the pipeline itself, following the pattern the .NET Dust workaround demonstrated, rather than trusting a developer’s local environment to produce a consistently versioned artifact that a shared pipeline can then find and deploy.

None of this makes the code-first plugin package model a bad idea. It is a genuine improvement over registering assemblies by hand through a desktop tool, and it brings plugin code closer to how the rest of a .NET codebase is built and shipped. The catch is that Microsoft shipped the authoring half of that story before the deployment half, and the gap between them is exactly where implementation teams are currently improvising. Firms that have already built Dataverse ALM pipelines from the ground up, Routeget Technologies among them, have generally closed that gap with a small, explicitly maintained script stage rather than an ad hoc one, which is the difference between a pipeline that survives a CLI version bump and one that quietly breaks the next time someone updates it.


#Dataverse #DataversePlugins #PowerPlatformALM #AzureDevOps #ExtensibilityAndProDev #EnterpriseArchitecture

Copilot Studio ROI Measurement: Why Resolution Rate Isn’t Enough Before You Scale

Operations manager reviewing a customer service agent performance dashboard in an enterprise office

A customer service director at a mid-market manufacturer recently walked into a steering committee meeting with a number she was proud of: her Copilot Studio agent was resolving 78 percent of engaged sessions without a human handoff, up from 61 percent three months earlier. The CFO asked one question that stopped the meeting cold. Had customer satisfaction moved in the same direction? It hadn’t. CSAT had drifted down two points over the same period. The agent was closing more conversations. It was not clear it was actually helping more people.

That gap is becoming the central question for any organization running a Copilot Studio pilot with an eye toward production scale. Copilot Studio ROI measurement has matured considerably over the past year, with Microsoft now publishing a formal value framework alongside the platform’s built-in analytics. But the metrics that make a pilot look successful to an internal audience are not automatically the metrics that justify expanding it to every customer-facing channel a company operates. Getting that distinction right, before the budget request goes to the board, is the difference between a scaling decision built on evidence and one built on a single flattering number.

Operations manager reviewing a customer service agent performance dashboard in an enterprise office

What the Monitor Tab Actually Tells You

Copilot Studio’s built-in analytics, accessible from the Monitor tab in the maker portal, track session outcomes across four categories: resolved, escalated, abandoned, and unengaged. Resolution rate is calculated as the share of engaged sessions that end in a resolved state, and Microsoft’s documentation is specific about how “resolved” gets determined. A session counts as resolved either when a user explicitly confirms an answer solved their problem, or, more quietly, when the user simply doesn’t respond after receiving one. That second path, an implied resolution, is where the manufacturer’s numbers started to diverge from reality. A user who gives up on a chatbot and closes the browser tab looks statistically identical, in the resolution rate calculation, to a user who got exactly what they needed.

Escalation rate and abandonment rate round out the core picture: escalation tracks handoffs to a human agent, split into system-intended handoffs (the bot routes on purpose), system-unintended handoffs (something went wrong), and user-requested handoffs. Abandonment tracks sessions that time out without either outcome. Engagement rate measures the share of total sessions that move past a passive greeting into an actual topic or system flow. CSAT, on a straightforward one-to-five scale, is the metric most likely to contradict a rosy resolution number, and it deserves at least as much weight in a scaling decision as the headline resolution figure, not a supporting-cast role beneath it.

The Quality-Versus-Throughput Trap

The pattern the manufacturer ran into has a name among practitioners who implement these agents for a living: the quality-versus-throughput trap. A resolution rate climbing while CSAT falls is a specific, checkable warning sign, not statistical noise. It usually means the agent is getting faster at closing sessions without getting better at actually answering the underlying question, and implied resolution is the mechanism that lets that happen without tripping any alarm in the standard dashboard view.

The fix isn’t complicated, but it does require deliberately pulling two numbers into the same review rather than reporting resolution rate in isolation. Any pilot-to-production decision should require both metrics on the same slide, tracked over the same window, with a defined tolerance for how far they’re allowed to diverge before the rollout pauses for investigation. It’s also worth checking topics with unusually high implied-resolution counts specifically, since a handful of poorly scoped topics are often responsible for most of the gap, and fixing those few topics can move the CSAT number more than a platform-wide tuning pass would.

Two IT professionals reviewing a chatbot conversation on a laptop screen

Microsoft’s Own Framework for Copilot Studio ROI Measurement

Microsoft has published a genuinely useful, if underused, structure for this problem in its Copilot Studio guidance documentation, organized around four value drivers: efficiency, quality, revenue, and strategic value. Each driver comes with its own pricing logic rather than a single blended score. Efficiency is priced as hours returned multiplied by a fully loaded hourly rate. Quality is priced as the change in error rate multiplied by transaction volume and the cost of an error. Revenue is priced as a conversion delta multiplied by volume, unit revenue, and an attribution discount that accounts for the agent not being the only factor in a customer’s decision. Strategic value, the hardest to quantify, folds in things like optionality, talent retention, and organizational resilience.

The most concrete piece of this framework is a formula Microsoft calls Agent Assisted Hours, which converts raw session data into a labor-hours estimate. It weights sessions that cite a knowledge source and sessions that don’t, applies outcome weights of 1.0 for resolved sessions and 0.7 for escalated or abandoned ones, and multiplies the result by a default time-savings assumption of six minutes per reference before dividing by sixty to get hours. Microsoft’s own worked example uses 10,000 monthly sessions, split between sessions with knowledge citations and sessions without, arriving at roughly 1,440 assisted hours per month. At the platform’s default hourly rate of 72 dollars, drawn from U.S. Bureau of Labor Statistics compensation data, that works out to a bit over 100,000 dollars in monthly value and something in the neighborhood of 1.2 million dollars annualized. Whether that specific rate or those specific session ratios apply to any given organization is a separate question, but the formula itself is a far more defensible way to talk to a CFO than “resolution rate went up.”

Where the Numbers Get Murky

Three complications are worth flagging before anyone builds a board presentation around these figures. First, Microsoft’s own documentation is inconsistent on how long a session has to sit idle before it counts as abandoned, with one guidance page citing thirty minutes and another citing an hour. That’s a small detail, but it changes the abandonment denominator enough to matter if two teams are comparing numbers pulled from different reference points.

Second, and more consequential for organizations running both a Copilot Studio agent and a Dynamics 365 Omnichannel contact center, the two systems measure resolution, escalation, and abandonment differently by design. Copilot Studio analytics track only the bot’s portion of an interaction, while Omnichannel analytics track the full lifecycle including the human agent’s part of the conversation. A single customer interaction can register as several distinct sessions in Copilot Studio’s counting logic while showing up as one session in Omnichannel. Microsoft states this plainly in its own guidance. It means a CIO comparing a “before Copilot Studio” baseline against an “after Copilot Studio” number needs to be certain both figures came from the same measurement system, not two systems with similarly named metrics that are quietly counting different things.

Third, the billing model underneath all of this changed in September 2025, when Copilot Studio moved from message-based billing to Copilot Credits. Microsoft’s admin center documentation describes a credit as one user interaction generating one response, a simple one-to-one framing. Partner implementers who have actually run production traffic describe something messier: a single turn that triggers generative grounding plus a connector action can consume well over ten credits, which means historical message-volume estimates from before the change can’t be used to forecast credit consumption after it. Microsoft does publish a Copilot Studio Agent Usage Estimator specifically because the credit math isn’t intuitive from the documentation alone, and any organization sizing a production rollout should run its own traffic patterns through that tool rather than extrapolating from a pilot that ran under lighter, less representative usage.

A Practical Checklist Before the Scaling Decision

None of this argues against scaling a Copilot Studio agent. It argues against scaling on the strength of one number that happens to look good in isolation. Before a pilot moves to production, pair resolution rate with CSAT on the same review cycle and set a divergence threshold that triggers a pause. Pull actual credit consumption from the Power Platform admin center’s agent-level usage view, not a projection based on pilot-stage traffic, since real usage patterns tend to run heavier than early testing suggests. Build a test set using Copilot Studio’s Agent Evaluation feature, which reached general availability in March 2026 and lets makers validate topic reliability against up to a hundred defined cases before exposing a scaled version to live customers. And export feedback comments and transcripts to an external store on a regular cadence, since the native Analytics tab retains free-text feedback for only twenty-eight days, which is not long enough to support a continuous improvement program that spans a full budget cycle.

The organizations getting real value from these agents are the ones treating the Monitor tab as a starting point for questions, not a finished scorecard. Routeget Technologies has walked several clients through exactly this transition, from pilot metrics that looked convincing on their own to a value model that could actually survive a CFO’s second question. That second question is usually the one that matters most.


#CopilotStudio #AgenticAI #CustomerServiceAI #AIGovernance #EnterpriseAI #DigitalTransformation

Power Automate API Request Limits Are Losing Their Grace Period. Most Dynamics 365 Integrations Aren’t Ready.

IT solutions architect reviewing a Power Automate integration flow dashboard on a large screen in an enterprise operations center

A finance operations lead watching a month-end close dashboard notices something odd: a batch of vendor invoices has been sitting in “waiting” status for eleven minutes. No error message, no failed run in the flow history, just silence. The Power Automate flow pulling records from Dataverse and pushing them into a document management system hasn’t crashed. It has been throttled, and almost nobody on the team knows that’s a distinct condition from a broken flow, let alone what triggers it or how long it lasts.

That gap in understanding is about to matter a lot more. Microsoft has spent the better part of the last two years quietly running Power Automate’s API request limits in what it calls a transition period: real entitlements exist on paper, actual enforcement is loose, and most tenants are running well past their official limits without consequence. That period has a stated end point, tied to when Power Platform Request usage reporting in the admin center reaches general availability, plus roughly six months. Teams that built integration flows assuming today’s permissive behavior is permanent are going to have an uncomfortable conversation with their CIO when enforcement tightens.

What Actually Counts Against Your Limit

The mental model most consultants carry around, that a “request” means one API call your flow makes to an external system, undersells how quickly limits get consumed. Every action in a flow run generates a request, whether it succeeds or fails. An action sitting inside an Apply to Each loop generates one request per item processed, not one request for the loop as a whole. Pagination counts separately too, so a flow that queries a Dataverse table with 50,000 rows and pages through results in batches of 5,000 will burn ten requests just retrieving data it hasn’t done anything with yet.

This is where a lot of Dynamics 365 integration flows get into trouble without anyone noticing during development. A flow built and tested against a sandbox environment with a few hundred sales order records behaves completely differently once it hits production volume. The loop that ran fine at fifty iterations in UAT becomes five thousand iterations against the live sales order table, and each of those iterations might trigger two or three downstream actions: a lookup, a field update, a notification. What looked like a lightweight automation in testing turns into a five-figure daily request count in production.

Developer typing on a laptop with a blurred Power Automate cloud flow diagram visible on a monitor in the background

The Power Automate API Request Limits That Actually Matter

Most teams that have heard of Power Automate throttling think of it as a single ceiling. In practice there are three separate mechanisms stacked on top of each other, and hitting any one of them produces the same frustrating symptom: a flow that stops making forward progress without a clear error.

The first is the 24-hour rolling entitlement, calculated per user for licensed accounts and pooled at the tenant level for application users and service accounts. A user with a standard Power Automate per-user or Dynamics 365 base license carries a 40,000 request allowance in any trailing 24-hour window. That window doesn’t reset at midnight. It slides continuously, so a burst of activity at 9 a.m. today is still being counted against the limit at 9 a.m. tomorrow, and any requests left unused simply expire rather than carrying forward.

The second is a five-minute burst cap of 100,000 requests, which applies independently of how much daily entitlement remains. A flow with a per-flow Process license carrying 250,000 requests per day can still get throttled mid-run if it tries to push too many of those requests through in a short burst, which is exactly what happens when an integration flow processes a large batch without pacing itself.

The third, and the one with the sharpest teeth, is continuous throttling over time. A flow that stays in a throttled state for 14 consecutive days gets turned off automatically. It can be reactivated, but if the underlying request pattern hasn’t changed, it cycles back into the same state. For a scheduled integration that runs nightly, two weeks of silent throttling is enough time for a genuinely broken process to look, from the outside, like nothing more than a slow week.

Architecting Integrations to Survive Enforcement

None of this means Power Automate is a poor choice for high-volume Dynamics 365 integration work. It means the flows need to be built with request budgets in mind from the start rather than retrofitted after a production incident.

Batching is the highest-leverage change available to most teams. Dataverse supports native batch operations that bundle multiple create, update, or delete operations into a single request rather than issuing one request per record. A flow rewritten to batch 100 record updates into a handful of batch calls instead of 100 individual actions can cut its request footprint by well over ninety percent for that segment of the process. This is worth doing even on flows that aren’t currently near any limit, because the same restructuring also improves run time and reduces the blast radius of a partial failure.

Child flows deserve more architectural attention than they usually get. Breaking a single monolithic flow into a parent that orchestrates and several children that each handle a bounded chunk of work makes it possible to apply concurrency control and pacing at a granular level, rather than trying to throttle an entire end-to-end process as one unit. Concurrency control settings on the trigger, often left at their defaults, are one of the more overlooked levers here: capping how many instances of a flow can run in parallel directly controls how fast it can burn through the five-minute burst allowance.

Trigger conditions matter more than most teams treat them. A flow that fires on every Dataverse row update and then checks conditions inside the flow body has already consumed a trigger execution and started accumulating requests before it decides the record doesn’t actually need processing. Moving that filtering logic into the trigger condition itself, evaluated before the flow run even starts, is free request savings that costs nothing to implement.

For flows that are genuinely high-volume by design, such as a real-time integration syncing order status between D365 Finance and Operations and an external logistics platform, the right answer may simply be licensing rather than architecture. A per-flow Process license carries a 250,000 request daily allowance on its own, and multiple Process licenses can be stacked on a single flow inside a solution, each one adding another 250,000 to that flow’s dedicated entitlement. For tenants not ready to change licensing, the Power Platform Request Capacity add-on adds 50,000 requests per 24 hours per pack and can be layered onto existing entitlements as a stopgap.

Get Ahead of the Reporting Gap

The Power Platform admin center’s usage reports are still catching up to the complexity of the limits themselves. Current reporting covers Power Automate API requests reasonably well but doesn’t yet give a clean picture of Dataverse, Copilot Studio, or Power Apps consumption in the same view, which means a team relying solely on the admin center dashboard is working from an incomplete picture of its actual request footprint. Until that reporting matures, the more reliable approach is instrumenting flows directly: logging request counts per run, watching for 429 responses in run history, and treating a spike in run duration as an early warning sign rather than waiting for a flow to get switched off.

Organizations we’ve worked with on Dynamics 365 and Power Platform integration architecture are increasingly building request budgeting into the design review for any flow expected to process more than a few thousand records a day, the same way they’d review a database query plan before it goes to production. That habit is worth adopting now, while the transition period still offers room to fix a poorly architected flow before enforcement makes the fix urgent instead of optional.


#PowerAutomate #APIRequestLimits #DynamicsIntegration #PowerPlatformGovernance #IntegrationArchitecture #EnterpriseAutomation

Dynamics 365 Contact Center Playbooks Let Supervisors Write Routing Logic in Plain English. IT Still Has to Govern It.

Contact center supervisor reviewing a live conversation routing and queue dashboard

It is 8:40 on a Monday morning and a contact center supervisor at a mid-size distributor is watching a queue for premium accounts back up past the fifteen-minute mark. Two years ago, fixing that meant opening a ticket with IT, waiting for someone who understands the routing rule builder to free up an afternoon, and hoping the change didn’t collide with three other rules already live on that queue. Today, in a growing number of Dynamics 365 Contact Center environments, that supervisor can type a sentence: if a Gold-tier customer waits more than thirty seconds with no agent available, raise their priority every thirty seconds until someone picks up. The system takes it from there.

What Dynamics 365 Contact Center Playbooks Actually Do

Conversation orchestration, the feature behind this shift, is not simply a rebrand of unified routing’s existing rule engine. Traditional unified routing evaluates a conversation once, at the moment it arrives, against a static classification ruleset and assigns it to a queue. Dynamics 365 Contact Center playbooks instead monitor a conversation across its full lifecycle and respond as conditions change: wait time climbing, an agent signing out, a queue moving from staffed to unstaffed outside business hours. The playbook itself is authored through a guided template rather than a rule-tree editor. An administrator (Microsoft’s documentation specifically calls out System Administrator and Omnichannel Administrator roles, not a developer role) picks a scenario such as dynamic prioritization, overflow handling, or bullseye expansion of the eligible agent pool, attaches up to ten conditions built from context variables like customer tier or region, and writes the logic as a sentence rather than a nested if/then structure.

Underneath that plain-language input, a language model converts the sentence into a structured runtime policy the routing engine can actually execute. That detail matters more than it sounds like it should, and we will come back to it.

The Real Change: Configuration Authority Moves Off IT's Desk

For a Contact Center Director, the operational upside is straightforward to state. Routing changes that used to require a developer familiar with the classification rule syntax, plus a change window, plus regression testing against every other rule on that queue, can now be drafted, tested in draft status, and published by the person who actually owns the queue’s performance. Microsoft’s own framing of the feature leans hard into this: playbooks are meant to be authored and published “within minutes” by operations staff, not routed through an IT backlog. For an organization running twenty or thirty queues across voice and chat, each with its own seasonal patterns and VIP handling rules, that is a genuine reduction in the lag between noticing a problem and fixing it.

It also changes who is accountable for a bad outcome, and that is where the governance conversation needs to start well before rollout, not after the first incident.

Why Dynamics 365 Contact Center Playbooks Need a Governance Layer Before Broad Rollout

Microsoft’s own documentation is candid about a specific limitation worth reading closely: because the system uses a language model to translate a plain-language playbook into structured runtime logic, the converted output might not fully capture what the administrator actually intended, and any deviation can only be identified once the playbook is running against live conversations. In practice, that means a supervisor could write a sentence that sounds unambiguous to a person and have it compiled into routing logic that behaves slightly differently than expected, with no warning until customers start landing in the wrong place. This is not a hypothetical edge case worth dismissing. It is the stated behavior of the feature, documented in the same page that describes how to build a playbook.

That single fact should shape how any organization rolls this out. Treating a published playbook as production logic the moment it goes live, with no observation period, skips the one safeguard the platform actually gives you: the Draft status. A playbook can sit in Draft indefinitely while an administrator reviews it, and Microsoft’s diagnostics tooling for unified routing extends to playbooks as well, giving supervisors a way to watch what a rule is actually doing against real traffic before trusting it unattended. Any rollout plan that skips a monitored soak period on a low-risk queue, in favor of pushing straight to a high-volume VIP line, is accepting a risk the documentation already flagged.

Contact center team configuring routing logic while agents handle live conversations in the background

There is a second governance thread that CIOs and legal or compliance stakeholders should not miss. Microsoft’s supplemental terms for the feature include an explicit disclaimer that conversation orchestration is not intended for, and should not be used to make, decisions affecting an employee’s compensation, rewards, seniority, or other employment-related entitlements, and that organizations remain responsible for complying with employee monitoring and consent laws in their jurisdiction. That guardrail exists because the underlying mechanism, real-time monitoring of live conversations and automated action based on evolving conditions, sits close enough to workforce monitoring that Microsoft felt the need to draw the line explicitly rather than leave it implied. Any organization piloting playbooks for agent-assignment scenarios, where the system is reconnecting customers with representatives they spoke to previously, should have its HR and legal teams review the scope of what is being monitored and why before the first playbook touches a live queue with actual agents on it.

Rollout Considerations Worth Deciding Before the First Playbook Goes Live

A few practical constraints shape how this should actually be piloted. The feature currently supports voice and live chat channels only, so any organization running significant volume through digital messaging channels, social, or SMS will need to keep those on the existing classification ruleset for now. Microsoft has stated plans to expand channel coverage, but has not committed to a date at the time of writing, so it should not be assumed for planning purposes. The platform also enforces validation that prevents publishing two playbooks for the same scenario on the same queue, which forces a useful discipline: one queue cannot end up with silently conflicting logic, but it also means teams need to decide up front which playbook owns a given scenario rather than layering fixes on top of each other the way ad hoc rule trees sometimes accumulate over the years.

Licensing is the other piece worth confirming before a pilot gets too far along. Conversation orchestration carries its own licensing requirement separate from base Contact Center or Customer Service entitlements, and organizations on a pay-as-you-go consumption model need an Azure subscription with billing configured before the feature will run in production. This is easy to miss during a proof of concept built in a sandbox environment and then discover as a blocker when it is time to move to a live queue, so it is worth confirming with a Microsoft licensing specialist as part of the pilot scope rather than after.

Where This Leaves a CIO Weighing the Rollout

The case for conversation orchestration is not that natural-language configuration is a novelty. It is that it collapses the distance between the person who understands a queue’s real-world behavior and the person who can change how it routes, without requiring both of those people to be the same person or to coordinate through a ticket queue. That is a legitimate operational gain, particularly for organizations whose contact center staffing and customer tiers shift with seasonality or promotions. But the platform’s own documentation hands you the risk list: translation drift between what was written and what actually runs, employment-law boundaries around monitoring, and a validation layer that assumes disciplined ownership of which playbook governs which scenario. None of those are reasons to skip the feature. They are the checklist for a rollout plan that treats a published playbook the way any other piece of production logic deserves to be treated, with a review step, an observation period, and a named owner. Organizations that have gone through this kind of change management before, when unified routing itself first replaced manual queue assignment, will recognize the pattern. This is the same shift one layer further along, and it rewards the teams that plan for it rather than the teams that discover the gaps live.

Routeget Technologies has helped clients stage this kind of rollout, pairing the operational speed of self-service configuration with a review process that catches translation drift before it reaches a live queue, and it is the kind of governance work that pays for itself the first time a playbook does not do quite what the sentence said it would.


#DynamicsContactCenter #UnifiedRouting #ConversationOrchestration #ContactCenterGovernance #CustomerServiceAI #ITGovernance

The Business Central Payables Agent Drafts Invoices. It Still Won’t Match a Purchase Order.

Finance professional reviewing an AP invoice matched against a purchase order and receipt on a computer dashboard

A controller at a mid-sized distributor recently described the moment her AP team realized what they’d actually bought. A vendor emailed a PDF invoice to the shared mailbox Business Central was watching, and within a few minutes the Business Central Payables Agent had pulled the vendor, mapped the line items to a G/L account, and dropped a fully drafted purchase invoice into the review queue. It looked like the AP clerk role had been automated away. Then someone asked whether the agent had checked the invoice against the purchase order or the goods receipt behind it, and the honest answer was no. It never does. Purchase order matching sits on Microsoft’s own published list of things the Payables Agent explicitly does not do, right alongside approval flows and anomaly detection.

That gap matters more than it sounds like it should, because Microsoft shipped a separate, unrelated feature in the same Business Central 2026 release wave that does handle order and receipt matching, and the two are easy to mistake for one connected capability. They are not. Understanding where the line actually falls is the difference between a rollout that genuinely reduces AP workload and one that quietly removes a control your finance team assumed was still there.

What the Business Central Payables Agent Actually Automates

The agent’s job starts and ends with turning an inbound PDF into a usable draft. It monitors a dedicated mailbox, pulls unread invoice emails, and runs each attached PDF through Azure Document Intelligence to extract the vendor name, amounts, and line detail. From there it tries to match the sender to an existing vendor record in Business Central; if it can’t do that confidently, it stops and asks a designated supervisor for instructions rather than guessing. When a new vendor genuinely needs to be created, the agent prefills the card from what it read off the invoice, but the record comes in blocked by default until a person reviews and releases it. Only after the vendor question is settled does the agent move to drafting the invoice itself, using historical purchasing patterns and item references to suggest which G/L accounts the line items belong to.

Finance professional reviewing an AP invoice matched against a purchase order and receipt on a computer dashboard

None of that becomes a posted transaction on its own. Every draft lands in a review queue where a human has to confirm, correct, or reject it before it becomes an actual purchase invoice, and Microsoft is direct about why: the agent’s account classifications and vendor matches “can be inaccurate,” and it has no way to evaluate business context the way a person reviewing the invoice would. That’s a reasonable design for what the agent is built to do, which is eliminate the manual keying and re-typing that eats the first half of most AP cycles. It is not built to answer the question of whether what you’re about to pay actually matches what was ordered and what showed up on the dock.

The Three-Way Match Gap Nobody’s Marketing Slide Mentions

Three-way matching, the practice of confirming an invoice against its purchase order and its receipt before payment, is the control most finance organizations rely on to catch overbilling, duplicate charges, and phantom deliveries. The Payables Agent doesn’t perform it. That’s not a bug or an oversight Microsoft is quietly working around; it’s a documented limitation, and as of this writing the agent itself is still labeled a public preview release rather than a finished, generally available feature.

What makes this genuinely confusing for a rollout is that the same 2026 wave 1 release also introduced “Match Purchase Invoices to Multiple Order and Receipt Lines,” a completely separate, non-AI capability built directly into standard purchase order processing. It adds a “Get Order Lines” action that surfaces received-but-uninvoiced or unreceived order lines, a “Matched Order Lines” page for reviewing and adjusting how invoice lines tie back to multiple purchase orders and partial receipts at once, and a “Receipt on Invoice” toggle that can auto-generate the receipt when a linked invoice posts. It reached general availability in April 2026, on its own timeline, with its own set of exclusions that keep it away from prepayment orders, item charges, projects, subcontracting, blanket orders, and intercompany transactions. Nothing in Microsoft’s documentation ties these two features together, and there’s no evidence the Payables Agent hands its drafts off into this matching workflow automatically. They simply shipped in the same release, aimed at the same purchase-to-pay process, and solve two different halves of the problem without talking to each other.

The practical result is that an AP team running the Payables Agent still needs to run invoices through order and receipt matching separately, whether that means the new native matching screens, an existing three-way-match process, or a third-party tool already in place. Treating the agent’s fast, clean drafts as evidence that matching already happened is exactly the kind of assumption that erodes a control environment quietly, one invoice at a time, until an audit or a duplicate payment surfaces the gap.

Consumption Billing Changes How You Budget for This

The licensing model adds a second layer finance leaders need to plan around before anyone flips this on for real volume. Copilot itself is bundled into Business Central’s Essentials and Premium subscription tiers, so the base chat and suggestion features a user sees day to day don’t carry a separate charge. Agents are different. The Payables Agent runs on Copilot Credits, a metered unit purchased through an Azure subscription, and consumption scales with how much work the agent actually does rather than with how many people are logged in. Microsoft’s own guidance is candid that it doesn’t publish a flat per-invoice rate; credit consumption depends on which features get used and what actions the agent performs on a given document, which means the honest answer to “what will this cost us” only comes from watching it run.

Hands comparing a printed purchase order against an invoice on a laptop screen during AP review

That variability lands at an awkward moment for most finance calendars. Invoice volume tends to spike at quarter-end and during seasonal peaks, which is precisely when a consumption-based bill is likely to jump, and precisely when a finance team has the least appetite for a surprise line item. Organizations used to a flat per-seat software cost don’t automatically have a forecasting habit built for variable, usage-driven spend, and marketing language that blurs “Copilot is included” with “the agent is included” doesn’t help anyone build one. There’s also a governance detail worth knowing before you assign ownership: viewing actual billing and consumption detail requires the SUPER or AGENT-DIAGNOSTICS permission set specifically. The narrower AGENT-ADMIN role that would typically administer the agent day to day does not, by itself, grant visibility into what it’s costing, so whoever ends up accountable for the Azure bill needs to be deliberately provisioned, not assumed.

What This Means for a Rollout Decision

None of this argues against adopting the Payables Agent. For an AP team drowning in PDF invoices that arrive by email in a single language, it removes a real chunk of manual entry, and the human-in-the-loop design means it isn’t going to post something wrong without a person signing off first. The documented ceilings are worth checking against your own volume before you commit to it as a strategy rather than a pilot: the agent tops out at 500 processed invoices and 100 monitored emails per day per environment, it’s validated for English only, it only reads PDF attachments up to a handful of pages and a few megabytes each, and it will not touch approval workflows or flag anomalies on its own. A high-volume, multi-language AP operation with heavy PO-based purchasing is going to run into those edges quickly.

The more useful framing for a CIO or CFO evaluating this isn’t “should we turn on AI for accounts payable.” It’s two separate questions that deserve two separate answers: does this reduce the manual work our AP team does today, and does it strengthen or weaken the matching controls we already rely on. The first answer, for the right invoice profile, is genuinely yes. The second, at least for now, is that the agent doesn’t touch that control at all, and the feature that does was built and shipped on its own, waiting to be adopted separately. Firms we’ve worked with on Business Central Copilot rollouts have had the smoothest results when they scoped the agent narrowly, ran it against real invoice volume for a full billing cycle before expanding it, and kept three-way matching exactly where it already lived rather than assuming the new AI layer had absorbed it.


#BusinessCentral #PayablesAgent #APAutomation #CopilotCredits #ThreeWayMatch #ERPGovernance

Financial Tags Finally Cover Purchase Order Invoicing in D365 Finance 10.0.49. Ledger Settlement Still Won’t Match Half of Them.

Finance professional reviewing a general ledger reconciliation dashboard with matched and unmatched transaction indicators

A controller running month-end reconciliation on a clearing account in Dynamics 365 Finance has a specific, recurring headache: the debit side of a transaction carries a purchase order number as a financial tag, the offsetting credit side does not, and the ledger settlement engine treats the two lines as unrelated even though anyone looking at the source documents can tell they belong together. Until version 10.0.49, this was a permanent structural gap rather than an occasional configuration mistake, because financial tags on purchase order invoicing simply did not exist as a supported scenario. Sales order invoicing got tag support years earlier. Purchase orders did not, which meant any finance team using tags to track PO references through the vendor side of the ledger was stuck writing the number into a description field or a financial dimension never designed to hold it. That gap closed with 10.0.49, and the fix is worth understanding in detail, because the parts of financial tags that already worked reasonably well are not the parts that are going to trip up the teams adopting this now.

What Financial Tags Actually Are, and Why the PO Gap Mattered

Financial tags are not a new concept in Dynamics 365 Finance. Introduced in version 10.0.16, they give a legal entity up to twenty user-defined fields that attach supplementary reference data directly to a general ledger voucher line, things like an external invoice number, a customer name, or a payment reference, without that data ever touching a subledger table or a financial dimension. That distinction matters more than it sounds. Financial dimensions were built for reusable, hierarchical, reportable categories: cost center, department, business unit. A purchase order number is none of those things. It is a single-use reference that exists to answer one question later: which document generated this line. Forcing that kind of data into a dimension structure bloats the dimension combination table and adds no analytical value, since nobody is running a financial report grouped by PO number. Tags were built specifically to hold this lower-reusability data cleanly, and by the time sales order invoicing gained tag support, most finance teams using the feature had already built tagging conventions around customer-side transactions. Vendor-side transactions were the obvious next step, and the 10.0.49 release finally delivers it, gated behind a feature called Enable financial tags for purchase order invoicing that sits alongside the equivalent, longer-standing sales order feature in Feature management.

Where the Real Work Starts: Ledger Settlement Matching

The reason this release deserves more than a changelog mention is that financial tags do something beyond passive record-keeping. They can serve as match criteria inside ledger settlement, the process finance teams use to pair debit and credit lines on clearing, prepaid, accrual, and other temporary accounts and mark them as settled. In principle, tagging both the AP-side and AR-side (or intercompany) legs of a transaction with the same PO reference should make settlement close to automatic: the engine finds the matching tag values and clears the pair. In practice, three specific failure patterns show up constantly, and none of them produce an error message that tells you what actually happened.

Close-up of hands reviewing a voucher transaction table with reference and status columns on a laptop

The first is the mismatched-side problem this article opened with. If the debit line carries a tag value and the credit line does not, or the two sides carry different values because they were entered by different people at different points in the process, settlement will not treat them as a match. There is no fuzzy matching here. The comparison is exact, and a trailing space or a different capitalization convention is enough to break it. The second is a timing problem specific to any organization adopting purchase order tagging now rather than at initial go-live: transactions posted before the feature was activated simply have no tag value on the line at all, which means every open item predating the 10.0.49 upgrade needs a separate remediation pass before it can participate in tag-based settlement. You cannot retroactively tag a posted voucher through the transaction UI; the supported path is the internal voucher data edit function, gated behind the Allow edits to internal data on general ledger vouchers feature, and it needs to run as a deliberate cleanup project, not something a settlement clerk discovers mid-close.

The third failure mode is the one that catches experienced admins off guard, because it involves a change that looks harmless. Tag labels can be renamed at any time without affecting already-posted data, which is a genuine convenience when a naming convention needs to evolve. But posted voucher lines retain whatever tag value was in effect at posting time, and if two lines that logically belong together were posted before and after a rename, or against two tags that were later consolidated under one label, the underlying stored values can diverge from what the current tag configuration implies, and settlement compares stored values, not current labels. A team that renamed a tag mid-quarter for good reasons can end up with a batch of open items that look identical in the UI but fail to match, and the only way to find out why is to pull voucher transactions against the general journal account entry table (not the financial tags table, which only exposes generic Tag01 through Tag20 labels and hides which business tag they actually correspond to) and compare raw values line by line.

Configuration Details Worth Getting Right Before You Enable the Feature

Beyond the settlement-matching behavior, a few configuration decisions are easy to get wrong on the first pass and expensive to unwind later. The delimiter used to separate tag values in General ledger parameters cannot be changed once set, so it is worth choosing a character your reference data will never plausibly contain, not just one that looks clean in a demo. Validation is optional by default even for list-type tags; as of 10.0.44, Fixed list and Fixed custom list value types exist specifically to prevent free-text drift, and for any tag that will be used as a settlement match key, that validation should be non-negotiable rather than left at the default. And because tag configuration changes are cached at the user session level, a tag that was just activated or edited will not reliably show up for a user until they sign out and back in and, in stubborn cases, clear the usage data cache under user options; teams that skip this step and conclude a newly enabled tag “isn’t working” are usually looking at a caching artifact, not a configuration bug.

For a finance function evaluating whether to turn purchase order tagging on now, the sequencing that avoids the most rework is to finalize the tag definitions and delimiter first, apply fixed-list validation to anything that will drive settlement matching, activate the feature and confirm both sides of a representative PO-to-payment cycle post with identical tag values, and only then decide how far back to remediate historical open items rather than assuming the feature will somehow reach backward on its own. None of this diminishes what 10.0.49 actually fixes: a real, years-old asymmetry between how sales and purchase transactions could be tagged is gone. What it does not fix, and was never going to, is the discipline required to keep tag values consistent across two sides of a transaction that are frequently entered by different people, in different modules, at different times. Routeget Technologies has helped finance teams build that discipline into their close process rather than discovering the gap during an audit, and the pattern is consistent enough across clients that it is worth planning for before enabling the feature rather than after the first failed settlement run.


#FinancialTags #DynamicsFinanceOps #LedgerSettlement #PurchaseOrderInvoicing #GeneralLedger #ERPReconciliation