Data 360 object model and APIs — DLOs, DMOs, unified DMOs, calculated insight objects, naming suffixes, the revenue DMOs, the two API planes (Connect /ssot with a normal session, tenant APIs with a token exchange), scopes, and the Query Connect API
The layers and names in Data 360 (Data Cloud): DLOs (__dll), DMOs (__dlm, ssot__), unified DMOs, calculated insight objects (__cio), and the standard DMOs for accounts, people and orders. Then the two API planes, Connect REST under /services/data/vXX.X/ssot with a normal session and tenant APIs with a token exchange and cdp_* scopes, and the Query Connect API (query-sql) with paging and limits.
markdownreferencev17NWC-K0F1stage: designtrust: officialservice: data360interface: restinterface: sqlData 360Data Cloud renamed Data 360data lake object __dlldata model object __dlmssot__ prefixunified DMOcalculated insight object __ciossot__Individual__dlmssot__Account__dlmssot__ContactPointEmail__dlmssot__SalesOrder__dlmssot__SalesOrderProduct__dlmssot__GrandTotalAmount__cUnifiedIndividual__dlmIndividualIdentityLink__dlmConnect REST API /ssottenant API token exchange /services/a360/tokenurn:salesforce:grant-type:external:cdpcdp_query_api cdp_profile_api cdp_ingest_api cdp_apiPOST /ssot/query-sqlsqlParametersquery-sql rows offset rowLimitquery results 24 hoursGET /ssot/data-model-objectsdataModelObject listdata spaces
Data 360 object model and APIs
Data Cloud was renamed Data 360 on October 14, 2025. Metadata types, scratch-org features and many pages still say Data Cloud or CDP.
The layers
| Layer | Suffix | What it is |
|---|---|---|
| Data stream → data lake object (DLO) | __dll | Raw ingested rows, one DLO per stream |
| Data model object (DMO) | __dlm | Harmonised data: DLO fields mapped to the Customer 360 model. Standard DMOs carry ssot__ in object and field names |
| Unified DMO | __dlm | The golden record that identity resolution writes, plus a link DMO joining each source record to it |
| Calculated insight object (CIO) | __cio | A SQL-defined metric (lifetime value, last order) per profile or account |
| Search index chunk and index objects | __dlm | Created by a search index for retrieval (reference/data360/search-indexes-and-retrievers.md) |
The revenue DMOs
| DMO | API name | Key fields for revenue |
|---|---|---|
| Individual | ssot__Individual__dlm | ssot__Id__c, names, birth date |
| Contact Point Email / Phone / Address | ssot__ContactPointEmail__dlm and so on | Email, phone and address, each linked to the party |
| Account / Account Contact | ssot__Account__dlm, ssot__AccountContact__dlm | Account name, number, parent, type; contact-to-account link |
| Sales Order | ssot__SalesOrder__dlm | ssot__SoldToCustomerId__c, ssot__BillToAccountId__c, ssot__GrandTotalAmount__c, ssot__PurchaseOrderDate__c, ssot__OrderStartDate__c, ssot__SalesOrderStatusId__c, ssot__CurrencyCode__c |
| Sales Order Product | ssot__SalesOrderProduct__dlm | Line items; many to one with Sales Order |
| Opportunity, Case, Master Product | ssot__Opportunity__dlm and so on | Pipeline, service history, catalogue |
| Unified Individual and its link | UnifiedIndividual__dlm, IndividualIdentityLink__dlm (names in Salesforce's Trailhead SQL) | The golden record and its source links |
Don't hard-code unified names. When an org has more than one ruleset, the ruleset ID is appended to the unified and link object names; Salesforce's workshop shows "Unified Individual ccid". List the DMOs and pick them up by name pattern: GET /services/data/v66.0/ssot/data-model-objects returns dataModelObject[], and …/data-model-objects/{name} returns its fields[].
Two ways to call Data 360
| Connect REST API | Tenant APIs | |
|---|---|---|
| Base | https://<My Domain>/services/data/v66.0/ssot/... | The instance_url returned by the token exchange, for example /api/v1/metadata |
| Token | The normal Salesforce access token (the CLI's session works) | Exchange it at https://<My Domain>/services/a360/token with grant_type=urn:salesforce:grant-type:external:cdp, subject_token=<access token>, subject_token_type=urn:ietf:params:oauth:token-type:access_token and optionally dataspace=<name> |
| Scopes | api; Data 360 setup operations also need cdp_api (per the community plugin's guide) | cdp_query_api (SQL), cdp_profile_api (profiles), cdp_ingest_api (Ingestion API), plus refresh_token |
| Use for | Setup and lifecycle (streams, mappings, identity resolution, insights, search indexes, data kits) and SQL through query-sql | Ingestion API, Profile API, direct Query API v2 and v3 |
Salesforce calls the Connect REST API "the preferred platform for customers to construct solutions on top of Data 360". The user also needs Data 360 permission sets for the objects it touches.
Query Connect API
POST /services/data/v66.0/ssot/query-sql?dataspace=default
{ "sql": "SELECT COUNT(*) AS n FROM ssot__SalesOrder__dlm WHERE ssot__PurchaseOrderDate__c >= :since",
"sqlParameters": [ { "type": "date", "name": "since", "value": "2026-01-01" } ] }
- The response holds:
returnedRows;metadata[], with each column'sname,typeandnullable;data[][];status, withqueryId,completionStatus,rowCount,chunkCount,progressandexpirationTime.- Large results:
- Poll
GET …/query-sql/{queryId}?waitTimeMs=5000until finished, then page withGET …/query-sql/{queryId}/rows?rowLimit=2000&offset=2000&omitSchema=true. - Cancel with
DELETE …/query-sql/{queryId}. - Status values: Salesforce's post shows
completionStatusboth asFinishedand asFINISHED. Compare case-insensitively. - Retention and caching: results live for 24 hours, and identical queries may be served from cache for 24 hours.
- Queries read DMOs, DLOs and CIOs by API name. Quote mixed-case names, as in
"ssot__Individual__dlm", if your SQL client lower-cases them.
From TypeScript, conn.request({ method: "POST", url: "/services/data/v66.0/ssot/query-sql", body }) with an @salesforce/core connection is enough. The pipeline guide's code does this: guides/data360/automate-the-golden-record-pipeline.md.