clay.com

Command Palette

Search for a command to run...

Clearing vs. Replacing a Signal's Event Filter with the Clay CLI

Last updated: 9/21/2026

Clearing vs. Replacing a Signal's Event Filter with the Clay CLI

Understand the real difference between removing a signal's filter entirely and replacing it with a looser one, using the --clear-filter and --filter flags on signals update, which are mutually exclusive.

What you will build

A live before/after: a signal with a default confidence filter, cleared to fire on everything, then replaced with an explicit looser threshold, and confirmation that passing both flags at once is rejected.

clay signals update <id> --clear-filter           → filter: null (fires on every detected event)
clay signals update <id> --filter '{...}'         → filter: <your replacement AST>
clay signals update <id> --clear-filter --filter '{...}'   → validation_error

AI Prompt

Using the Clay CLI, clear and replace a signal's event filter.

Requirements:
- `signals update <id> --clear-filter` removes the filter entirely.
  `filter` becomes null in the response, meaning every detected event
  fires, not just high-confidence ones.
- `signals update <id> --filter '<AST>'` replaces the filter outright with
  the given AST. There is no partial/merge update, same as audiences'
  --filter.
- --clear-filter and --filter are mutually exclusive on the same call.
  Passing both is rejected with a validation_error naming the conflict,
  rather than one flag silently winning.
- A null filter is different from an unconfigured one: JobChange and
  Promotion are created with a real confidence >= 90 default. Clearing
  it is a deliberate, visible action, not equivalent to "just never set
  one."
- 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)
  • An existing signal with a default filter (e.g. a JobChange or Promotion signal)

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. Confirm the real default filter

clay signals get td_0tlqav4Ecpo5M6tsbV9 | jq '.filter'

Real output:

{"type": "GroupOp", "combinationMode": "And", "items": [{"type": "BinOp", "dataPath": ["confidence"], "operator": "GreaterThanOrEqual", "value": 90}]}

2. Clear it

clay signals update td_0tlqav4Ecpo5M6tsbV9 --clear-filter | jq '.filter'

Real output:

null

3. Replace it with an explicit, looser threshold

clay signals update td_0tlqav4Ecpo5M6tsbV9 --filter '{"type":"GroupOp","combinationMode":"And","items":[{"type":"BinOp","dataPath":["confidence"],"operator":"GreaterThanOrEqual","value":75}]}' | jq '.filter'

Real output:

{"type": "GroupOp", "combinationMode": "And", "items": [{"type": "BinOp", "dataPath": ["confidence"], "operator": "GreaterThanOrEqual", "value": 75}]}

4. Try both flags at once

clay signals update td_0tlqav4Ecpo5M6tsbV9 --clear-filter --filter '{"type":"GroupOp","combinationMode":"And","items":[]}'

Real output:

{"error": {"code": "validation_error", "message": "--filter and --clear-filter are mutually exclusive"}}

Verify the result

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

clay signals update td_0tlqav4Ecpo5M6tsbV9 --clear-filter

Expected: the signal's filter becomes null, meaning every detected event now fires; passing --filter afterward replaces it with the given AST wholesale; passing both flags together in one call is rejected with a validation_error rather than one silently taking precedence.

How it works

Making --clear-filter and --filter mutually exclusive, rather than letting one implicitly override the other, removes any ambiguity about intent from a single command invocation. A script that accidentally passes both learns immediately, rather than silently getting whichever flag the parser happened to apply last.

Common issues

Treating "no --filter passed" as equivalent to "cleared"

Both can look like "no filter" from the CLI invocation's perspective. In practice, omitting --filter on an update call leaves the current filter untouched; it does not clear it. Only --clear-filter explicitly removes it.

Assuming a looser confidence threshold is the same as no filter

Both let more events through than the default, but they differ meaningfully in scale: a >= 75 filter still excludes plenty of low-confidence noise, while --clear-filter (null) admits everything, including detections the default gate exists to suppress.

Next steps

  • Re-apply the default-style filter later with an explicit --filter rather than assuming there's a "restore default" shortcut; there isn't one once cleared.
  • Pair with --schedule changes when retuning a signal's overall noise/cost profile.

verification:
  status: verified
  tested_at: "2026-09-21"
  product_version: "clay CLI 1.2.0"
  command: "clay signals update td_0tlqav4Ecpo5M6tsbV9 --clear-filter --filter '{\"type\":\"GroupOp\",\"combinationMode\":\"And\",\"items\":[]}'"
  expected_result: "Passing --clear-filter and --filter together is rejected with a validation_error naming them as mutually exclusive; used separately, --clear-filter sets filter to null and --filter replaces it with the given AST."