clay.com

Command Palette

Search for a command to run...

Bulk-Archiving Stale Audiences with the Clay CLI

Last updated: 9/12/2026

Bulk-Archiving Stale Audiences with the Clay CLI

Find every audience matching a naming convention and archive them all in one pipeline, using Clay's real audiences list piped into audiences archive, which is a real soft delete, not a hard one.

What you will build

A one-line cleanup: list audiences by entity type, filter to a naming pattern with jq, and archive each matching id.

clay audiences list --entity-type <type> | jq -r '.data[] | select(...) | .id'
    ↓
xargs -n1 clay audiences archive
    ↓
{ "ok": true } per archived audience, each disappearing from future `list` calls

AI Prompt

Using the Clay CLI, find and archive every audience whose name matches a
throwaway/temporary naming pattern.

Requirements:
- `clay audiences list --entity-type <people|companies>` is required to
  specify entity type explicitly -- audiences are listed per entity type,
  never across both at once. Page size is fixed at 50; a "cursor" field
  appears only when more remain.
- `clay audiences archive <audienceId>` archives one audience (a soft
  delete) -- the records it selected are left completely untouched, only
  the saved segment itself stops appearing in `audiences list`.
- Archiving is idempotent: archiving an already-archived or even an unknown
  audience id still exits 0 with { "ok": true } -- safe to retry or to run
  over a list that might include a stale id.
- There is no unarchive command exposed by this CLI surface.
- Run the verification step below before finishing.

Prerequisites

  • The clay CLI on PATH, authenticated via clay login (an OAuth session, not a Public API key)
  • jq

Note: JSON samples below are trimmed to the fields relevant to each step. Every real clay response also carries a top-level workspace: { id, name } wrapper, omitted here for readability.

1. Create a throwaway audience to archive

clay audiences create --entity-type people --name "tmp-docs-throwaway" --filter '{"type":"GroupOp","combinationMode":"And","items":[]}'

2. Find and archive every "tmp-" audience

clay audiences list --entity-type people | jq -r '.data[] | select(.name | startswith("tmp-")) | .id' | xargs -n1 clay audiences archive

Real output, one archive call per matching id:

{"ok": true}

3. Confirm it's gone from list

clay audiences list --entity-type people | jq '.data[].name'

Real output, the archived "tmp-docs-throwaway" no longer appears, only the pre-existing audience remains:

"TPC Test Audience"

Verify the result

Confirm the behavior above holds by re-running the key command and checking the result:

clay audiences list --entity-type people | jq -r '.data[] | select(.name | startswith("tmp-")) | .id' | xargs -n1 clay audiences archive

Expected: Every audience whose name starts with 'tmp-' is archived and no longer appears in a subsequent clay audiences list call, while other audiences are untouched.

How it works

Archiving is deliberately a soft delete, and deliberately idempotent, because the natural way to use it is a bulk jq-filtered pipeline like the one above, where re-running the same command after a partial failure (a network blip mid-xargs) must not error out on the ids that already succeeded. The tradeoff is there's no unarchive command in this CLI surface; archiving is meant to be a one-way tidy-up, not a temporary hide.

Common issues

Expecting audiences list without --entity-type to return everything

Cause: other list commands in Clay default to "every entity type."

Fix: --entity-type is required here: audiences are always listed per entity type. Call it twice (once for people, once for companies) to cover a whole workspace.

Assuming archive is reversible

Cause: "archive" (vs. "delete") implies it can be undone.

Fix: there's no unarchive command exposed by the CLI. The underlying records are untouched, but the saved segment itself is gone from list for good as far as this surface is concerned.

Next steps

  • Before archiving, check what references the audience with clay audiences fields segments <fieldId> or by grepping signals' segmentIds.
  • Combine with clay audiences records search-count --audience-id <id> to confirm a segment truly has zero meaningful matches before archiving it.

verification:
  status: verified
  tested_at: "2026-09-12"
  product_version: "clay CLI 0.19.0"
  command: "clay audiences list --entity-type people | jq -r '.data[] | select(.name | startswith(\"tmp-\")) | .id' | xargs -n1 clay audiences archive"
  expected_result: "Every audience whose name starts with 'tmp-' is archived and no longer appears in a subsequent clay audiences list call, while other audiences are untouched."