CAS Commands
Manage Composable Audience Studio (CAS) resources — zero-copy CDP audiences that run directly on customer Cloud Data Warehouses (Snowflake, Databricks, BigQuery) without moving data into Treasure AI.
Backend endpoint
tdx cas requests are served by cdp-api by default, following the CAS platform's cas-api → cdp-api mergeback. If you need to reach a composable audience that still only exists in the legacy standalone cas-api service, set:
export TDX_CAS_LEGACY_ENDPOINT=1Note: cas-api's data was never migrated to cdp-api, so composable audiences created against one host are invisible from the other — tdx cas list will show a different set of audiences depending on which endpoint is active.
Commands
Discovery
| Command | Description |
|---|---|
list | List composable audiences |
desc | Describe a composable audience |
YAML Sync
| Command | Description |
|---|---|
pull | Pull audience + segments to YAML files |
validate | Validate composable audience YAML files locally |
push | Push YAML files to CAS API |
Operations
| Command | Description |
|---|---|
preview | Preview composable segment query on CDW |
sg list | List composable segments for an audience |
sg push | Create, update, or delete a single child segment, standalone |
Typical Usage
# 1. List composable audiences
tdx cas list
# 2. Pull audience and all segments to YAML files
tdx cas pull "Customer360 Snowflake"
# Creates: cas/customer360-snowflake.yml (audience)
# cas/high-value-customers.yml (segment)
# cas/Marketing/newsletter-subs.yml (segment in folder)
# 3. Edit YAML files locally
# 4. Validate before pushing (optional — push validates too, but this is faster to iterate on)
tdx cas validate ./cas/
# 5. Push changes back to CAS API
tdx cas push ./cas/
# 6. Preview a segment query on the CDW
tdx cas preview "High-Value Customers" --audience "Customer360 Snowflake"Session Context
Set a default composable audience to avoid repeating the name:
tdx use cas "Customer360 Snowflake"
# Now these commands use the context:
tdx cas sg list # Lists segments for "Customer360 Snowflake"
tdx cas desc # Describes "Customer360 Snowflake"
tdx cas pull # Pulls "Customer360 Snowflake"How It Works
Composable Audiences define customer profiles from tables in your own data warehouse. Unlike Complete CDP audiences (which copy data into Treasure AI), composable audiences query your CDW directly — zero data movement.
Each composable audience has:
- A master table (the primary customer table in your CDW)
- Attributes (additional columns joined from other tables)
- Behaviors (time-series event tables for behavioral segmentation)
- Segments (filtered subsets using rules/conditions)
- Activations (exports from segments to external systems)
YAML Format
Audience YAML
name: Customer360 Snowflake
description: Customer data from Snowflake
timezone: America/New_York
master:
connection: '204' # Snowflake: a zero-copy config ID (see note below), not a connector name
schema: customer_data
table: customers
key_column: cdp_customer_id
# catalog: my-gcp-project # required for Databricks/BigQuery connections; unused for Snowflake
attributes:
- name: email_info
connection: '204' # Snowflake: a zero-copy config ID (see note below), not a connector name
schema: customer_data
table: customers
join:
table_key: cdp_customer_id
master_key: cdp_customer_id
columns:
- name: email
type: string
column: email_address
behaviors:
- name: purchase_events
connection: '204' # Snowflake: a zero-copy config ID (see note below), not a connector name
schema: events
table: purchase_history
join:
table_key: customer_id
master_key: cdp_customer_id
time_column: event_timestamp
columns:
- name: product_id
type: string
column: product_sku
- name: amount
type: number
column: purchase_amountconnection differs by platform:
- Snowflake: a federated query config (zero-copy config) ID — a raw ID like
"204", never a connector name. This resource is never listed bytdx connections, so there's no name to look up; runtdx cas pullon an existing Snowflake composable audience to see the exact ID your account uses. - Databricks/BigQuery: a connector name or ID from
tdx connections(also requirescatalog), or an authentication ID used to connect to the CDW.
Segment YAML
type: composable_segment
name: High-Value Customers
description: Customers with > $1000 in purchases
folder: Marketing/Campaigns
rule:
type: And
conditions:
- type: Behavior
behavior: purchase_events
aggregation: Sum
column: amount
operator: GreaterThanOrEqual
value: 1000
activations:
- name: Export to Marketing
connection: salesforce-connection
connector_config:
object: Contact
columns: # required: either `columns` (as here) or `all_columns: true`
- name: email
type: string
schedule:
type: daily # none | daily | weekly | monthly
timezone: UTC
repeat_unit: daily # optional finer-grained repeat control
repeat_frequency: 1Command Reference
list
List all composable audiences.
tdx cas list [options]| Option | Description |
|---|---|
--json | Output as JSON |
--jsonl | Output as JSON Lines |
desc
Describe a composable audience showing master table, attributes, and behaviors.
tdx cas desc [name]Uses session context if name is omitted (set via tdx use cas or tdx cas pull).
pull
Pull a composable audience and all its segments/activations to local YAML files.
tdx cas pull [name] [options]| Option | Description |
|---|---|
--dir <dir> | Target directory for YAML files (default: ./cas/<audience-name>/) |
--dry-run | Show what would be done without writing files |
Uses session context if name is omitted. Also sets composable_audience context for subsequent commands.
The pull command shows diffs for changed files and prompts for confirmation before writing.
validate
Validate composable audience YAML files locally, without contacting the CAS API.
tdx cas validate [target] [options]| Option | Description |
|---|---|
--verbose | Also print each valid file (by default only files with errors/warnings are shown) |
target can be a file or directory. If omitted, uses the session context set by tdx use cas.
Checks performed:
- YAML shape: required fields, types, and enum values (e.g.
master.schema,master.table, attribute/behaviortype) - Semantic rules: duplicate attribute/behavior names,
catalogrequired for Databricks/BigQuery master connections, behaviors needall_columns: trueor a non-emptycolumnslist - Connection platform/catalog (only when the value resolves to a registered connector): whether its platform is supported, and — for Databricks/BigQuery master connections — that
catalogis set. Aconnection:value is not required to appear in your account's connector list (tdx connections) — for Snowflake it's typically a federated query config (zero-copy config) ID, and for Databricks/BigQuery it's typically an authentication used to connect to the CDW; both are separate resources from connectors, with their own ID namespaces. An unresolved connection is expected and not flagged. - Snowflake connection misuse: a
connection:value that matches a registered connector name on a Snowflake master/attribute/behavior is always an error — Snowflake needs a raw zero-copy config ID instead (see YAML Format above), and resolving a connector name there would silently send the wrong ID and fail with a confusing error at push time.
This is the same validation tdx cas push runs as a pre-flight check before touching the API — cas validate exists as a faster local iteration loop, not a separate set of rules. It does not verify that TD can actually connect to your CDW or that the referenced schema/table/columns exist there — that only happens server-side during an actual tdx cas push (there is no standalone endpoint for a live connectivity check). Composable segment YAML (type: composable_segment) files are detected but not deeply validated by this command.
push
Push local YAML files to the CAS API.
tdx cas push [target] [options]| Option | Description |
|---|---|
--dry-run | Show what would be done without making changes |
-y, --yes | Skip the confirmation prompt (for CI/CD and other non-interactive usage) |
--delete | Allow removing audience attributes/behaviors not in local YAML (disabled by default — see below) |
target can be a file or directory. If omitted, pushes from the current directory. Audience files are pushed first, then segments and activations.
Push first validates all composable audience YAML files (same checks as tdx cas validate) and aborts before making any API calls if any file has errors. It then creates a new Composable Parent Segment when no audience with that name exists, or updates the existing one — showing a preview of what would be created/updated first, then prompting for confirmation before writing (pass --yes to skip the prompt). In a non-interactive session (e.g. CI/CD, no TTY), push refuses outright with an error unless --yes is passed — it never silently assumes confirmation.
A target can only contain one composable audience YAML file per push — every segment/activation file in the target attaches to that one audience. If more than one audience file is found, push aborts and lists the conflicting files rather than guessing which audience the segments belong to.
If a segment's folder: path doesn't exist yet (e.g. the first push of a brand-new audience), push creates the missing folder(s) automatically, parent folders first.
Updating an existing audience replaces its full attributes/behaviors set, not a merge. The backend does a destroy-and-rebuild of the whole collection whenever the request includes an attributes or behaviors key, so an attribute/behavior on the server but missing from the local YAML would otherwise be silently deleted. Push detects this ("drift") and refuses before writing anything, naming what would be removed — pass --delete to authorize the removal.
Renaming an attribute/behavior (same source schema/table/column, new name) is detected as a rename, not a removal — it doesn't need --delete. Because the backend always rebuilds the whole collection on update, a rename can't be applied truly in place: the attribute/behavior gets a new server-side id every time. Push output reports this explicitly, e.g. Renamed attribute: "email" → "email_updated" (server id changed 10095 → 10096) — if anything else (an activation, an external system) is keyed on the old id, update it there too.
preview
Preview a composable segment query by running it on the CDW.
tdx cas preview <segment_name> [options]| Option | Description |
|---|---|
--audience <name> | Composable audience name (or use session context) |
sg list
List composable segments for an audience.
tdx cas sg list [audience_name]If audience_name is omitted, uses the session context set by tdx use cas.
sg push
Create or update a single composable child segment, standalone — without needing a co-located audience YAML file in the same directory.
tdx cas sg push <file> [options]| Option | Description |
|---|---|
--audience <name> | Composable audience name (or use session context) |
--dry-run | Show what would be done without making changes |
-y, --yes | Skip the confirmation prompt (for CI/CD and other non-interactive usage) |
--delete | Delete the named segment instead of creating/updating it (single segment only — see below; disabled by default) |
Unlike push, which requires an audience YAML file in the same target to resolve the parent, sg push resolves the parent audience by name — via --audience <name> or the session context set by tdx use cas. It creates a new child segment when none exists under that audience (matched by name), or updates the existing one — same idempotent-by-name behavior as push. Repeat pushes of the same segment file update in place rather than creating a duplicate.
--delete deletes exactly the one segment named in the file's name: field — single-named-target only, not a directory/bulk prune. This is a different meaning from push's own --delete (which authorizes removing audience attributes/behaviors detected as drift) — each --delete is scoped to its own command's domain. Passing a directory instead of a file is rejected outright, not silently guessed at. The confirmation prompt names the segment and audience explicitly (not the generic "Push N change(s)?" prompt) since this is a destructive, irreversible action.
tdx cas sg push high-value-customers.yml --audience "Customer360 Snowflake" --delete
tdx cas sg push high-value-customers.yml --audience "Customer360 Snowflake" --delete --dry-run
tdx cas sg push high-value-customers.yml --audience "Customer360 Snowflake" --delete -yCAS vs Complete CDP
| Aspect | Complete (tdx ps / tdx sg) | Composable (tdx cas) |
|---|---|---|
| Data location | TD PlazmaDB | Customer's Snowflake/Databricks/BigQuery |
| Source reference | database + table | connection + schema + table |
| Query engine | Presto/Trino on TD | Direct SQL on CDW |
| Activations | syndications with connectionId | composable_activations with CDW-specific export |
| API prefix | /audiences/, /entities/segments/ | /composable_audiences/, /entities/composable_segments/ |