mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 03:09:50 +08:00
Compare commits
3 Commits
103e0b95f2
...
8eeef27e59
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8eeef27e59 | ||
|
|
abe0d620a4 | ||
|
|
36f7a19206 |
@ -4,6 +4,8 @@ This repository provides a curated collection of Salesforce agent skills for bui
|
||||
|
||||
The skills are contributed by Salesforce and the broader community. It’s optimized for Agentforce Vibes and can be used with any AI tool that supports skills.
|
||||
|
||||
> ⚠️ **Expect frequent changes.** The Salesforce skills library is evolving rapidly as we refine patterns and incorporate feedback. Skills may be renamed, restructured, or removed between releases — they do not follow the same stability guarantees as GA platform APIs. If you’ve forked or synced the repository, be prepared for upstream changes that may conflict with local modifications. This repository is always the source of truth.
|
||||
|
||||
## 🗂️ Structure
|
||||
|
||||
```
|
||||
|
||||
5
skills/segmenting-datacloud-api/CREDITS.md
Normal file
5
skills/segmenting-datacloud-api/CREDITS.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Credits & Acknowledgments
|
||||
|
||||
Author: Matthew Lieber
|
||||
|
||||
This skill provides a REST API-first approach to Data Cloud segment management, complementing the `segmenting-datacloud` skill which uses the `sf data360` CLI plugin.
|
||||
35
skills/segmenting-datacloud-api/README.md
Normal file
35
skills/segmenting-datacloud-api/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# segmenting-datacloud-api
|
||||
|
||||
Manage Salesforce Data Cloud segments via the Connect REST API (`sf api request rest`), without requiring the `sf data360` community plugin.
|
||||
|
||||
## Use this skill for
|
||||
|
||||
- creating, updating, and deleting segments via REST API
|
||||
- publishing and deactivating segments
|
||||
- getting segment details and member lists
|
||||
- counting segment populations
|
||||
- full endpoint schema reference (request/response bodies, query params, error codes)
|
||||
|
||||
## Example requests
|
||||
|
||||
```text
|
||||
"Create a Dbt segment targeting individuals who purchased in the last 30 days"
|
||||
"List all active waterfall segments in my org"
|
||||
"Publish segment 1sgxx00000000PpAAI"
|
||||
"Get the members of my High_Value_Customers segment"
|
||||
"Delete the old test segment and recreate it on accounts"
|
||||
```
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -o myorg
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -X POST -H "Content-Type:application/json" -b @/tmp/segment.json -o myorg
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/My_Segment/actions/publish" -X POST -H "Content-Type:application/json" -b '{}' -o myorg
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/My_Segment/members?limit=100" -o myorg
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [SKILL.md](SKILL.md)
|
||||
- [CREDITS.md](CREDITS.md)
|
||||
341
skills/segmenting-datacloud-api/SKILL.md
Normal file
341
skills/segmenting-datacloud-api/SKILL.md
Normal file
@ -0,0 +1,341 @@
|
||||
---
|
||||
name: segmenting-datacloud-api
|
||||
description: "Manage Salesforce Data Cloud segments via the Connect REST API using `sf api request rest`. Use this skill when the user wants to create, list, get, update, delete, publish, deactivate, or count segments in Data Cloud — even if they say \"Data 360\", \"CDP segments\", or just \"segments\". Also use when the user asks about segment members or segment status. TRIGGER when: user manages segments via REST API, needs full endpoint schemas, or wants to bypass the sf data360 plugin. DO NOT TRIGGER when: user explicitly uses sf data360 CLI commands (use segmenting-datacloud), or the task is DMO/mapping/identity-resolution/activation work."
|
||||
compatibility: "Requires an org with Data Cloud enabled and the sf CLI installed"
|
||||
metadata:
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Data Cloud Segments — REST API via SF CLI
|
||||
|
||||
This skill manages Data Cloud segments through the Salesforce Connect API Segments endpoints, executed via `sf api request rest`.
|
||||
|
||||
## Authentication
|
||||
|
||||
All Segments endpoints require the **Core Salesforce token** (not the CDP token). The `sf api request rest` command handles authentication automatically using the target org.
|
||||
|
||||
Always include `-o <org-alias>` or rely on the default target org. The user's current default org is shown in the `sf api request rest --help` output.
|
||||
|
||||
## API Base Path
|
||||
|
||||
All endpoints live under `/services/data/v65.0/ssot/segments`. When calling `sf api request rest`, pass the full path starting with `/services/data/v65.0/`.
|
||||
|
||||
## Command Pattern
|
||||
|
||||
```bash
|
||||
# GET request (no body)
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -o <org>
|
||||
|
||||
# POST/PATCH with inline body
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -X POST \
|
||||
-H "Content-Type:application/json" \
|
||||
-b '{"field":"value"}' \
|
||||
-o <org>
|
||||
|
||||
# POST/PATCH with body from file
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -X POST \
|
||||
-H "Content-Type:application/json" \
|
||||
-b @/tmp/segment-body.json \
|
||||
-o <org>
|
||||
|
||||
# DELETE (requires empty JSON body due to sf CLI quirk)
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/MySegment" -X DELETE \
|
||||
-H "Content-Type:application/json" \
|
||||
-b '{}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
**Important sf CLI quirks:**
|
||||
- DELETE requests require `-H "Content-Type:application/json" -b '{}'` — the CLI errors without a body.
|
||||
- POST endpoints that accept no body (publish, deactivate) also need `-H "Content-Type:application/json" -b '{}'`.
|
||||
- For complex JSON bodies, prefer writing to a temp file first and using `-b @/tmp/file.json` to avoid shell quoting issues.
|
||||
|
||||
## Operations
|
||||
|
||||
### 1. List Segments
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments?batchSize=20&offset=0" -o <org>
|
||||
```
|
||||
|
||||
**Query parameters** (all optional):
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `batchSize` | integer | 1-200, default 20 |
|
||||
| `offset` | integer | Number of segments to skip |
|
||||
| `orderby` | string | Sort field + direction, e.g. `Name ASC`, `MarketSegmentType DESC` |
|
||||
| `dataspace` | string | Data space name (default data space if omitted) |
|
||||
| `filters` | string | Up to 10 filters joined by AND. See Filters section below |
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"batchSize": 20,
|
||||
"offset": 0,
|
||||
"orderByExpression": "[Name asc]",
|
||||
"segments": [ ... ],
|
||||
"totalSize": 42
|
||||
}
|
||||
```
|
||||
|
||||
Each segment object in the array contains: `apiName`, `dataSpace`, `description`, `displayName`, `lastModifiedDate`, `marketSegmentDefinitionId`, `marketSegmentId`, `publishInterval`, `segmentOnApiName`, `segmentOnId`, `segmentStatus`, `segmentType`.
|
||||
|
||||
#### List Filters
|
||||
|
||||
Filterable fields: `Name` (displayName), `SegmentStatus`, `MarketSegmentType` (segmentType), `SegmentOn` (segmentOnApiName), `LastPublishedEndDateTime`.
|
||||
|
||||
Operators: `eq`, `contains`, `in` (comma-separated values), `!=`.
|
||||
|
||||
```
|
||||
filters=Name contains MySegment AND SegmentStatus eq Active
|
||||
filters=MarketSegmentType in Dbt,Waterfall AND SegmentOn eq individual
|
||||
```
|
||||
|
||||
### 2. Create Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments" -X POST \
|
||||
-H "Content-Type:application/json" \
|
||||
-b @/tmp/create-segment.json \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
**Required fields:**
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `description` | string | Segment description |
|
||||
| `displayName` | string | Segment display name |
|
||||
| `segmentOnApiName` | string | API name of the entity to segment on (e.g. `ssot__Individual__dlm`, `ssot__Account__dlm`) |
|
||||
| `segmentType` | string | One of: `Dbt`, `Dynamic`, `Lookalike`, `Realtimez`, `Waterfall`. **Default to `Dbt` when the user does not specify a type.** |
|
||||
|
||||
**Optional fields:**
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `developerName` | string | API name for the segment (required for POST) |
|
||||
| `additionalMetadata` | object | Map of additional metadata |
|
||||
| `dataSpace` | string | Data space (use `dataspace` query param in v59+) |
|
||||
| `publishSchedule` | string | Enum: `NoRefresh`, `One`, `Two`, `Four`, `Six`, `Twelve`, `TwentyFour` (hours) |
|
||||
| `publishScheduleStartDateTime` | string | ISO datetime for schedule start — **must be in the future** |
|
||||
| `publishScheduleEndDate` | string | ISO datetime for schedule end — despite the name, use full `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` format |
|
||||
| `includeDbt` | object | SQL-based segment definition for Dbt segments. Structure: `{"models": {"models": [{"name": "m1", "sql": "..."}]}}`. Note the nested `models.models` — the outer `models` is an object, the inner `models` is an array of model objects each with `name` and `sql`. The SQL SELECT must include both the primary key (`ssot__Id__c`) and the key qualifier (`KQ_Id__c`) of the segmentOn entity. See [Data Cloud SQL Reference](https://developer.salesforce.com/docs/data/data-cloud-query-guide/guide/dc-query-section.html) for query syntax |
|
||||
| `lookalikeCriteria` | object | Lookalike criteria |
|
||||
| `lookbackPeriod` | string | Lookback period |
|
||||
|
||||
**Example — create a Dbt segment (default type):**
|
||||
```json
|
||||
{
|
||||
"description": "Customers with more than 5 purchases in the last 30 days",
|
||||
"displayName": "Frequent Recent Buyers",
|
||||
"developerName": "Frequent_Recent_Buyers",
|
||||
"segmentOnApiName": "ssot__Individual__dlm",
|
||||
"segmentType": "Dbt",
|
||||
"additionalMetadata": {},
|
||||
"includeDbt": {
|
||||
"models": {
|
||||
"models": [
|
||||
{
|
||||
"name": "m1",
|
||||
"sql": "SELECT ssot__Individual__dlm.ssot__Id__c, ssot__Individual__dlm.KQ_Id__c FROM ssot__Individual__dlm WHERE ssot__Individual__dlm.ssot__Id__c IN (SELECT IndividualId__c FROM ssot__SalesOrder__dlm WHERE CreatedDate__c >= DATEADD(day, -30, CURRENT_DATE) GROUP BY IndividualId__c HAVING COUNT(*) > 5)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"publishSchedule": "TwentyFour",
|
||||
"publishScheduleStartDateTime": "2026-04-17T00:00:00.000Z",
|
||||
"publishScheduleEndDate": "2026-05-17T23:59:59.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Important notes on Dbt SQL:**
|
||||
- The SQL SELECT must include both the primary key (`ssot__Id__c`) and the key qualifier (`KQ_Id__c`) of the segmentOn entity, or the API will return an `ENTITY_SAVE_ERROR`.
|
||||
- The `includeDbt` structure uses nested `models.models` — the outer `models` is an object, the inner `models` is an array of model objects each with `name` (e.g. `"m1"`) and `sql`.
|
||||
- The GET response flattens this to `includeDbt.models: [...]` (single-level array), but the POST body requires the nested `models.models` structure.
|
||||
- The SQL must follow Data Cloud SQL syntax. See the [Data Cloud SQL Reference](https://developer.salesforce.com/docs/data/data-cloud-query-guide/guide/dc-query-section.html) for supported functions, operators, and DMO querying patterns.
|
||||
|
||||
**Response (200):** Returns the full segment object with `apiName`, `marketSegmentId`, `marketSegmentDefinitionId`, `segmentStatus` (typically `PROCESSING`), and all provided fields.
|
||||
|
||||
**Error responses:**
|
||||
- 400: Invalid segment type, empty developerName/displayName, parse error
|
||||
- 409: Segment already exists
|
||||
|
||||
### 3. Get Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiNameOrId>" -o <org>
|
||||
```
|
||||
|
||||
Pass either the segment API name (developerName) or the segment ID.
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"segments": [ { ...segment object... } ]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Update Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiName>" -X PATCH \
|
||||
-H "Content-Type:application/json" \
|
||||
-b @/tmp/update-segment.json \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
Uses the same body schema as Create, with these differences:
|
||||
- `developerName` is **not supported** for PATCH (can't rename the API name)
|
||||
- `segmentType` is **not supported** for PATCH (can't change type after creation)
|
||||
- `additionalMetadata` is **not supported** for PATCH
|
||||
|
||||
Include only the fields you want to change. The required fields (`description`, `displayName`, `segmentOnApiName`) must still be present.
|
||||
|
||||
**Example — update description and publish schedule:**
|
||||
```json
|
||||
{
|
||||
"description": "Updated description",
|
||||
"displayName": "Recent High Value Customers",
|
||||
"segmentOnApiName": "ssot__Individual__dlm",
|
||||
"publishSchedule": "TwentyFour"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Delete Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiName>" -X DELETE \
|
||||
-H "Content-Type:application/json" \
|
||||
-b '{}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
Returns **204 No Content** on success (empty output).
|
||||
|
||||
### 6. Publish Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentId>/actions/publish" -X POST \
|
||||
-H "Content-Type:application/json" -b '{}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
Uses the segment **ID** (not API name). No request body.
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"errors": [],
|
||||
"jobId": "1f8f521f-0616-4bdf-a515-d95192475c95",
|
||||
"partitionId": "1sgxx00000000Pp_6157146b-...",
|
||||
"publishStatus": "PUBLISHING",
|
||||
"segmentId": "1sgxx00000000PpAAI",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Count Segment
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiName>/actions/count" -X POST \
|
||||
-H "Content-Type:application/json" \
|
||||
-b '{"preferApproxCount": true}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
**Request body:**
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `preferApproxCount` | boolean | yes | `true` for approximate count (faster), `false` for exact |
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"errors": [],
|
||||
"segmentId": "1sgxx00000000MbAAI",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Deactivate Segment
|
||||
|
||||
By API name:
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiName>/actions/deactivate" -X POST \
|
||||
-H "Content-Type:application/json" -b '{}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
By segment ID:
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentId>/actions/deactivate" -X POST \
|
||||
-H "Content-Type:application/json" -b '{}' \
|
||||
-o <org>
|
||||
```
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"errors": [],
|
||||
"segmentApiName": "TestFilter",
|
||||
"segmentId": "1sgxx00000000UfAAI",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 9. Get Segment Members
|
||||
|
||||
**The segment must be published before you can retrieve members.** If the segment has never been published, the API will return a 404 `ITEM_NOT_FOUND` error.
|
||||
|
||||
```bash
|
||||
sf api request rest "/services/data/v65.0/ssot/segments/<segmentApiName>/members?limit=100&offset=0" -o <org>
|
||||
```
|
||||
|
||||
**Query parameters** (all optional):
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `fields` | string | Comma-separated: `Id__c`, `KQ_Id__c`, `Delta_Type__c`, `Segment_Id__c`, `Parent_Segment_Id__c`, `Snapshot_Type__c`, `Timestamp__c`, `Version_Stamp__c` |
|
||||
| `filters` | string | e.g. `Delta_Type__c IN ('New','Existing') AND Timestamp__c IN 2026-04-09T14:12:41.111Z` |
|
||||
| `limit` | integer | 1-1000, default 100 |
|
||||
| `offset` | integer | Rows to skip |
|
||||
| `orderBy` | string | e.g. `Timestamp__c DESC` |
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"data": [ ... ],
|
||||
"endTime": "2025-04-11T15:16:10.000Z",
|
||||
"filter": "Delta_Type__c in ( new , existing )",
|
||||
"limit": 100,
|
||||
"offSet": 0,
|
||||
"orderBy": "Id__c asc",
|
||||
"rowCount": 5,
|
||||
"startTime": "2025-04-11T15:16:10.000Z",
|
||||
"totalCount": 5
|
||||
}
|
||||
```
|
||||
|
||||
## Common Segment Entity API Names
|
||||
|
||||
| Entity | API Name |
|
||||
|--------|----------|
|
||||
| Individual | `ssot__Individual__dlm` |
|
||||
| Account | `ssot__Account__dlm` |
|
||||
|
||||
When the user says "segment on individuals" or "segment on accounts", use these API names.
|
||||
|
||||
## Workflow: Create and Publish a Segment
|
||||
|
||||
A typical end-to-end flow:
|
||||
|
||||
1. **Create** the segment (POST) — returns `marketSegmentId`
|
||||
2. **Get** the segment to confirm it was created and check status
|
||||
3. **Publish** the segment using the `marketSegmentId` from step 1
|
||||
4. **Check status** by getting the segment again — look at `segmentStatus`
|
||||
5. **Count** the segment to trigger population count
|
||||
6. **Get members** to see who's in the segment
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **401 Unauthorized**: Run `sf org login web -a <alias>` to re-authenticate
|
||||
- **404 Not Found**: Check the segment API name is correct (case-sensitive)
|
||||
- **400 Bad Request**: Validate required fields are present; check `segmentType` enum values
|
||||
- **409 Conflict**: Segment with that `developerName` already exists
|
||||
Loading…
Reference in New Issue
Block a user