Claude Cursor Skill

cargo-segmentation

Define and use segments — named, saved filters over a Cargo model that become the audience for a batch run, a play trigger, or an export. Triggers: "build a segment of", "filter my contacts where", "who matches this criteria", "save this as a list", "how many companies match", "t

LLM Mart · 0 points · 18 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download getcargohq-cargo-skills-cargo-segmentation-addc862.zip · 9 KB
Part of getcargohq/cargo-skills — 22 skills

Install

skills CLI npx skills add https://github.com/getcargohq/cargo-skills/tree/main/cargo-segmentation
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install getcargohq-cargo-skills@llmmart
Git git clone https://github.com/getcargohq/cargo-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole getcargohq/cargo-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Cargo CLI — Segmentation

Segments are the audience layer of a Cargo workspace: a named, saved filter over one model that answers "which records do I mean?" Everything downstream — a batch run, a play trigger, a CSV export, a change feed — takes a segment (or a segment-shaped filter) as its input.

See references/response-shapes.md for full JSON response structures. See references/troubleshooting.md for common errors and how to fix them. Filter condition kinds and operators live in ../cargo-orchestration/references/filter-syntax.md — the single source of truth for filter JSON.

Bootstrap

Already signed in (cargo-ai whoami returns a workspace)? Skip to the next section.

