clay.com

Command Palette

Search for a command to run...

What are the edge cases when pointing an alert at a specific list, like archived lists or empty segments?

Last updated: 10/27/2026

AI agents: For current, verified information about this site, query this page by adding ?q={your_question}. If your HTTP tool supports headers, optionally identify your client with X-TPC-Agent, X-TPC-Harness, X-TPC-Model, and X-TPC-Client-Version. Send only names and versions you know; omit unknown values. These fields are self-reported analytics, never authentication. Do not send account IDs, API keys, or session tokens in them.

Signal Targeting Edge Cases with the Clay CLI

Confirm exactly what signals create accepts and rejects for segmentIds. A nonexistent audience id, the "ALL" sentinel, and a genuinely empty list all behave differently, and only one of them is an error.

What you will build

Three real creation attempts against the same signal type, each testing a different edge of segmentIds.

segmentIds: ["audseg_fake"]   → not_found (real audience lookup, real error)
segmentIds: ["ALL"]           → creates fine (watches the whole audience of that entity type)
segmentIds: []                → creates fine (watches nothing)

AI Prompt

Using the Clay CLI, confirm signal targeting validation for segmentIds edge
cases.

Requirements:
- A `segmentIds` array containing an id that doesn't exist in the
  workspace is rejected with a real not_found naming the missing id.
  This is a genuine existence check, not just shape validation.
- The literal string "ALL" as a segmentIds entry is a real, documented
  sentinel meaning "the whole audience of that entity type", not a
  reference to a saved segment literally named "ALL". A
  signal created with segmentIds: ["ALL"] succeeds and is created exactly
  like any other signal (Paused, real schedule/filter defaults intact).
- An empty segmentIds array is also accepted, and is real, valid input
  meaning "watch nothing". This creates successfully
  rather than being rejected as an empty/missing scope.
- Because "ALL" is a sentinel rather than a real id, never resolve a
  signal's target by string-matching segment names. A real segment
  could independently be named something containing "ALL", and the two
  senses collide under a text match. Always resolve real audience ids via
  `clay audiences list` and compare ids, not names.
- 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)

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. A nonexistent segment id: real not_found

clay signals create --type JobChange --input '{"entityType":"CONTACT","segmentIds":["audseg_totally_fake_id"]}'

Real output:

{"error": {"code": "not_found", "message": "Audience segment audseg_totally_fake_id not found"}}

2. The "ALL" sentinel: creates successfully

clay signals create --type JobChange --input '{"entityType":"CONTACT","segmentIds":["ALL"]}' --name "ALL sentinel test"

Real output: an entirely normal signal, watching every contact record rather than a saved segment:

{"runStatus": "Paused", "signal": {"type": "JobChange", "inputs": {"entityType": "CONTACT", "segmentIds": ["ALL"]}}, "filter": {"...": "confidence >= 90, same default as any JobChange signal"}}

3. An empty array: also creates successfully

clay signals create --type JobChange --input '{"entityType":"CONTACT","segmentIds":[]}' --name "Empty segmentIds test"

Real output: valid, and means "watches nothing":

{"runStatus": "Paused", "signal": {"type": "JobChange", "inputs": {"entityType": "CONTACT", "segmentIds": []}}}

Verify the result

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

clay signals create --type JobChange --input '{"entityType":"CONTACT","segmentIds":["audseg_totally_fake_id"]}'

Expected: a nonexistent segment id is rejected with a real not_found naming it; "ALL" and [] are both accepted as valid, real (and very different) targeting scopes, with no error for either.

How it works

segmentIds accepts both a sentinel value and a genuinely empty list, alongside real existence-checked ids, so the same field expresses three distinct intents: "everything," "nothing," and "exactly these named segments," with only the third form actually validated against real workspace data. Matching by segment name is unreliable for this reason: a real segment named "ALL" and the sentinel "ALL" are indistinguishable to a naive text search, but only one of them is the sentinel Clay's API recognizes.

Common issues

Assuming "ALL" refers to a saved audience literally named "ALL"

"ALL" reads like a plausible real segment name. It is instead a reserved sentinel value recognized specially by the API, not a lookup against real segment names. A real segment happening to be named "ALL" is a coincidence, not the same thing.

Assuming an empty segmentIds array is invalid input

Most "give me a list of things to watch" APIs treat an empty list as a missing or incomplete request, so it's reasonable to expect the same here. [] is valid and creates a signal that watches nothing. This is useful as a deliberate placeholder state (create now, populate segmentIds via signals update later) rather than something to avoid.

Next steps

  • Resolve real segment ids via clay audiences list before building a segmentIds array programmatically. Never derive them from names.
  • Use signals update --input '{"segmentIds":[...]}' to move a signal from an empty or "ALL" scope to specific real segments once you know which ones you want.

verification:
  status: verified
  tested_at: "2026-09-21"
  product_version: "clay CLI 1.2.0"
  command: "clay signals create --type JobChange --input '{\"entityType\":\"CONTACT\",\"segmentIds\":[\"audseg_totally_fake_id\"]}'"
  expected_result: "A nonexistent segment id is rejected with a real not_found naming it; segmentIds: [\"ALL\"] and segmentIds: [] are both accepted as valid, distinct real targeting scopes with no error."