Skip to content

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:

bash
export TDX_CAS_LEGACY_ENDPOINT=1

Note: 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

CommandDescription
listList composable audiences
descDescribe a composable audience

YAML Sync

CommandDescription
pullPull audience + segments to YAML files
validateValidate composable audience YAML files locally
pushPush YAML files to CAS API

Operations

CommandDescription
previewPreview composable segment query on CDW
sg listList composable segments for an audience
sg pushCreate, update, or delete a single child segment, standalone

Typical Usage

bash
# 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:

bash
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

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_amount

connection 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 by tdx connections, so there's no name to look up; run tdx cas pull on an existing Snowflake composable audience to see the exact ID your account uses.
  • Databricks/BigQuery: a connector name or ID from tdx connections (also requires catalog), or an authentication ID used to connect to the CDW.

Segment YAML

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: 1

Command Reference

list

List all composable audiences.

bash
tdx cas list [options]
OptionDescription
--jsonOutput as JSON
--jsonlOutput as JSON Lines

desc

Describe a composable audience showing master table, attributes, and behaviors.

bash
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.

bash
tdx cas pull [name] [options]
OptionDescription
--dir <dir>Target directory for YAML files (default: ./cas/<audience-name>/)
--dry-runShow 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.

bash
tdx cas validate [target] [options]
OptionDescription
--verboseAlso 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/behavior type)
  • Semantic rules: duplicate attribute/behavior names, catalog required for Databricks/BigQuery master connections, behaviors need all_columns: true or a non-empty columns list
  • Connection platform/catalog (only when the value resolves to a registered connector): whether its platform is supported, and — for Databricks/BigQuery master connections — that catalog is set. A connection: 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.

bash
tdx cas push [target] [options]
OptionDescription
--dry-runShow what would be done without making changes
-y, --yesSkip the confirmation prompt (for CI/CD and other non-interactive usage)
--deleteAllow 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.

bash
tdx cas preview <segment_name> [options]
OptionDescription
--audience <name>Composable audience name (or use session context)

sg list

List composable segments for an audience.

bash
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.

bash
tdx cas sg push <file> [options]
OptionDescription
--audience <name>Composable audience name (or use session context)
--dry-runShow what would be done without making changes
-y, --yesSkip the confirmation prompt (for CI/CD and other non-interactive usage)
--deleteDelete 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.

bash
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 -y

CAS vs Complete CDP

AspectComplete (tdx ps / tdx sg)Composable (tdx cas)
Data locationTD PlazmaDBCustomer's Snowflake/Databricks/BigQuery
Source referencedatabase + tableconnection + schema + table
Query enginePresto/Trino on TDDirect SQL on CDW
Activationssyndications with connectionIdcomposable_activations with CDW-specific export
API prefix/audiences/, /entities/segments//composable_audiences/, /entities/composable_segments/