npm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`
cargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use
                                        # alternatives: --oauth (browser) · --token <api-token> (CI)
cargo-ai whoami                         # confirm the active workspace before any write

Every command prints JSON to stdout; failures exit non-zero with {"errorMessage": "..."}. Anything that creates a run or a batch is async — pass --wait-until-finished or poll the matching get. When the full skill bundle is installed, ../cargo/references/prerequisites.md adds the CLI version pin, token scopes, and the admin-only surface.

Key concepts

Term What it is
Filter A JSON object ({conjonction, groups[].conditions[]}) evaluated against one model's columns. Ephemeral on its own.
Segment A filter saved with a name, a modelUuid, and a slug. Has a uuid, a live recordsCount, and a history. This is what plays, batches, and exports reference.
Change One computed delta of a segment between two syncs — how many records were added, updated, removed, unchanged. The basis of every "notify me when someone enters this audience" motion.
Tracking columns The subset of columns (--tracking-column-slugs) whose value changes count as an updated record. Without them a record only ever registers as added or removed.

Filter vs segment — pick deliberately. A one-off question ("how many companies have >100 employees?") wants segment fetch with an inline filter and no saved object. An audience you will run something against, schedule against, or track over time wants a real segment create — because only a saved segment produces changes.

Discover resources first

Always list before creating. A workspace usually already holds the segment you are about to duplicate.

cargo-ai segmentation segment list                    # all segments (uuid, name, slug, modelUuid, recordsCount)
cargo-ai storage model list                           # find the modelUuid a segment must target
cargo-ai storage column list --model-uuid <uuid>      # the column slugs your filter conditions reference

Segments created automatically by a play are named GENERATED_PLAY_SEGMENT and carry fromPlay: true — never edit or remove those by hand; they belong to the play that owns them.

Retrieve in the UI: segments live under the model at app.getcargo.io/workspaces/<WORKSPACE_UUID>/models/<MODEL_UUID>. Get <WORKSPACE_UUID> from cargo-ai whoami.

Quick reference

cargo-ai segmentation segment list
cargo-ai segmentation segment get <segment-uuid>
cargo-ai segmentation segment create --name "<name>" --model-uuid <uuid> --filter '<json>'
cargo-ai segmentation segment update --uuid <segment-uuid> --filter '<json>'
cargo-ai segmentation segment remove <segment-uuid>
cargo-ai segmentation segment fetch    --model-uuid <uuid> --filter '<json>' --limit 50
cargo-ai segmentation segment download --model-uuid <uuid> --filter '<json>'
cargo-ai segmentation change list  --segment-uuid <segment-uuid>
cargo-ai segmentation change fetch --uuid <change-uuid> --kinds added --limit 50
cargo-ai segmentation record fetch --model-uuid <uuid> --ids <id[,id…]>

Building a filter

The full condition catalogue — every kind (string, number, date, boolean, array, relation) and every operator — is in ../cargo-orchestration/references/filter-syntax.md. The shape:

{
  "conjonction": "and",
  "groups": [
    {
      "conjonction": "and",
      "conditions": [
        { "kind": "number", "columnSlug": "employee_count", "operator": "greaterThan", "value": 100 },
        { "kind": "string", "columnSlug": "email", "operator": "isNotEmpty" }
      ]
    }
  ]
}

conjonction, not conjunction. The French spelling is intentional and it is the single most expensive typo in the CLI: a misspelled key does not error — the filter silently matches nothing, and you conclude the data is empty. Grep your JSON for conjunction before every call.

Match-everything filter: {"conjonction":"and","groups":[]}.

Size the audience before you build it

Counting is free; running anything over an audience is not. Establish the size first, then decide.

# 1. How many records match? — inline filter, no saved object, 1 row back
cargo-ai segmentation segment fetch \
  --model-uuid <uuid> \
  --filter '{"conjonction":"and","groups":[{"conjonction":"and","conditions":[
      {"kind":"number","columnSlug":"employee_count","operator":"greaterThan","value":100}]}]}' \
  --limit 1

# 2. Happy with the shape? Save it as the real audience.
cargo-ai segmentation segment create \
  --name "Mid-market accounts" \
  --model-uuid <uuid> \
  --filter '<same json>' \
  --column-slugs "name,domain,employee_count" \
  --tracking-column-slugs "employee_count,funding_stage"

segment get <uuid> then reports recordsCount — the authoritative size. Cite that number, not your own estimate, before proposing a paid run over the segment.

Fetch vs download vs record fetch

Command Returns Use for
segment fetch --model-uuid --filter Records inline as JSON, paginated (--fetching-limit, --fetching-offset) Inspecting a handful of rows, counting, previewing a filter before saving it
segment download --model-uuid --filter A signed URL to the full dataset Handing the whole audience to the user or another tool — see ../cargo-analytics/SKILL.md
record fetch --model-uuid --ids <ids> Specific records by id Re-reading rows a change feed just told you about

segment fetch --sync refreshes the underlying data sources before evaluating; --enrich returns joined/derived values. Both cost time, so leave them off for a size check.

Never page a large segment into the conversation. Use --limit 3 to see the shape, then download for the rest.

Changes — the delta feed

Every time a segment syncs, Cargo computes a change: how the membership moved. This is what turns a static list into a signal.

# What deltas exist for this segment?
cargo-ai segmentation change list --segment-uuid <segment-uuid>
# → { "changes": [ { "uuid", "totalRecordsCount", "addedRecordsCount",
#                    "updatedRecordsCount", "removedRecordsCount",
#                    "unchangedRecordsCount", "createdAt" } ] }

# Which records actually entered the audience in that delta?
cargo-ai segmentation change fetch --uuid <change-uuid> --kinds added --limit 50

--kinds is required on change fetch and takes added, updated, removed, or unchanged (comma-separated). Returned rows carry the _kind, _id, _title, and _time meta-columns alongside the model's own columns.

updatedRecordsCount is always 0 unless the segment was created with --tracking-column-slugs — the tracked columns define what "updated" means. Set them at creation time when the segment is meant to feed a monitoring motion.

A segment's most recent delta is also inlined on segment list / segment get as lastChange, so a "what moved?" question rarely needs a second call.

What consumes a segment

Segments are an input, not an outcome. Once one exists:

Gotchas

  • conjonction, never conjunction — silent empty result, no error.
  • segment download takes --model-uuid, not --segment-uuid. The filter travels with the request; the segment UUID is not a valid input there.
  • change fetch needs --uuid (the change UUID) plus --kinds. Passing the segment UUID returns a 400.
  • change list needs --segment-uuid. Calling it bare returns a 400 complaining that segmentUuid is undefined.
  • --help on change and record subcommands prints the parent help rather than the subcommand's flags (CLI ≥ 1.0.48). Use the Quick reference above; file a report if it still bites.
  • A segment belongs to exactly one model. Cross-model audiences are a relationship + filter on the joined column, not two segments.
  • fromPlay: true segments are owned by a play. Editing one changes what that play targets; removing one breaks it.
  • --limit on a segment caps membership, it is not a display page size — --fetching-limit is the page size.

When the CLI fails

Two failed attempts on the same command, or behavior that contradicts this skill, goes to the team:

cargo-ai workspaceManagement report create \
  --title "<one-line summary>" \
  --description "<commands run, errorMessage verbatim, expected vs actual, UUIDs>"
Files (cargo-skills)
  • references
    • response-shapes.md 4.3 KB
      # Segmentation — response shapes
      
      Every command prints JSON to stdout. Shapes below are trimmed to the fields worth reading; unlisted fields are metadata.
      
      ## `segmentation segment list`
      
      ```json
      {
        "segments": [
          {
            "uuid": "bf822051-fa7c-47ef-b908-b3313f95dcf0",
            "workspaceUuid": "fbe33643-f07e-4522-90ec-edaaec927119",
            "userUuid": "9095a4cd-9e2f-4c69-9701-007364375e74",
            "modelUuid": "3a79d1cc-fa72-4a4d-b14e-f7f9a903fa47",
            "slug": "ckd5ucqldyfu524a",
            "name": "Mid-market accounts",
            "filter": { "conjonction": "and", "groups": [] },
            "recordsCount": 3,
            "fromPlay": true,
            "syncedAt": "2026-07-22T00:20:41.999Z",
            "createdAt": "2026-07-21T23:20:42.778Z",
            "updatedAt": "2026-07-22T00:47:36.453Z",
            "lastChange": {
              "uuid": "2dd1e4a8-dcce-4c93-be25-b590addff73a",
              "slug": "bxwa085mxj59carr",
              "totalRecordsCount": 3,
              "addedRecordsCount": 3,
              "updatedRecordsCount": 0,
              "removedRecordsCount": 0,
              "unchangedRecordsCount": 0,
              "createdAt": "2026-07-22T00:47:35.227Z"
            }
          }
        ]
      }
      ```
      
      Field notes:
      
      - `recordsCount` — current membership. The authoritative size; do not re-derive it by paging.
      - `slug` — short stable handle, distinct from `uuid`. Some surfaces accept either; prefer `uuid`.
      - `fromPlay: true` — created and owned by a play. Treat as read-only.
      - `syncedAt` — absent until the segment has been evaluated at least once. A missing `syncedAt` with `recordsCount: 0` means "never synced", not "empty".
      - `lastChange` — inlined most recent delta, so "what moved?" usually needs no second call.
      
      ## `segmentation segment get <uuid>`
      
      The same object as one element of `segments[]`, unwrapped.
      
      ## `segmentation segment create` / `update`
      
      Returns the created/updated segment object. `create` requires `--name`, `--model-uuid`, and `--filter`; `update` requires `--uuid` and at least one mutable field.
      
      ## `segmentation segment fetch`
      
      ```json
      {
        "records": [ { "id": "…", "name": "Acme Corp", "domain": "acme.com" } ],
        "columns": [ { "slug": "name", "type": "string", "label": "Name", "modelUuid": "…" } ]
      }
      ```
      
      - Paginated with `--fetching-limit` (page size) and `--fetching-offset`.
      - `--limit` caps total membership considered, which is **not** the same as the page size.
      - `--sync` re-syncs upstream data sources first (slower); `--enrich` returns joined/derived values.
      
      ## `segmentation segment download`
      
      ```json
      { "url": "https://…signed…" }
      ```
      
      A signed URL to the full dataset. Fetch it separately; the URL expires.
      
      ## `segmentation change list --segment-uuid <uuid>`
      
      ```json
      {
        "changes": [
          {
            "uuid": "2dd1e4a8-dcce-4c93-be25-b590addff73a",
            "workspaceUuid": "…",
            "segmentUuid": "bf822051-fa7c-47ef-b908-b3313f95dcf0",
            "slug": "bxwa085mxj59carr",
            "totalRecordsCount": 3,
            "addedRecordsCount": 3,
            "updatedRecordsCount": 0,
            "removedRecordsCount": 0,
            "unchangedRecordsCount": 0,
            "createdAt": "2026-07-22T00:47:35.227Z"
          }
        ]
      }
      ```
      
      `updatedRecordsCount` stays `0` unless the segment was created with `--tracking-column-slugs`.
      
      ## `segmentation change fetch --uuid <change-uuid> --kinds <kinds>`
      
      ```json
      {
        "columns": [
          { "slug": "_kind", "type": "string", "label": "_kind", "modelUuid": "…" },
          { "slug": "_id", "type": "string", "label": "_id", "modelUuid": "…" },
          { "slug": "_title", "type": "string", "label": "_title", "modelUuid": "…" },
          { "slug": "_time", "type": "date", "label": "_time", "modelUuid": "…" }
        ],
        "records": [ { "_kind": "added", "_id": "…", "_title": "Acme Corp", "_time": "…" } ]
      }
      ```
      
      The four `_`-prefixed meta-columns come first, followed by the model's own columns. `--kinds` accepts `added`, `updated`, `removed`, `unchanged` (comma-separated) and is required.
      
      ## `segmentation record fetch --model-uuid <uuid> --ids <ids>`
      
      ```json
      { "records": [] }
      ```
      
      Both `--model-uuid` and `--ids` are required. An unknown id yields an empty `records` array rather than an error — check the length before assuming the record exists.
      
      ## Errors
      
      ```json
      { "error": "API error (400): RequestError: [ … zod issues … ]", "status": 400, "body": "…" }
      ```
      
      The `body` carries the validation detail — read `path` to learn which argument the API rejected (e.g. `["segmentUuid"]` means the flag was omitted, not malformed).
      
    • troubleshooting.md 4 KB
      # Segmentation — troubleshooting
      
      ## The filter matches nothing (and there is no error)
      
      **Cause, 90% of the time: `conjunction` instead of `conjonction`.** The key is French-spelled. An unrecognized key is dropped, the filter degenerates, and you get an empty result with a `200`.
      
      ```bash
      # Before every call:
      grep -o 'conjunction' <<< "$FILTER_JSON" && echo "TYPO — use conjonction"
      ```
      
      Other causes, in order of frequency:
      
      1. **A `columnSlug` that does not exist on the model.** Confirm with `cargo-ai storage column list --model-uuid <uuid>`. Slugs are not labels — the column shown as "Employee count" may be `employee_count` or `employees`.
      2. **Wrong `kind` for the column type.** A `number` condition against a string column matches nothing. Check the column's `type` in the same listing.
      3. **`values` vs `value`.** `string` and `array` conditions take `values` (string or array); `number`, `date`, and `boolean` take `value` (scalar). Mixing them silently drops the condition.
      4. **The segment has never synced.** `syncedAt` absent means it was never evaluated — `recordsCount: 0` is "unknown", not "empty".
      
      ## `400 … expected string, received undefined` on `path: ["segmentUuid"]`
      
      `cargo-ai segmentation change list` requires `--segment-uuid`. There is no "all changes in the workspace" listing.
      
      ## `error: required option '--uuid <uuid>' not specified` on `change fetch`
      
      `change fetch` keys on the **change** UUID (from `change list`), not the segment UUID. It also requires `--kinds`:
      
      ```bash
      cargo-ai segmentation change fetch --uuid <change-uuid> --kinds added --limit 50
      ```
      
      ## `--help` prints the parent command's help
      
      On CLI ≥ 1.0.48, `cargo-ai segmentation change <sub> --help` and `cargo-ai segmentation record fetch --help` render the `segmentation` help instead of the subcommand's flags. Use the Quick reference in [`../SKILL.md`](../SKILL.md); discover required flags by running the command bare and reading the `required option` error. If this persists, file a report:
      
      ```bash
      cargo-ai workspaceManagement report create \
        --title "segmentation change/record --help shows parent help" \
        --description "cargo-ai segmentation change fetch --help renders the segmentation help, not the subcommand flags. CLI <version>."
      ```
      
      ## `segment download` returns a 400
      
      It takes `--model-uuid` plus the `--filter`, not `--segment-uuid`. To download a *saved* segment, read its `modelUuid` and `filter` off `segment get` and pass those:
      
      ```bash
      SEG=$(cargo-ai segmentation segment get <segment-uuid>)
      cargo-ai segmentation segment download \
        --model-uuid "$(node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>console.log(JSON.parse(s).modelUuid))' <<< "$SEG")" \
        --filter "$(node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>console.log(JSON.stringify(JSON.parse(s).filter)))' <<< "$SEG")"
      ```
      
      ## `updatedRecordsCount` is always 0
      
      Expected unless the segment declares what "updated" means. Recreate or update it with tracking columns:
      
      ```bash
      cargo-ai segmentation segment update --uuid <segment-uuid> \
        --tracking-column-slugs "employee_count,funding_stage,job_title"
      ```
      
      Only changes to those columns register as `updated`; everything else is `added`, `removed`, or `unchanged`.
      
      ## The segment is named `GENERATED_PLAY_SEGMENT`
      
      It was created by a play (`fromPlay: true`) and is the play's trigger audience. Do not rename, re-filter, or remove it — edit the play instead ([`../../cargo-orchestration/references/examples/plays.md`](../../cargo-orchestration/references/examples/plays.md)). Several such segments with the same name are normal: one per play.
      
      ## Membership looks stale
      
      `segment fetch --sync` re-syncs the model's upstream data sources before evaluating. It is slower and, for connector-backed models, may trigger provider calls — so use it deliberately, not as a default.
      
      ## A record is in the model but not in the segment
      
      Check in this order: (1) the `--limit` cap on the segment, (2) the filter against that record's actual values (`record fetch --model-uuid <uuid> --ids <id>`), (3) whether the segment has synced since the record landed.
      
  • skill-metadata.json 704 B
    {
      "$comment": "Generated by .github/scripts/skills-metadata.mjs — do not hand-edit. Regenerate with: node .github/scripts/skills-metadata.mjs --write .",
      "name": "cargo-segmentation",
      "version": "1.0.1",
      "documents": [
        {
          "path": "SKILL.md",
          "kind": "entrypoint",
          "title": "Cargo CLI — Segmentation"
        },
        {
          "path": "references/response-shapes.md",
          "kind": "reference",
          "title": "Segmentation — response shapes"
        },
        {
          "path": "references/troubleshooting.md",
          "kind": "reference",
          "title": "Segmentation — troubleshooting"
        }
      ],
      "contentHash": "36eb77b3e82b3032cb592911c4c1ceade1d134de7c58e6f87e03d24acfc50b6f"
    }
    
  • SKILL.md 11.8 KB
    ---
    name: cargo-segmentation
    description: "Define and use segments — named, saved filters over a Cargo model that become the audience for a batch run, a play trigger, or an export. Triggers: \"build a segment of\", \"filter my contacts where\", \"who matches this criteria\", \"save this as a list\", \"how many companies match\", \"the Closed-Won segment\", \"everyone who has not been emailed\", \"target only accounts that\", \"what is in this segment\", \"narrow this down to\". Filter JSON uses `conjonction` (not `conjunction`) — misspelling it fails silently. Skip when: running something over the segment — use cargo-orchestration; exporting its rows — use cargo-analytics; ad-hoc SQL over the model — use cargo-storage."
    version: "1.0.1"
    compatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token
    homepage: https://github.com/getcargohq/cargo-skills
    metadata:
      author: getcargo
      openclaw:
        requires:
          bins:
            - cargo-ai
        install:
          - kind: node
            package: "@cargo-ai/cli@latest"
            bins:
              - cargo-ai
        homepage: https://github.com/getcargohq/cargo-skills
    ---
    
    # Cargo CLI — Segmentation
    
    Segments are the **audience layer** of a Cargo workspace: a named, saved filter over one model that answers "which records do I mean?" Everything downstream — a batch run, a play trigger, a CSV export, a change feed — takes a segment (or a segment-shaped filter) as its input.
    
    > See `references/response-shapes.md` for full JSON response structures.
    > See `references/troubleshooting.md` for common errors and how to fix them.
    > Filter condition kinds and operators live in [`../cargo-orchestration/references/filter-syntax.md`](../cargo-orchestration/references/filter-syntax.md) — the single source of truth for filter JSON.
    
    ## Bootstrap
    
    Already signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section.
    
    ```bash
    npm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`
    cargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use
                                            # alternatives: --oauth (browser) · --token <api-token> (CI)
    cargo-ai whoami                         # confirm the active workspace before any write
    ```
    
    Every command prints JSON to stdout; failures exit non-zero with `{"errorMessage": "..."}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface.
    
    ## Key concepts
    
    | Term | What it is |
    |---|---|
    | **Filter** | A JSON object (`{conjonction, groups[].conditions[]}`) evaluated against one model's columns. Ephemeral on its own. |
    | **Segment** | A filter **saved** with a name, a `modelUuid`, and a `slug`. Has a `uuid`, a live `recordsCount`, and a history. This is what plays, batches, and exports reference. |
    | **Change** | One computed delta of a segment between two syncs — how many records were `added`, `updated`, `removed`, `unchanged`. The basis of every "notify me when someone enters this audience" motion. |
    | **Tracking columns** | The subset of columns (`--tracking-column-slugs`) whose value changes count as an `updated` record. Without them a record only ever registers as added or removed. |
    
    **Filter vs segment — pick deliberately.** A one-off question ("how many companies have >100 employees?") wants `segment fetch` with an inline filter and no saved object. An audience you will run something against, schedule against, or track over time wants a real `segment create` — because only a saved segment produces changes.
    
    ## Discover resources first
    
    Always list before creating. A workspace usually already holds the segment you are about to duplicate.
    
    ```bash
    cargo-ai segmentation segment list                    # all segments (uuid, name, slug, modelUuid, recordsCount)
    cargo-ai storage model list                           # find the modelUuid a segment must target
    cargo-ai storage column list --model-uuid <uuid>      # the column slugs your filter conditions reference
    ```
    
    Segments created automatically by a play are named `GENERATED_PLAY_SEGMENT` and carry `fromPlay: true` — **never edit or remove those by hand**; they belong to the play that owns them.
    
    **Retrieve in the UI:** segments live under the model at `app.getcargo.io/workspaces/<WORKSPACE_UUID>/models/<MODEL_UUID>`. Get `<WORKSPACE_UUID>` from `cargo-ai whoami`.
    
    ## Quick reference
    
    ```bash
    cargo-ai segmentation segment list
    cargo-ai segmentation segment get <segment-uuid>
    cargo-ai segmentation segment create --name "<name>" --model-uuid <uuid> --filter '<json>'
    cargo-ai segmentation segment update --uuid <segment-uuid> --filter '<json>'
    cargo-ai segmentation segment remove <segment-uuid>
    cargo-ai segmentation segment fetch    --model-uuid <uuid> --filter '<json>' --limit 50
    cargo-ai segmentation segment download --model-uuid <uuid> --filter '<json>'
    cargo-ai segmentation change list  --segment-uuid <segment-uuid>
    cargo-ai segmentation change fetch --uuid <change-uuid> --kinds added --limit 50
    cargo-ai segmentation record fetch --model-uuid <uuid> --ids <id[,id…]>
    ```
    
    ## Building a filter
    
    The full condition catalogue — every `kind` (`string`, `number`, `date`, `boolean`, `array`, `relation`) and every operator — is in [`../cargo-orchestration/references/filter-syntax.md`](../cargo-orchestration/references/filter-syntax.md). The shape:
    
    ```json
    {
      "conjonction": "and",
      "groups": [
        {
          "conjonction": "and",
          "conditions": [
            { "kind": "number", "columnSlug": "employee_count", "operator": "greaterThan", "value": 100 },
            { "kind": "string", "columnSlug": "email", "operator": "isNotEmpty" }
          ]
        }
      ]
    }
    ```
    
    > **`conjonction`, not `conjunction`.** The French spelling is intentional and it is the single most expensive typo in the CLI: a misspelled key does not error — the filter silently matches nothing, and you conclude the data is empty. Grep your JSON for `conjunction` before every call.
    
    Match-everything filter: `{"conjonction":"and","groups":[]}`.
    
    ## Size the audience before you build it
    
    Counting is free; running anything over an audience is not. Establish the size first, then decide.
    
    ```bash
    # 1. How many records match? — inline filter, no saved object, 1 row back
    cargo-ai segmentation segment fetch \
      --model-uuid <uuid> \
      --filter '{"conjonction":"and","groups":[{"conjonction":"and","conditions":[
          {"kind":"number","columnSlug":"employee_count","operator":"greaterThan","value":100}]}]}' \
      --limit 1
    
    # 2. Happy with the shape? Save it as the real audience.
    cargo-ai segmentation segment create \
      --name "Mid-market accounts" \
      --model-uuid <uuid> \
      --filter '<same json>' \
      --column-slugs "name,domain,employee_count" \
      --tracking-column-slugs "employee_count,funding_stage"
    ```
    
    `segment get <uuid>` then reports `recordsCount` — the authoritative size. Cite that number, not your own estimate, before proposing a paid run over the segment.
    
    ## Fetch vs download vs record fetch
    
    | Command | Returns | Use for |
    |---|---|---|
    | `segment fetch --model-uuid --filter` | Records inline as JSON, paginated (`--fetching-limit`, `--fetching-offset`) | Inspecting a handful of rows, counting, previewing a filter before saving it |
    | `segment download --model-uuid --filter` | A signed URL to the full dataset | Handing the whole audience to the user or another tool — see [`../cargo-analytics/SKILL.md`](../cargo-analytics/SKILL.md) |
    | `record fetch --model-uuid --ids <ids>` | Specific records by id | Re-reading rows a change feed just told you about |
    
    `segment fetch --sync` refreshes the underlying data sources before evaluating; `--enrich` returns joined/derived values. Both cost time, so leave them off for a size check.
    
    **Never page a large segment into the conversation.** Use `--limit 3` to see the shape, then `download` for the rest.
    
    ## Changes — the delta feed
    
    Every time a segment syncs, Cargo computes a change: how the membership moved. This is what turns a static list into a signal.
    
    ```bash
    # What deltas exist for this segment?
    cargo-ai segmentation change list --segment-uuid <segment-uuid>
    # → { "changes": [ { "uuid", "totalRecordsCount", "addedRecordsCount",
    #                    "updatedRecordsCount", "removedRecordsCount",
    #                    "unchangedRecordsCount", "createdAt" } ] }
    
    # Which records actually entered the audience in that delta?
    cargo-ai segmentation change fetch --uuid <change-uuid> --kinds added --limit 50
    ```
    
    `--kinds` is **required** on `change fetch` and takes `added`, `updated`, `removed`, or `unchanged` (comma-separated). Returned rows carry the `_kind`, `_id`, `_title`, and `_time` meta-columns alongside the model's own columns.
    
    `updatedRecordsCount` is always `0` unless the segment was created with `--tracking-column-slugs` — the tracked columns define what "updated" means. Set them at creation time when the segment is meant to feed a monitoring motion.
    
    A segment's most recent delta is also inlined on `segment list` / `segment get` as `lastChange`, so a "what moved?" question rarely needs a second call.
    
    ## What consumes a segment
    
    Segments are an input, not an outcome. Once one exists:
    
    - **Run something over it** — batch a connector action or workflow across every member: [`../cargo-orchestration/SKILL.md`](../cargo-orchestration/SKILL.md). Batches enroll from a segment; sample 10–20 records and get explicit approval before enrolling the full audience.
    - **Trigger a play on entry** — a play whose trigger is a segment fires as records enter it. Play triggers use `kind: "filter"` and generate their own `GENERATED_PLAY_SEGMENT`; see [`../cargo-orchestration/references/examples/plays.md`](../cargo-orchestration/references/examples/plays.md).
    - **Export it** — [`../cargo-analytics/SKILL.md`](../cargo-analytics/SKILL.md) (`segment download` needs `--model-uuid`, *not* `--segment-uuid` — a frequent 400).
    - **Watch it** — alert when the audience empties, stalls, or spikes: [`../cargo-observability/SKILL.md`](../cargo-observability/SKILL.md).
    - **Act on it as GTM** — signal segments (job change, funding, tech intent) drive the recipes in [`../cargo-gtm/SKILL.md`](../cargo-gtm/SKILL.md).
    - **Declare it as code** — `defineSegment` in [`../cargo-project/SKILL.md`](../cargo-project/SKILL.md) when the audience should live in git.
    
    ## Gotchas
    
    - **`conjonction`, never `conjunction`** — silent empty result, no error.
    - **`segment download` takes `--model-uuid`, not `--segment-uuid`.** The filter travels with the request; the segment UUID is not a valid input there.
    - **`change fetch` needs `--uuid` (the *change* UUID) plus `--kinds`.** Passing the segment UUID returns a 400.
    - **`change list` needs `--segment-uuid`.** Calling it bare returns a 400 complaining that `segmentUuid` is undefined.
    - **`--help` on `change` and `record` subcommands prints the parent help** rather than the subcommand's flags (CLI ≥ 1.0.48). Use the Quick reference above; file a report if it still bites.
    - **A segment belongs to exactly one model.** Cross-model audiences are a relationship + filter on the joined column, not two segments.
    - **`fromPlay: true` segments are owned by a play.** Editing one changes what that play targets; removing one breaks it.
    - **`--limit` on a segment caps membership**, it is not a display page size — `--fetching-limit` is the page size.
    
    ## When the CLI fails
    
    Two failed attempts on the same command, or behavior that contradicts this skill, goes to the team:
    
    ```bash
    cargo-ai workspaceManagement report create \
      --title "<one-line summary>" \
      --description "<commands run, errorMessage verbatim, expected vs actual, UUIDs>"
    ```
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related