
Preparing Datacloud
- 2k installs
- 763 repo stars
- Updated July 24, 2026
- forcedotcom/sf-skills
preparing-datacloud is an agent skill that Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, tran.
About
preparing datacloud Data Cloud Prepare Phase Use this skill when the user needs ingestion and lake preparation work data streams Data Lake Objects DLOs transforms Document AI unstructured ingestion or the handoff from connector setup into a live stream Use preparing datacloud when the work involves sf data360 data stream sf data360 dlo sf data360 transform sf data360 docai choosing how data should enter Data Cloud rerunning or rescanning ingestion after a source update preparing Ingestion API backed streams after connector setup is complete Delegate elsewhere when the user is still creating testing source connections connecting datacloud connecting datacloud SKILL md mapping to DMOs or designing IR data graphs harmonizing datacloud harmonizing datacloud SKILL md querying ingested data retrieving datacloud retrieving datacloud SKILL md Ask for or infer target org alias source connection name source object dataset document source desired stream type DLO naming expectations whether the user is creating updating running or deleting a stream whether the source is CRM a database connector an unstructured file source or an
- description: "Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data strea
- compatibility: "Requires an external community sf data360 CLI plugin and a Data Cloud-enabled org"
- Use this skill when the user needs **ingestion and lake preparation work**: data streams, Data Lake Objects (DLOs), tran
- Follow preparing-datacloud SKILL.md steps and documented constraints.
- Follow preparing-datacloud SKILL.md steps and documented constraints.
Preparing Datacloud by the numbers
- 2,001 all-time installs (skills.sh)
- +6 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #587 of 16,659 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
preparing-datacloud capabilities & compatibility
- Capabilities
- description: "salesforce data cloud prepare phas · compatibility: "requires an external community s · use this skill when the user needs **ingestion a · follow preparing datacloud skill.md steps and do
- Use cases
- orchestration
What preparing-datacloud says it does
description: "Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, transforms, or Document AI configurations. TRIGGER when: user creates
compatibility: "Requires an external community sf data360 CLI plugin and a Data Cloud-enabled org"
Use this skill when the user needs **ingestion and lake preparation work**: data streams, Data Lake Objects (DLOs), transforms, Document AI, unstructured ingestion, or the handoff from connector setup
npx skills add https://github.com/forcedotcom/sf-skills --skill preparing-datacloudAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2k |
|---|---|
| repo stars | ★ 763 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 24, 2026 |
| Repository | forcedotcom/sf-skills ↗ |
When should an agent use preparing-datacloud and what problem does it solve?
Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, transforms, or Document AI configurations. TRIGGER when: user creates or manages Dat
Who is it for?
Developers invoking preparing-datacloud as documented in the skill source.
Skip if: Skip when requirements fall outside preparing-datacloud documented scope.
When should I use this skill?
Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, transforms, or Document AI configurations. TRIGGER when: user creates or manages Dat
What you get
Outputs aligned with the preparing-datacloud SKILL.md workflow and stated deliverables.
- ingestion API payloads
- connector/object configuration
- authenticated Python ingest scripts
By the numbers
- Documents 8 required environment variables for ingestion auth and targeting
Files
preparing-datacloud: Data Cloud Prepare Phase
Use this skill when the user needs ingestion and lake preparation work: data streams, Data Lake Objects (DLOs), transforms, Document AI, unstructured ingestion, or the handoff from connector setup into a live stream.
When This Skill Owns the Task
Use preparing-datacloud when the work involves:
sf data360 data-stream *sf data360 dlo *sf data360 transform *sf data360 docai *- choosing how data should enter Data Cloud
- rerunning or rescanning ingestion after a source update
- preparing Ingestion API-backed streams after connector setup is complete
Delegate elsewhere when the user is:
- still creating/testing source connections → connecting-datacloud
- mapping to DMOs or designing IR/data graphs → harmonizing-datacloud
- querying ingested data → retrieving-datacloud
---
Required Context to Gather First
Ask for or infer:
- target org alias
- source connection name
- source object / dataset / document source
- desired stream type
- DLO naming expectations
- whether the user is creating, updating, running, or deleting a stream
- whether the source is CRM, a database connector, an unstructured file source, or an Ingestion API feed
---
Core Operating Rules
- Verify the external plugin runtime before running Data Cloud commands.
- Run the shared readiness classifier before mutating ingestion assets:
node ../orchestrating-datacloud/scripts/diagnose-org.mjs -o <org> --phase prepare --json. - Prefer inspecting existing streams and DLOs before creating new ingestion assets.
- Suppress linked-plugin warning noise with
2>/dev/nullfor normal usage. - Treat DLO naming and field naming as Data Cloud-specific, not CRM-native.
- Confirm whether each dataset should be treated as
Profile,Engagement, orOtherbefore creating the stream. - Distinguish stream-level refresh from connection-level reruns when working with unstructured sources.
- Use UI setup intentionally when initial stream or unstructured asset creation is platform-gated.
- Hand off to Harmonize only after ingestion assets are clearly healthy.
---
Recommended Workflow
1. Classify readiness for prepare work
node ../orchestrating-datacloud/scripts/diagnose-org.mjs -o <org> --phase prepare --json2. Inspect existing ingestion assets
sf data360 data-stream list -o <org> 2>/dev/null
sf data360 dlo list -o <org> 2>/dev/null3. Confirm the stream category before creation
Use these rules when suggesting categories:
| Category | Use for | Typical requirement |
|---|---|---|
Profile | person/entity records | primary key |
Engagement | time-based events or interactions | primary key + event time field |
Other | reference/configuration/supporting datasets | primary key |
When the source is ambiguous, ask the user explicitly whether the dataset should be treated as Profile, Engagement, or Other.
4. Create or inspect streams intentionally
sf data360 data-stream get -o <org> --name <stream> 2>/dev/null
sf data360 data-stream create-from-object -o <org> --object Contact --connection SalesforceDotCom_Home 2>/dev/null
sf data360 data-stream create -o <org> -f stream.json 2>/dev/null
sf data360 data-stream run -o <org> --name <stream> 2>/dev/null5. Check DLO shape
sf data360 dlo get -o <org> --name Contact_Home__dll 2>/dev/null6. Choose the right refresh mechanism
Use the smaller refresh scope that matches the user goal:
sf data360 data-stream run -o <org> --name <stream> 2>/dev/null
sf data360 connection run-existing -o <org> --name <connection-id> 2>/dev/nulldata-stream runis the closest match to a stream-level refresh or re-scan.connection run-existingruns at the connection level and can be useful for some connector workflows, but it is not a reliable replacement for stream refresh on unstructured sources.- For unstructured document connectors, prefer
data-stream runwhen the goal is to re-scan newly added or changed files.
7. Handle unstructured sources deliberately
For SharePoint-style document ingestion, a minimal unstructured DLO payload can look like:
{
"name": "my_udlo",
"label": "My UDLO",
"category": "Directory_Table",
"dataSource": {
"sourceType": "SF_DRIVE",
"directoryAndFilesDetails": [
{
"dirName": "SPUnstructuredDocument/<CONNECTION_ID>/<SITE_ID>",
"fileName": "*"
}
],
"sourceConfig": {
"reservedPrefix": "$dcf_content$"
}
}
}Use the UI for the first-time unstructured setup when the user needs the richer end-to-end pipeline. The UI path can seed additional document metadata fields and downstream assets that a bare CLI DLO create flow may not provision automatically.
8. Use the local Ingestion API example for send-data workflows
For external systems pushing records into Data Cloud:
1. create the connector in connecting-datacloud 2. upload the schema with sf data360 connection schema-upsert 3. create the stream in the UI when required 4. send records with the local example in examples/ingestion-api/
cd examples/ingestion-api
cp .env.example .env
python3 send-data.pyKey details:
- auth is a staged flow: JWT → Salesforce token → Data Cloud token
- the ingestion endpoint uses the tenant URL, not the Salesforce instance URL
202means the payload was accepted for processing, not that records are queryable immediately- validation failures often surface in the Problem Records DLO family
9. Only then move into harmonization
Once the stream and DLO are healthy, hand off to harmonizing-datacloud.
---
High-Signal Gotchas
- CRM-backed stream behavior is not the same as fully custom connector-framework ingestion.
sf data360 data-stream runandsf data360 connection run-existingare not interchangeable; prefer stream-level refresh for unstructured rescans.SFDCstreams sync on a platform-managed schedule;data-stream runis not the general control path for CRM connector refresh.- Some external database connectors can be created via API while stream creation still requires UI flow or org-specific browser automation. Do not promise a pure CLI stream-creation path for every connector type.
- Initial SharePoint-style unstructured setup can be richer in the UI than in a minimal CLI DLO create flow.
- Stream deletion can also delete the associated DLO unless the delete mode says otherwise.
- DLO field naming differs from CRM field naming, including
__c→_ctransformations. - Query DLO record counts with Data Cloud SQL instead of assuming list output is sufficient.
CdpDataStreamsmeans the stream module is gated for the current org/user; guide the user to provisioning/permissions review instead of retrying blindly.
---
Output Format
Prepare task: <stream / dlo / transform / docai>
Source: <connection + object>
Target org: <alias>
Artifacts: <stream names / dlo names / json definitions>
Verification: <passed / partial / blocked>
Next step: <harmonize or retrieve>---
References
- README.md
- examples/ingestion-api/README.md
- ../orchestrating-datacloud/assets/definitions/data-stream.template.json
- ../orchestrating-datacloud/references/plugin-setup.md
- ../orchestrating-datacloud/references/feature-readiness.md
Credits & Acknowledgments
Primary contributor: Gnanasekaran Thoppae
This skill is part of the *-datacloud family. Shared attribution, upstream source mapping, and maintenance notes live in:
- ../orchestrating-datacloud/CREDITS.md
- ../orchestrating-datacloud/UPSTREAM.md
CONSUMER_KEY=<your consumer key from External Client App>
CONSUMER_SECRET=<your consumer secret>
SF_USERNAME=<your salesforce username>
SF_LOGIN_URL=https://login.salesforce.com
TENANT_URL=https://<tenant-id>.c360a.salesforce.com
PRIVATE_KEY_FILE=/path/to/server.key
CONNECTOR_NAME=Badge_Scanner
OBJECT_NAME=Badge_Scan
Ingestion API example
This folder contains a minimal, public-safe example for sending records into Salesforce Data Cloud through the Ingestion API.
What this example assumes
Before running send-data.py, complete the connect/prepare setup steps:
1. create an Ingestion API connector 2. upload the schema with sf data360 connection schema-upsert 3. create the corresponding data stream in the UI if your org requires that step
Related connector definitions live in:
- ../../../connecting-datacloud/examples/connections/ingest-api-connection.json
- ../../../connecting-datacloud/examples/connections/ingest-api-schema.json
Prerequisites
pip install PyJWT cryptography requestsSetup
cd skills/preparing-datacloud/examples/ingestion-api
cp .env.example .env
# edit .env with your values
python3 send-data.pyEnvironment variables
CONSUMER_KEY— external client app consumer keyCONSUMER_SECRET— external client app consumer secret if your auth flow needs itSF_USERNAME— Salesforce username used for JWT authSF_LOGIN_URL— login host such ashttps://login.salesforce.comTENANT_URL— Data Cloud tenant URL such ashttps://<tenant>.c360a.salesforce.comPRIVATE_KEY_FILE— path to the JWT private keyCONNECTOR_NAME— Ingestion API connector nameOBJECT_NAME— uploaded schema object name
Notes
- auth is a staged flow: JWT → Salesforce token → Data Cloud token
- the ingestion endpoint uses the Data Cloud tenant URL, not the Salesforce instance URL
202means the payload was accepted for processing- validation failures often appear in the Problem Records DLO family
#!/usr/bin/env python3
"""
Send data to Data Cloud through the Ingestion API.
Prerequisites:
pip install PyJWT cryptography requests
Usage:
1. Copy .env.example to .env and fill in your values
2. python3 send-data.py
See README.md in this folder for setup notes.
"""
from __future__ import annotations
import os
import time
import uuid
from datetime import datetime, timezone
from pathlib import Path
import jwt
import requests
def load_env_file() -> None:
env_file = Path(__file__).parent / ".env"
if not env_file.exists():
return
for line in env_file.read_text().splitlines():
if "=" in line and not line.startswith("#"):
key, val = line.split("=", 1)
os.environ.setdefault(key.strip(), val.strip())
load_env_file()
CONSUMER_KEY = os.environ["CONSUMER_KEY"]
SF_USERNAME = os.environ["SF_USERNAME"]
SF_LOGIN_URL = os.environ.get("SF_LOGIN_URL", "https://login.salesforce.com")
TENANT_URL = os.environ["TENANT_URL"]
PRIVATE_KEY_FILE = os.environ["PRIVATE_KEY_FILE"]
CONNECTOR_NAME = os.environ["CONNECTOR_NAME"]
OBJECT_NAME = os.environ["OBJECT_NAME"]
def get_cdp_token() -> str:
"""Authenticate: JWT -> Salesforce access token -> Data Cloud token."""
private_key = Path(PRIVATE_KEY_FILE).read_text()
claim = {
"iss": CONSUMER_KEY,
"sub": SF_USERNAME,
"aud": SF_LOGIN_URL,
"exp": int(time.time()) + 300,
}
assertion = jwt.encode(claim, private_key, algorithm="RS256")
token_data = requests.post(
f"{SF_LOGIN_URL}/services/oauth2/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": assertion,
},
timeout=60,
).json()
if "access_token" not in token_data:
raise RuntimeError(f"Salesforce auth failed: {token_data}")
cdp_data = requests.post(
f"{token_data['instance_url']}/services/a360/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
data={
"grant_type": "urn:salesforce:grant-type:external:cdp",
"subject_token": token_data["access_token"],
"subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
},
timeout=60,
).json()
if "access_token" not in cdp_data:
raise RuntimeError(f"Data Cloud token exchange failed: {cdp_data}")
return cdp_data["access_token"]
def send_records(cdp_token: str, records: list[dict[str, str]]) -> tuple[int, str]:
"""Send records to the Ingestion API."""
url = f"{TENANT_URL}/api/v1/ingest/sources/{CONNECTOR_NAME}/{OBJECT_NAME}"
response = requests.post(
url,
headers={
"Authorization": f"Bearer {cdp_token}",
"Content-Type": "application/json",
},
json={"data": records},
timeout=60,
)
return response.status_code, response.text
if __name__ == "__main__":
print("Authenticating...")
token = get_cdp_token()
print("Data Cloud token acquired")
records = [
{
"ScanId": str(uuid.uuid4()),
"EventId": "EVT-001",
"AttendeeId": "ATT-001",
"Scantime": datetime.now(timezone.utc).isoformat(),
"Room": "Main Hall",
},
{
"ScanId": str(uuid.uuid4()),
"EventId": "EVT-001",
"AttendeeId": "ATT-002",
"Scantime": datetime.now(timezone.utc).isoformat(),
"Room": "Workshop A",
},
{
"ScanId": str(uuid.uuid4()),
"EventId": "EVT-001",
"AttendeeId": "ATT-003",
"Scantime": datetime.now(timezone.utc).isoformat(),
"Room": "Workshop B",
},
]
print(f"Sending {len(records)} records to {CONNECTOR_NAME}/{OBJECT_NAME}...")
status, body = send_records(token, records)
print(f"Response: {status} {body}")
if status == 202:
print("\nData accepted. Records typically appear in Data Cloud within a few minutes.")
print(
"Query with: sf data360 query sql -o <org> --sql 'SELECT * FROM \"<DLO_NAME>__dll\" LIMIT 10'"
)
else:
print("\nIngestion failed. Check the response above for details.")
preparing-datacloud
Ingestion and lake-preparation workflows for Salesforce Data Cloud.
Use this skill for
- data streams
- Data Lake Objects (DLOs)
- data transforms
- Document AI setup and extraction
- unstructured ingestion and re-scan workflows
- deciding how a source dataset should enter Data Cloud
- classifying a dataset as
Profile,Engagement, orOther - using the Ingestion API send-data example after connector setup
Example requests
"Create a Data Cloud stream from Contact"
"Inspect the DLO created by this stream"
"Help me create a transform for ingested data"
"Re-run this SharePoint document stream so it picks up new files"
"Show me how to send records to Data Cloud through the Ingestion API"Common commands
sf data360 data-stream list -o myorg 2>/dev/null
sf data360 data-stream create-from-object -o myorg --object Contact --connection SalesforceDotCom_Home 2>/dev/null
sf data360 data-stream run -o myorg --name Contact_Home 2>/dev/null
sf data360 dlo get -o myorg --name Contact_Home__dll 2>/dev/null
sf data360 transform list -o myorg 2>/dev/null
sf data360 connection run-existing -o myorg --name <connection-id> 2>/dev/nullKey reminders
- confirm whether a dataset should be treated as
Profile,Engagement, orOtherbefore creating the stream data-stream runis the preferred re-scan path for unstructured document ingestionconnection run-existingis a connection-level rerun and is not a full substitute for stream refresh- some external database and Ingestion API stream-creation flows still require UI setup
- initial unstructured DLO setup can be richer in the UI than in a minimal CLI payload
- use the local examples/ingestion-api/ folder for the send-data flow
References
- SKILL.md
- examples/ingestion-api/README.md
- ../orchestrating-datacloud/assets/definitions/data-stream.template.json
- CREDITS.md
Related skills
Forks & variants (1)
Preparing Datacloud has 1 known copy in the catalog totaling 519 installs. They canonicalize to this original listing.
- forcedotcom - 519 installs
How it compares
Use preparing-datacloud over generic Salesforce REST skills when loading batched structured records into Data Cloud connectors rather than standard sObject CRUD.
FAQ
What is preparing-datacloud?
Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, transforms, or Document AI configurations. TRIGGER when: user cr
When should I use preparing-datacloud?
Salesforce Data Cloud Prepare phase. Use this skill when the user creates or manages Data Cloud data streams, DLOs, transforms, or Document AI configurations. TRIGGER when: user cr
Is preparing-datacloud safe to install?
Review the Security Audits panel on this page before production use.