# Segment Commands

Manage CDP segments for audiences and activations.

Alias
`tdx sg` is an alias for `tdx segment`

## Commands

### Navigation & Discovery

| Command | Description |
|  --- | --- |
| [`use`](#use) | Set parent segment context |
| [`list`](#list) | List folders and segments |
| [`view`](#view) | Show segment details |
| [`desc`](#desc) | Show segment schema (column types) |
| [`show`](#show) | Execute segment SQL and show results |
| [`sql`](#sql) | Get SQL query for segment |
| [`fields`](#fields) | List available fields for segmentation |


### YAML Sync

| Command | Description |
|  --- | --- |
| [`pull`](#pull) | Pull child segments to YAML files |
| [`push`](#push) | Push YAML files to TD as child segments |
| [`validate`](#validate) | Validate segment and journey YAML files locally |


## Typical Usage

```bash
# 0. List available parent segments
tdx ps list

# 1. Pull all child segments from a parent to YAML files
#    (this also sets parent_segment context)
tdx sg pull "My Audience"
# Creates: segments/my-audience/

# 2. Edit YAML files locally (add/modify segments and activations)
# Edit segments/my-audience/high-value-customers.yml with your text editor

# 3. Push changes back to TD (syncs segments and activations)
tdx sg push

# 4. Review segments in TD (context already set by pull)
tdx sg list -r
```

The pull/push workflow enables version control and code review for segment definitions:

```bash
# Work from any subdirectory - push finds tdx.json automatically
cd segments/my-audience/marketing
# Edit newsletter-subs.yml
tdx sg push                # Push all changes from root
```

## How It Works

**Child segments** define filtered audiences within a parent segment. They use rules (conditions) to filter customers from the parent segment's enriched data. Each child segment can have one or more **activations** that export the filtered audience to external systems.

The `tdx sg` commands help you manage child segments as local YAML files. You can `pull` existing segments from Treasure AI, edit them locally, and `push` changes back. The YAML files include both segment rules and activation configurations.

```mermaid
flowchart TB
    subgraph LOCAL["Local"]
        YAML["segments/&lt;parent&gt;/*.yml"]
        CLI["tdx sg desc/show/sql"]
    end

    subgraph TD["Treasure AI"]
        API["CDP API"]
        subgraph PS["Parent Segment"]
            PARENT[("Enriched<br/>Customer Data")]
        end
        CHILD["Child Segments"]
        ACT["Activations"]
        EXT["External Systems<br/>(S3, Salesforce, etc.)"]
    end

    YAML <-->|"pull / push"| API
    CLI -.->|"query"| CHILD
    API --> CHILD
    PARENT -->|"filtered by rules"| CHILD
    CHILD -->|"activations"| ACT
    ACT -->|"export"| EXT
```

### Folder Structure

Pull creates individual YAML files for each segment, organized by folder:

```
segments/
└── my-audience/                    # Normalized from "My Audience"
    ├── tdx.json                    # { "parent_segment": "My Audience" }
    ├── active-users.yml            # Root-level segment
    ├── high-value-customers.yml    # Another root-level segment
    ├── marketing/
    │   ├── email-subscribers.yml   # Segment in Marketing folder
    │   └── newsletter-subs.yml     # Another segment in folder
    └── sales/
        ├── enterprise-leads.yml    # Segment in Sales folder
        └── q1/
            └── q1-targets.yml      # Segment in Sales/Q1 folder
```

Each segment file includes its activations (syndications), enabling file-based management of your CDP configuration.

## Context-Based Workflow

Child segment commands require a parent segment context. Set it using one of these methods:

```bash
# Option 1: Use the segment use command
tdx sg use "My Audience"

# Option 2: Pull sets context automatically
tdx sg pull "My Audience"

# Now run segment commands without specifying parent
tdx sg list                    # List folders and segments in "My Audience"
tdx sg view "Premium Users"    # View child segment details
tdx sg desc "Premium Users"    # Show segment schema
```

Names are case-sensitive. Pattern matching (`*`, `?`) is supported for filtering.

## Commands

### use

Set or show the parent segment context for subsequent commands.

```bash
tdx sg use [name]
```

```bash
# Set parent segment context
tdx sg use "My Audience"

# Show current context (no argument)
tdx sg use
```

### list

List folders and segments within the current parent segment context.

```bash
tdx sg list [pattern] [options]
```

| Option | Description |
|  --- | --- |
| `-r, --recursive` | Recurse. **Alone**: show the full tree. **With a `<pattern>`**: search the whole tree by name and print each match with its full folder path — ready to feed `sg move`. Matching is the tdx glob convention (case-insensitive; a plain string is a substring, `*`/`?` are wildcards; safe on names with `()`/`[]`). Returns every match (filter a large set with `--json` piped to `jq`, or narrow the pattern) |
| `--max-depth <n>` | Maximum recursion depth (default: 10) |
| `-w, --web` | Show web console URLs for segments |


```bash
# First, set parent segment context
tdx use parent_segment "My Audience"

# List folders and segments in context
tdx sg list

# List contents of a specific folder
tdx sg list "Marketing"

# Filter by pattern (glob) — immediate children only
tdx sg list "*Premium*"

# List recursively (full tree)
tdx sg list -r

# Search the WHOLE tree by name — prints full folder paths to feed `sg move`.
# A bare name only matches top-level segments; `<pattern> -r` finds nested ones anywhere.
# A plain string is a case-insensitive substring (safe on names with ()/[]); * and ? are wildcards:
tdx sg list "VIP (US)" -r
tdx sg list "VIP" -r --json             # contains "VIP", as JSON for jq
tdx sg list "Q1 *" -r                   # wildcard

# Show web console URLs for each segment
tdx sg list -w
```

JSON Output
When using `--json` or `--jsonl` output, URLs are always included in the response.

Listing Parent Segments
Use `tdx ps list` to list available parent segments.

### move

Safely move one or more child segments to a different folder. The move changes **only** the folder — each segment's filtering rule and activations are left untouched.

```bash
tdx sg move <segment...> --folder <folder> [options]
```

Segments and the target folder can be given by **numeric ID** or by **name/path**. Numeric IDs are used as-is; names are resolved within the current parent segment.

| Option | Description |
|  --- | --- |
| `--folder <folder>` | Target folder, by ID or name (required) |
| `--dry-run` | Show what would move without making any changes |


```bash
# Move one segment by ID
tdx sg move 1603887 --folder 8299501

# Move several segments at once
tdx sg move 1603887 1603888 1603889 --folder 8299501

# Move by name — needs a parent segment context
tdx sg use "Customer 360"
tdx sg move "VIP Customers" --folder "Archive"

# Names can be nested paths, relative to the parent
tdx sg move "Marketing/VIP Customers" --folder "Marketing/Archive"

# Preview without changing anything
tdx sg move 1603887 --folder 8299501 --dry-run
```

Names are resolved **relative to the parent segment context** (set via `tdx sg use` or `--parent-segment`); numeric IDs work without context. IDs come from `tdx sg list -r` (use `-r` to include nested segments) or the Console URL. Name matching is **case-insensitive**; an ambiguous name errors and lists the matches with their IDs so you can pass the ID instead. Batch segments only.

Use this instead of raw API calls
This is the safe, supported way to move segments between folders. Hand-rolled API calls can accidentally drop a segment's filtering rule (this caused a production incident); `tdx segment move` cannot.

### view

Show details of a folder or child segment within the current context.

```bash
tdx sg view [name] [options]
```

| Option | Description |
|  --- | --- |
| `-w, --web` | Open segment in web browser |


```bash
# Show folder details
tdx sg view "Marketing"

# Show child segment details (includes web console URL)
tdx sg view "Premium Users"

# Open segment in web browser
tdx sg view "Premium Users" -w

# JSON output
tdx sg view "Premium Users" --json
```

Web Console URL
The output always includes a `url` field with a link to the segment in the Treasure AI web console.

### desc

Show schema (column names and types) for a child segment.

```bash
tdx sg desc [name]
```

```bash
# Show schema for child segment
tdx sg desc "Premium Users"

# JSON output
tdx sg desc "Premium Users" --json
```

### show

Execute segment SQL query and show results.

```bash
tdx sg show [name]
```

```bash
# Execute segment SQL query and show results
tdx sg show "Premium Users"

# With output format
tdx sg show "Premium Users" --json
```

### sql

Get SQL query for a child segment.

```bash
tdx sg sql [name]
tdx sg sql --path <file-path>
```

| Option | Description |
|  --- | --- |
| `--path <file-path>` | YAML file path for unpushed segment |


```bash
# Get SQL query for server-side segment
tdx sg sql "Premium Users"

# For segments in folders, include folder path
tdx sg sql "Marketing/Newsletter Subscribers"

# Get SQL from local YAML file (before pushing)
tdx sg sql --path segments/my-audience/premium-users.yml

# JSON output
tdx sg sql "Premium Users" --json
```

### fields

List available fields for segmentation in the current parent segment context.

```bash
tdx sg fields
```

```bash
# List available fields (uses parent_segment context)
tdx sg fields

# JSON output
tdx sg fields --json
```

### pull

Pull all child segments from a parent segment to individual YAML files. This also sets the `parent_segment` context for subsequent commands.

```bash
tdx sg pull [parent_name]
```

The `parent_name` argument is optional if you have set a parent segment context with `tdx sg use`.

| Option | Description |
|  --- | --- |
| `-y, --yes` | Skip confirmation prompt |
| `--dry-run` | Preview changes without writing files |


```bash
# Pull all segments from parent (sets context)
tdx sg pull "My Audience"

# Preview changes without writing files
tdx sg pull "My Audience" --dry-run

# Skip confirmation prompt
tdx sg pull "My Audience" -y

# With context set (tdx sg use "My Audience")
tdx sg pull
```

**Output includes:**

- Number of segments and activations found
- New, changed, and unchanged files
- Diff preview for changed files


### push

Push individual segment YAML files to Treasure AI. Uses `parent_segment` context or detects parent from `tdx.json` in the segments directory.

```bash
tdx sg push [directory]
```

| Option | Description |
|  --- | --- |
| `-y, --yes` | Skip confirmation prompt |
| `--dry-run` | Preview changes without applying |
| `--delete` | Delete segments not in local YAML files |


```bash
# Push all segments (uses context or tdx.json)
tdx sg push

# Push from specific directory
tdx sg push segments/my-audience

# Preview changes without applying
tdx sg push --dry-run

# Skip confirmation prompt
tdx sg push -y
```

**Features:**

- Automatically creates missing TD folders
- Shows diff before applying changes (segments and activations)
- Shows segments/activations that will be deleted (exist on server but not in YAML)
- Syncs activations by name (create/update/delete)
- Creates new segments or updates existing ones based on segment name
- Asks for confirmation before applying changes


### validate

Validate segment and journey YAML files locally without pushing to Treasure AI. This is useful to catch syntax errors, missing references, and invalid configurations before pushing.

```bash
tdx sg validate [target]
```

| Argument | Description |
|  --- | --- |
| `target` | File or directory to validate (optional, defaults to context directory) |


```bash
# Validate all segments and journeys in context directory
tdx sg validate

# Validate a specific file
tdx sg validate high-value-customers.yml

# Validate a specific directory
tdx sg validate segments/my-audience
```

**Validations performed:**

For segments:

- Missing or empty `name` field
- Empty attribute values in conditions
- Invalid operator types
- Missing required operator fields (e.g., `value` for Equal, `min`/`max` for Between)
- Invalid `arrayMatching` configuration


For journeys:

- Missing `name` or empty `stages`
- Duplicate step names
- Invalid `next` step references
- Wait step condition references to undefined embedded segments
- Decision branch references to undefined segments
- A/B test variant percentages not summing to 100%
- Invalid jump step targets


**Example output:**

```
✔ high-value-customers.yml (segment)

✖ bad-journey.journey.yml (journey): 2 error(s)

bad-journey.journey.yml:15:7: error [MISSING_SEGMENT_REFERENCE]
Wait condition references undefined segment 'missing_segment'
    14 |     condition:
    15 |       segment: missing_segment
       |       ^
    16 |       next: to_end

bad-journey.journey.yml:22:5: error [INVALID_NEXT_REFERENCE]
Step references non-existent step 'nonexistent'
    21 |   name: activation_step
    22 |     next: nonexistent
       |     ^
    23 |     with:

Validation failed: 1 file(s) with errors, 1 valid
```

Validation also runs automatically before `tdx sg push`, so you can catch errors early in your workflow.

## Segment YAML Schema

Each segment has its own YAML file with optional activations:

```yaml
# segments/my-audience/us-customers.yml
name: US Customers
description: All customers in the United States

rule:
  type: Value
  attribute: country
  operator:
    type: Equal
    value: US
```

```yaml
# segments/my-audience/marketing/high-value-customers.yml
name: High Value Customers
description: Customers with LTV > $1000
kind: batch        # batch, realtime, or funnel_stage
visible: true      # Show in UI (default: true)

rule:
  type: And
  conditions:
    - type: Value
      attribute: ltv
      operator:
        type: Greater
        value: 1000

activations:
  - name: Daily Salesforce Sync
    description: Sync high-value customers to SFDC daily
    connection: my-salesforce-connection
    all_columns: false
    columns:
      - email
      - first_name
      - last_name
      - ltv
    schedule:
      type: daily
      timezone: America/Los_Angeles
    connector_config:
      object: Contact
      mode: upsert

  - name: Weekly Marketing Cloud Export
    connection: marketing-cloud-export
    all_columns: true
    schedule:
      type: weekly
      repeat_sub_frequency: [1]  # Monday
      timezone: UTC
    notification:
      notify_on:
        - onSuccess
        - onFailure
      email_recipients:
        - user@example.com  # Must be TD account email
```

### Activation Schema

Activations (syndications) define how segment data is exported to external systems:

| Field | Description | Required |
|  --- | --- | --- |
| `name` | Activation name (used for matching) | Yes |
| `description` | Description | No |
| `connection` | TD Connection name (use `tdx connections` to list) | Yes |
| `all_columns` | Export all columns | No (default: false) |
| `columns` | Columns to export (if not all_columns) | No |
| `schedule` | Schedule configuration | No |
| `connector_config` | Connector-specific settings (see below) | No |
| `notification` | Notification settings (see below) | No |


Finding Connection Names
Use `tdx connections` to list available connections and their names:

```bash
tdx connections
```

**Schedule Types:**

| Type | Description | Additional Fields |
|  --- | --- | --- |
| `none` | Manual trigger only | - |
| `minutes_interval` | Run every N minutes | `repeat_frequency` (interval in minutes) |
| `hourly` | Run every hour | - |
| `daily` | Run daily | `timezone` |
| `weekly` | Run weekly | `repeat_sub_frequency` (day numbers 0-6), `timezone` |
| `monthly` | Run monthly | `repeat_sub_frequency` (day numbers 1-31), `timezone` |
| `cron` | Cron expression | `cron`, `timezone` |


**Column Format:**

Columns can be simple strings or objects with additional properties:

```yaml
columns:
  # Simple column name
  - email
  - first_name

  # Column with visibility setting
  - name: ssn
    visibility: masked  # clear or masked
```

**Notification Settings:**

Configure email notifications for activation runs:

```yaml
notification:
  notify_on:
    - onSuccess    # Notify on successful completion
    - onFailure    # Notify on failure
  email_recipients:
    - user@example.com  # Must be TD account email addresses
```

| Field | Description |
|  --- | --- |
| `notify_on` | Events to notify on: `onSuccess`, `onFailure` |
| `email_recipients` | List of email addresses (must be registered TD account emails) |


**Connector Config Settings:**

The `connector_config` field contains connector-specific settings that vary by connection type. Use `tdx connection schema <connection>` to see available fields for a specific connection.

```yaml
# Example: Treasure AI connector
connector_config:
  database_name: my_database
  table_name: my_table
  mode: append  # append or replace

# Example: Salesforce Marketing Cloud connector
connector_config:
  de_name: CustomerSegment
  shared_data_extension: false
```

Schema Validation
When pushing segments, tdx automatically validates `connector_config` against the connector's schema. Invalid values or unknown fields will show helpful error messages:

```
Error: Invalid connector_config for activation "My Activation":
  × mode: Invalid value for "Mode"
    Expected: one of: append, replace
    Received: invalid_mode
```

Use `tdx connection schema <connection>` to see valid field names and values.

### Important Behaviors

**Filename Collisions:**

When pulling segments, filenames are sanitized (lowercase, spaces to hyphens). If two segments would result in the same filename (e.g., "My Segment" and "my-segment"), numeric suffixes are added:

- `my-segment.yml` (first segment)
- `my-segment-1.yml` (second segment)


**Activation Matching:**

Activations are matched by `name` only. This has important implications:

- **Renaming an activation** in YAML will delete the old activation and create a new one (losing execution history and statistics)
- To preserve an activation's history, update its properties without changing the name


**Segment Matching:**

Segments are matched by `folder + name`. This means:

- You can have segments with the same name in different folders
- Moving a segment YAML file to a different folder creates a new segment (does not move the existing one)


### Supported Operators

All operators use the unified `value` field. When multiple values are needed (e.g., `In`, `Contain`), provide an array.

#### Comparison Operators

| Operator Type | Required Fields | Value Type | Description |
|  --- | --- | --- | --- |
| `Equal` | `value` | string, number, boolean | Exact match |
| `NotEqual` | `value` | string, number, boolean | Not equal (use `not: true` with `Equal`) |
| `Greater` | `value` | number | Greater than |
| `GreaterEqual` | `value` | number | Greater than or equal |
| `Less` | `value` | number | Less than |
| `LessEqual` | `value` | number | Less than or equal |
| `Between` | `minValue`, `maxValue` | number | Value in range (exclusive) |


#### List Operators

| Operator Type | Required Fields | Value Type | Description |
|  --- | --- | --- | --- |
| `In` | `value` | array of strings/numbers | Value in set |
| `NotIn` | `value` | array of strings/numbers | Value not in set (use `not: true` with `In`) |


#### String Operators

| Operator Type | Required Fields | Value Type | Description |
|  --- | --- | --- | --- |
| `Contain` | `value` | array of strings | Contains any substring |
| `StartWith` | `value` | array of strings | Starts with any prefix |
| `EndWith` | `value` | array of strings | Ends with any suffix |
| `Regexp` | `value` | regex pattern string | Matches regular expression |


#### Null Operators

| Operator Type | Required Fields | Description |
|  --- | --- | --- |
| `IsNull` | (none) | Checks if value is null |


#### Time Operators

| Operator Type | Required Fields | Description |
|  --- | --- | --- |
| `TimeWithinPast` | `value`, `unit` | Within past N time units |
| `TimeWithinNext` | `value`, `unit` | Within next N time units |
| `TimeToday` | (none) | Matches today |
| `TimeThis` | `from.unit` | Current period (this week, this month, etc.) |
| `TimeNext` | `from.unit` | Next period (next week, next month, etc.) |
| `TimeRange` | `from`, `to` or `from`, `duration` | Complex time range |
| `TimeInBetweenNext` | `from`, `to` | Between two future dates |


### Time Units

For time-based operators (`TimeWithinPast`, `TimeWithinNext`, etc.), the `unit` field must be one of:

| Unit | Description |
|  --- | --- |
| `year` | Years |
| `quarter` | Quarters |
| `month` | Months |
| `week` | Weeks |
| `day` | Days |
| `hour` | Hours |
| `minute` | Minutes |
| `second` | Seconds |


Both singular (`day`, `week`) and plural (`days`, `weeks`) forms are accepted. Plural forms are automatically normalized.

### Negation with `not`

Most operators support a `not` field to invert the condition:

```yaml
# Emails NOT containing "@test.com"
operator:
  type: Contain
  value: ["@test.com"]
  not: true

# Value NOT equal to "inactive"
operator:
  type: Equal
  value: inactive
  not: true
```

### Operator Examples

**In (multiple values):**

```yaml
# Match customers in US, Canada, or Mexico
operator:
  type: In
  value: ["US", "CA", "MX"]
```

**NotIn (exclude multiple values):**

```yaml
# Exclude test and spam accounts
operator:
  type: In
  value: ["test", "spam", "internal"]
  not: true
```

**Contain (multiple substrings):**

```yaml
# Match emails from specific domains
operator:
  type: Contain
  value: ["@gmail.com", "@yahoo.com", "@outlook.com"]
```

**StartWith (multiple prefixes):**

```yaml
# Match product SKUs starting with specific prefixes
operator:
  type: StartWith
  value: ["PRO-", "ENT-", "PREM-"]
```

**EndWith (multiple suffixes):**

```yaml
# Match files with specific extensions
operator:
  type: EndWith
  value: [".pdf", ".doc", ".xlsx"]
```

**Between (numeric range):**

```yaml
# Age between 18 and 65
operator:
  type: Between
  minValue: 18
  maxValue: 65
```

**TimeWithinPast:**

```yaml
operator:
  type: TimeWithinPast
  value: 30
  unit: day  # Must be singular
```

**TimeWithinNext:**

```yaml
operator:
  type: TimeWithinNext
  value: 7
  unit: day
```

**TimeThis (current period):**

```yaml
operator:
  type: TimeThis
  from:
    unit: month  # This month
```

**TimeNext (next period):**

```yaml
operator:
  type: TimeNext
  from:
    unit: week  # Next week
```

**TimeRange (complex range):**

```yaml
# Last 3 months
operator:
  type: TimeRange
  from:
    last: 3
    unit: month
  duration:
    month: 3
```

### Segment Reference Conditions

You can include or exclude members of other segments using `type: include` or `type: exclude`:

```yaml
rule:
  type: And
  conditions:
    # Include members of another segment
    - type: include
      segment: california_customers

    # Exclude members of another segment
    - type: exclude
      segment: churned_users

    # Combined with value conditions
    - type: Value
      attribute: tier
      operator:
        type: Equal
        value: premium
```

| Type | Description |
|  --- | --- |
| `type: include` | Include profiles that are members of the referenced segment |
| `type: exclude` | Exclude profiles that are members of the referenced segment |


The `segment` field references another child segment by name within the same parent segment.

### Complex Rule Example

```yaml
rule:
  type: And
  conditions:
    # High value OR premium member
    - type: Or
      conditions:
        - type: Value
          attribute: ltv
          operator:
            type: Greater
            value: 1000
        - type: Value
          attribute: membership
          operator:
            type: Equal
            value: premium

    # Active within last 30 days
    - type: Value
      attribute: last_activity
      operator:
        type: TimeWithinPast
        unit: day
        value: 30

    # Not from test accounts
    - type: Value
      attribute: email
      operator:
        type: Contain
        value:
          - "@test.com"
        not: true

    # Exclude users already in another segment
    - type: exclude
      segment: already_contacted
```

## Related Commands

For managing **parent segments** (audiences), use the dedicated `tdx parent-segment` command (alias: `tdx ps`).

See [Parent Segment Commands](/treasure-code/commands/parent-segment) for full documentation including:

- `list` - List parent segments
- `pull` - Pull configuration to YAML
- `push` - Push YAML configuration
- `validate` - Validate configuration
- `preview` - Preview sample data
- `run` - Run the workflow