| name | segment |
| description | Manages CDP child segments using `tdx sg` commands with YAML rule configs. Covers Value/Behavior condition types, all operators (Equal, In, Between, TimeWithinPast, etc.), behavior aggregations with filters, and nested condition group restrictions. Use when creating audience segments with filtering rules, configuring behavior-based conditions, managing segment hierarchies, or exploring available fields with `tdx sg fields`. |
| owner | william.gonzalez@treasure.ai |
| tier | 1 |
| classification | product |
| phase | 1 |
| last-validated | "2026-07-07T00:00:00.000Z" |
| validation-model | claude-opus-4-8 |
| known-limitations | `tdx sg move` by bare name only resolves segments at the parent's top level; nested
segments require the full folder path. The same name can exist in multiple folders — if a
bare name matches more than one, `sg move` refuses and lists the matches (pass the full
path or id). Find a segment's path with `tdx sg list '<pattern>' -r`.
|
tdx Segment - CDP Child Segment Management
Segment Creation Workflow
Process one segment at a time. For each segment:
- Create the YAML file
- Validate with
tdx sg validate <file>
- Count check — run
tdx sg sql --path <file> | tdx query - and verify count > 0
- If count is 0, the rule is too restrictive — revise before proceeding
- Preview with
preview_segment tool — get user approval before proceeding
- Push with
tdx sg push -y "<file>" — always specify the file path explicitly
Never batch multiple segments in validate or push operations.
After push succeeds, display the Console link:
https://console.treasuredata.com/app/audiences/<parent_id>/segments/<segment_id>
Editing segments safely — read this first
All segment edits go through the typed tdx sg commands. Never edit a segment with raw tdx api HTTP calls.
- Never
tdx api PUT/PATCH a segment. Raw writes skip validation and can erase a segment's rule. Use the typed command for the change you want: tdx sg move to change folder, tdx sg push to change rules/activations.
- Never read-modify-write a segment. Do not GET a segment and write the object back — rule fields can come back empty from list/
entities reads, so writing it back erases the rule. Always use the dedicated command for the specific change.
- To change only the folder, use
tdx sg move (below). It changes the folder and nothing else.
If a typed command seems not to exist for what you need, ask the user — do not fall back to raw tdx api.
Core Commands
tdx sg use "Customer 360"
tdx sg pull "Customer 360"
tdx sg validate <file>
tdx sg push --dry-run "<file>"
tdx sg push -y "<file>"
tdx sg list
tdx sg list -r
tdx sg fields
tdx sg show "Segment Name"
tdx sg sql "Segment Name" | tdx query -
tdx sg sql --path <file>
tdx sg move <segment...> --folder <folder>
Note: --path requires a project directory created by tdx sg pull. The file must be inside a folder with tdx.json.
Moving segments between folders
To move one or more segments to a different folder, use tdx sg move. It changes only the folder — the segment's rule and activations are left untouched (it re-reads and verifies the rule survived).
tdx sg move 12345 --folder 67890
tdx sg move 12345 12346 --folder 67890
tdx sg move 12345 --folder 67890 --dry-run
tdx sg use "Customer 360"
tdx sg move "VIP Customers" --folder "Archive"
tdx sg move "Marketing/VIP Customers" --folder "Marketing/Archive"
- Segments and the target folder can be given by numeric ID or by name/path (names resolve within the current parent segment context).
- Find a segment or folder by name with
tdx sg list '<pattern>' -r — it searches the whole tree for names matching <pattern> (case-insensitive; a plain string matches as a substring, so 'VIP (US)' matches that name as-is; * and ? are wildcards) and prints each match with its full folder path + id, ready to pass to tdx sg move. On several matches it lists them all — pass the intended path/id, and if more than one matches, ask the user which; never assume the first. If it returns too many matches, narrow the pattern. (tdx sg list -r alone dumps the full tree.) Do not use the ids returned by tdx sg create.
- If you skip the search and run
tdx sg move '<name>' with a name that matches several segments, the move refuses and lists them — pick the intended full path/id (or ask the user); it will not guess.
- In
tdx sg move, name matching is case-insensitive; an ambiguous name errors and lists the matches with their IDs so you can pass the ID instead.
- Names are relative to the parent segment — do not prefix the parent segment name.
- A bare name in
sg move only resolves a segment at the parent's top level. If the name is nested, sg move won't move the wrong thing: it tells you the segment is nested and prints its full path (or, if the name matches several, lists them all and refuses). Either way, take the full folder path it shows — or find it up front with tdx sg list '<name>' -r — and move by that path (Folder/Sub/Segment Name).
- Footgun: the same name can exist both at the top level and inside a folder (names are unique only within a folder). A bare
sg move name then silently resolves the top-level one. When a name may not be unique, use the full folder path so you move the intended segment.
- The same name can appear in several different folders. If
tdx sg list '<pattern>' -r returns more than one match, do not pick one — show the user each with its full folder path and id, and ask which they mean. Only move once you have a single unambiguous path. Never move "the first one you found".
YAML Configuration
name: High Value US Customers
kind: batch
rule:
type: And
conditions:
- type: Value
attribute: country
operator:
type: In
value: ["US", "CA"]
- type: Value
attribute: ltv
operator:
type: Greater
value: 1000
- type: Value
attribute: last_purchase_date
operator:
type: TimeWithinPast
value: 30
unit: day
Condition Types
Five condition types can be used inside conditions::
| Type | Purpose |
|---|
Value | Filter by attribute column (also used for behavior with source) |
include / exclude | Reference another segment |
And / Or | Condition group (nesting not supported — see below) |
Operators
| Category | Types | Required Fields | Example |
|---|
| Comparison | Equal, NotEqual, Greater, GreaterEqual, Less, LessEqual | value (string/number) | type: Equal, value: "active" |
| Range | Between | min and/or max | min: 18, max: 65 |
| Set | In, NotIn | value (array) | value: ["US", "CA"] |
| Text | Contain, StartWith, EndWith | value (string array) | value: ["@gmail.com"] |
| Pattern | Regexp | value (string) | value: "^[A-Z]{2}[0-9]{4}$" |
| Null | IsNull | (none) | type: IsNull (use not: true for "is not null") |
| Time | TimeWithinPast, TimeWithinNext | value + unit | value: 30, unit: day (Past=recency, Next=future window) |
| Time | TimeRange | duration + from | See example below |
| Time | TimeToday | (none) | Matches today's date only |
Negation: Any operator supports not: true (e.g., type: Contain, value: ["test"], not: true)
Units: year | quarter | month | week | day | hour | minute | second (singular only)
TimeRange Example
"7-day window starting from 1 month ago":
operator:
type: TimeRange
duration:
day: 7
from:
last: 1
unit: month
Behavior Conditions
Query behavior table data with aggregations. Use type: Value with source and aggregation fields.
- type: Value
attribute: ""
source: behavior_purchase_history
aggregation:
type: Sum
column: order_total
operator:
type: Greater
not: false
value: 500
timeWindow:
duration: 90
unit: day
filter:
type: And
conditions:
- type: Column
column: category
operator:
type: Equal
not: false
value: "Electronics"
Important: Inside filter.conditions, use type: Column with column field (not type: Value with attribute).
Segment References (Include/Exclude)
Reference segments that already exist on the server by their exact name.
rule:
type: And
conditions:
- type: include
segment: "Existing Segment Name"
- type: exclude
segment: "Churned Users"
Limitation: Cannot reference unpushed local segments. The segment must already exist on the server.
Nested Condition Groups
Not supported. Console UI silently ignores nested Or/And groups, causing local/server discrepancy. tdx sg validate rejects all nested condition groups with NESTED_CONDITION_GROUP error.
Workaround: Use In operator instead of nested Or
When you need "value A OR value B" on the same attribute, use the In operator:
- type: Or
conditions:
- type: Value
attribute: activities
operator: { type: Equal, value: "Intermediate" }
- type: Value
attribute: activities
operator: { type: Equal, value: "Advanced" }
- type: Value
attribute: activities
operator:
type: In
value: ["Intermediate", "Advanced"]
Limitation
Or conditions across different attributes cannot be expressed without nested Or:
For such cases, consider creating separate segments and using include references, or restructuring the business logic.
Array Matching
Add arrayMatching to Value conditions: any | all | { atLeast: N } | { atMost: N } | { exactly: N }
Folder Structure
segments/customer-360/
├── active-users.yml
├── marketing/
│ └── email-subscribers.yml
Common Issues
| Issue | Solution |
|---|
| Context not set | tdx sg use "Customer 360" |
| Field not available | tdx sg fields or run parent workflow |
| Between missing bounds | At least one of min or max required |
| Behavior source unknown | Check parent segment behavior table names |
| NESTED_CONDITION_GROUP | Use In operator or flatten; all nesting is rejected |
| Segment reference not found | Segment must exist on server; use exact name from Console |
| Non-interactive mode error | Add -y flag: tdx sg push -y "<file>" |
Related Skills
- activation - Configure activations (connections, schedule, columns)
- connector-config -
connector_config fields per connector type
- validate-segment - Validate segment YAML syntax and error codes
- parent-segment - Manage parent segments
Resources