Data 360 calculated insights and data graphs — revenue metrics on golden records (lifetime value, order count, last order, average order value), CI SQL and its API, running insights, and data graphs that serve a golden record with its orders as JSON for grounding

How to turn unified people and accounts plus their orders into revenue context. Calculated insights are SQL metrics stored as __cio objects. Covers their documented API fields (apiName ending __cio, displayName, definitionType, expression), the run endpoint, and SQL that joins Sales Order through the link DMO to the golden record. Data graphs precompute a golden record with related orders and insights as one JSON document for real-time grounding. Covers their endpoints and how they are packaged.

markdownreferencev12RC7-RKK0stage: enrichtrust: officialservice: data360interface: restinterface: sqlcalculated insights__cioPOST /ssot/calculated-insightsapiName __ciodefinitionType CalculatedMetric StreamingMetric ExternalMetricexpression ANSI SQLPOST /ssot/calculated-insights/{name}/actions/runlifetime value SQLorder countlast order dateaverage order valueRFMdimensions and measuresdata graphPOST /ssot/data-graphsdata graph refreshGET /ssot/data-graphs/data/{name}real-time grounding by IDPrompt Builder grounding with Data 360Data 360 query flow

Created 23 Oct 2026 · Modified 23 Oct 2026 · 1 version

Calculated insights and data graphs

Calculated insights: revenue metrics on golden records

A calculated insight (CI) is an ANSI SQL aggregate saved as a __cio object. Its dimensions are what you group by: always the golden record's ID, plus any slices. Its measures are the aggregates.

Lifetime revenue per golden individual, following the join Salesforce's Trailhead query uses (sales order → link DMO → unified individual):

SELECT
  u.ssot__Id__c                                     AS unified_individual_id__c,
  SUM(o.ssot__GrandTotalAmount__c)                  AS lifetime_revenue__c,
  COUNT(o.ssot__Id__c)                              AS order_count__c,
  MAX(o.ssot__PurchaseOrderDate__c)                 AS last_order_date__c,
  SUM(o.ssot__GrandTotalAmount__c) / COUNT(o.ssot__Id__c) AS average_order_value__c
FROM ssot__SalesOrder__dlm o
JOIN IndividualIdentityLink__dlm l
  ON o.ssot__SoldToCustomerId__c = l.SourceRecordId__c
 AND o.KQ_SoldToCustomerId__c = l.KQ_SourceRecordId__c
LEFT OUTER JOIN UnifiedIndividual__dlm u ON l.UnifiedRecordId__c = u.ssot__Id__c
GROUP BY u.ssot__Id__c
  • Key qualifiers. Salesforce's query also matches the KQ_ key-qualifier columns, which keep IDs from different sources apart. The exact link-DMO column names above are the hub's reading. Confirm them with GET /ssot/data-model-objects/{name}.
  • Account revenue. Group ssot__BillToAccountId__c through the account link DMO to the unified account instead.
  • Output columns end in __c. Name them as you want them to appear in prompts and in the search-index narrative.

API (under /services/data/v66.0/ssot):

CallEndpoint
List or createGET / POST /calculated-insights. The body takes apiName (must end __cio), displayName, definitionType, expression, and optionally dataSpaceName, description and draft
Run nowPOST /calculated-insights/{apiName}/actions/run (path per the community plugin). A data kit sets a publishInterval
Read rowsQuery the __cio with query-sql, like any object
  • definitionType is CalculatedMetric (batch), StreamingMetric or ExternalMetric. Revenue rollups are CalculatedMetric.
  • Create the insight before the search index and data graph that read it, and run it after each identity resolution run, so metrics follow the latest golden records.

Data graphs: a golden record with its orders, as one document

A data graph precomputes a root DMO (for example UnifiedIndividual__dlm) with related objects (link records, sales orders and products, insights) into a JSON record per root ID. That's the shape a prompt wants: this customer with their orders, in one lookup.

CallEndpoint (community plugin, reconciled to Salesforce's v67 spec)
DefinitionsGET /data-graphs/metadata
RefreshPOST /data-graphs/{name}/actions/refresh
Read one recordGET /data-graphs/data/{name}, scoped to one record ID. The community plugin builds the ID into the path; confirm the exact form in the spec
  • Use a data graph for "tell me about this account": grounding by a known ID, in real time.
  • Use a search index for "find accounts like this" or "who is ready to buy": semantic or hybrid search across many golden records (reference/data360/search-indexes-and-retrievers.md).
  • The revenue pipeline uses both (patterns/golden-record-rag-pipeline-for-revenue.md).
  • In an agent, a flow that queries Data 360 is the action Salesforce's workshop uses ("Get Merchant Order Insights"). Prompt Builder templates can ground on Data 360 too (family 6).

Failures

SymptomCause → fix
CI create rejectedapiName lacks __cio, the SQL isn't an aggregate grouped by a key, or a column lacks __c
CI is emptyIdentity resolution hasn't run, or the join misses the key qualifier and matches nothing. Count rows at each join with query-sql
Revenue double-countedJoining order lines (Sales Order Product) and orders in the same aggregate. Aggregate lines in a sub-query first
Data graph returns stale ordersIt hasn't refreshed since the last ingest. Refresh after the CI run
Data graph read 404The wrong root ID: use the unified ID, not the CRM Account or Contact ID

Read this document as markdown — the same bytes an agent receives.