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
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 withGET /ssot/data-model-objects/{name}. - Account revenue. Group
ssot__BillToAccountId__cthrough 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):
| Call | Endpoint |
|---|---|
| List or create | GET / POST /calculated-insights. The body takes apiName (must end __cio), displayName, definitionType, expression, and optionally dataSpaceName, description and draft |
| Run now | POST /calculated-insights/{apiName}/actions/run (path per the community plugin). A data kit sets a publishInterval |
| Read rows | Query the __cio with query-sql, like any object |
definitionTypeisCalculatedMetric(batch),StreamingMetricorExternalMetric. Revenue rollups areCalculatedMetric.- 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.
| Call | Endpoint (community plugin, reconciled to Salesforce's v67 spec) |
|---|---|
| Definitions | GET /data-graphs/metadata |
| Refresh | POST /data-graphs/{name}/actions/refresh |
| Read one record | GET /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
| Symptom | Cause → fix |
|---|---|
| CI create rejected | apiName lacks __cio, the SQL isn't an aggregate grouped by a key, or a column lacks __c |
| CI is empty | Identity resolution hasn't run, or the join misses the key qualifier and matches nothing. Count rows at each join with query-sql |
| Revenue double-counted | Joining order lines (Sales Order Product) and orders in the same aggregate. Aggregate lines in a sub-query first |
| Data graph returns stale orders | It hasn't refreshed since the last ingest. Refresh after the CI run |
| Data graph read 404 | The wrong root ID: use the unified ID, not the CRM Account or Contact ID |