Almanac

Consultant-focused KB for Microsoft Dynamics 365 Customer Insights – Data: implementation notes, gotchas, and configuration decisions beyond the official docs — across data unification, customer profiles, segments, measures and insights, predictions and AI, Dataverse integration, Copilot, and administration.

feature-dataverse-output-tables.mdv1 · history
CurrentApplies to AllUpdated 6 days agoSource Microsoft Learn

What it does

Customer Insights - Data writes its output — unified profiles, segment membership, unified activities, measures, enrichments and prediction results — into the linked Dataverse environment as system-managed tables with an msdynci_ prefix. Once they're there, anything that can talk to Dataverse (Web API, model-driven apps, Power Automate, Power BI, Fabric) can read them without going near the Customer Insights APIs.

Key facts

  • Tables are exposed through the standard Dataverse Web API at {Organization URI}/api/data/v9.2/, so the same OData syntax, auth and service protection limits you already know apply.
  • The entity sets documented are msdynci_customerprofiles, msdynci_segmentmemberships, msdynci_unifiedactivities, msdynci_customermeasures, msdynci_enrichments and msdynci_predictions.
  • Real-time web personalisation adds msdynci_p13nprofile, msdynci_p13nviews and msdynci_p13nactions, and changes how unified activity data is surfaced — the docs qualify msdynci_unifiedactivities as the path when web personalisation isn't in use.
  • Read only. Microsoft is explicit that POST, PATCH and PUT against these tables can break Customer Insights processing. GET is the only supported verb.
  • Microsoft's stated direction is to move off the Customer Insights - Data APIs onto the Dataverse APIs for filtering, sorting, scale and consistency. Treat the old API surface as legacy on new builds.
  • Calling app needs the usual three things: an Entra app registration, Dataverse API permissions, and at least Viewer permission inside Customer Insights - Data. All three, not two.
  • Segment membership is not a relational join table. The documented filter pattern is a contains() on msdynci_segments, i.e. you're string-matching against a serialised list on the customer row.
  • Profile lookups by business key work through alternate keys — ?$filter={alternate_column} eq '{value}' — but only for columns you've actually set up as such.
  • Metadata is not queryable yet. Segment definitions and workflow/run management were still listed as coming, so orchestration and admin calls stay on the Customer Insights APIs for now.
  • The tables only exist in Dataverse if the environment is using Customer Insights managed storage, or a bring-your-own-lake environment with Dataverse data sharing switched on.

When to use / skip

This is the default integration surface now, and for most projects it's the only one worth building against. If a client wants unified profiles inside a model-driven app, a canvas app, a Power BI report over Dataverse, a plugin, or any bespoke service, point them here rather than at the Customer Insights REST API or a nightly export to blob storage. The exception is genuine bulk movement — pulling every profile for a downstream warehouse. Dataverse service protection limits will make that miserable, and you want an ADLS or Fabric export instead. Skip it entirely on bring-your-own-lake environments where nobody has enabled Dataverse data sharing, because the tables simply won't be there.

Configuration decisions

  • Whether output lands in Dataverse at all — that's decided by the storage choice made at environment creation, and it's not casually reversible.
  • Which columns get promoted into the unified profile, since the shape of msdynci_customerprofiles is whatever unification produced, not a fixed schema.
  • Which alternate keys you need on the profile table so downstream apps can look a customer up by email, CRM contact ID or loyalty number rather than the Customer Insights CustomerId.
  • Service principal versus user context for each consumer, and which Customer Insights permission level that principal gets.
  • Whether measures and predictions are consumed from these tables directly, or copied into your own Dataverse columns for a nicer form experience and audit history.
  • How segment membership gets consumed given the serialised column — filter in the query, or flatten it into your own table on a schedule.

Gotchas

  • Someone will eventually try to write to msdynci_ tables from a plugin, a flow or a data migration tool. It looks like an ordinary Dataverse table and it isn't. Lock this down in your solution review before it corrupts a refresh.
  • The profile table's column set moves when unification changes. Add a source field, rerun unification, and a canvas app or Power BI report bound to the old shape can quietly stop returning what it used to.
  • Rows are replaced by the refresh cycle, not updated transactionally. Anything that assumes stable record timestamps or Dataverse-style change tracking behaviour on these tables needs testing, not assumption.
  • Dataverse API limits are per user or per service principal, per server. A chatty integration on a single app registration will get throttled long before Customer Insights runs out of steam.
  • Viewer permission in Customer Insights is easy to forget because the Dataverse call fails in a way that looks like a Dataverse security problem rather than a Customer Insights one.
  • Segment membership filtering by name means renaming a segment breaks every consumer silently. Nothing errors, you just get zero rows.

Consultant notes

  • Demo this early. Showing a client that unified profiles are already sitting in their own Dataverse environment, queryable with tooling they own, kills a surprising amount of "so how do we get the data out" anxiety.
  • Push back hard on any design that treats these tables as writable. The correct pattern is: read msdynci_, write to your own table.
  • Agree a contract on the unified profile schema with whoever builds the downstream apps, and make changes to unification go through the same change control as a Dataverse schema change.
  • Before go-live, check the consuming app registrations have Customer Insights permissions assigned, not just Dataverse ones — this is the single most common day-one failure.
  • If the client is still on the older Customer Insights - Data REST APIs, flag the migration now while it's a small piece of work rather than after they've built ten flows on it.

Worth another look when the metadata APIs land, or if the profile schema changes shape again.

Was this accurate?