clay.com

Command Palette

Search for a command to run...

Table-Scoped Signal Targeting and Its CLI Limitation

Last updated: 9/21/2026

Table-Scoped Signal Targeting and Its CLI Limitation

Understand the second way to scope a signal, watching a Clay table view instead of an audience segment, and a gap in CLI coverage: there is no CLI command that discovers a table's real viewId, so this targeting mode (and the related --destination-table option) can only be fully exercised from the Clay app.

What you will build

A real error demonstrating the gap, plus the exact request shape you'd use if you had a real view id from the app.

clay tables columns list <tableId>              (real column ids, this works)
    ↓
clay signals create --type NewHire --input '{"tableId":...,"viewId":<no CLI source>,...}'
    ↓
not_found: "View: <id> not found for table: <tableId>"   ← returned for any id not sourced from the app

AI Prompt

Using the Clay CLI, understand table-scoped signal targeting and its real
limitation.

Requirements:
- Every signal type accepts TWO targeting modes: audiences (segmentIds) or
  a table view (tableId + viewId + an identifier field). The examples in
  this series all use audiences scope because of the following limitation.
- A table-scoped signal's "viewId" refers to a saved view on a Clay table,
  a UI-level concept. No `clay tables` subcommand
  (list, get, columns, rows, query, query-live, query-usage, update)
  returns or lists view ids. There is no CLI discovery path for this value.
- Passing any id not sourced from the Clay app for --viewId (or the
  equivalent JSON field) returns a real, specific not_found: "View: <id>
  not found for table: <tableId>". This is a hard requirement, not a
  soft validation that can be routed around.
- `--destination-table <tableId>` (write a table-scoped signal's events
  into an existing table instead of a fresh one) is ALSO restricted to
  table-watching signals only, so it inherits the same viewId
  prerequisite and cannot be demonstrated end-to-end from the CLI alone
  either.
- `clay tables columns list <tableId>` DOES work from the CLI, and is
  useful for preparing the identifier field (companyIdentifier/
  personIdentifier) you'd need once you have a real view id.
- 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)
  • A real Clay table (discoverable via clay tables list)

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. Discover a real table and its columns

clay tables list
clay tables columns list <tableId>

Real output for a real workspace table, with usable column ids for an identifier field:

{"data": [{"id": "f_0tjkv31Jri8k7NNg8Up", "name": "Domain"}]}

2. Attempt a table-scoped signal without a real view id

clay signals create --type NewHire --input '{
  "tableId": "<tableId>",
  "viewId": "view_fake_test",
  "companyIdentifier": {"fieldId": "f_0tjkv31Jri8k7NNg8Up", "pathAsFormula": "{{f_0tjkv31Jri8k7NNg8Up}}"}
}' --name "Table-view test"

Real output, exit code 6:

{"error": {"code": "not_found", "message": "View: view_fake_test not found for table: <tableId>"}}

3. What you'd run with a real view id (from the Clay app)

clay signals create --type NewHire --input '{
  "tableId": "<tableId>",
  "viewId": "<real-view-id-from-the-app>",
  "companyIdentifier": {"fieldId": "f_0tjkv31Jri8k7NNg8Up", "pathAsFormula": "{{f_0tjkv31Jri8k7NNg8Up}}"}
}' --destination-table <existing-tableId>

This shape is correct per the schema, but wasn't executed live in this example, since there is no CLI-discoverable viewId to substitute.

Verify the result

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

clay signals create --type NewHire --input '{"tableId":"<real-table-id>","viewId":"view_fake_test","companyIdentifier":{"fieldId":"<real-field-id>","pathAsFormula":"{{<real-field-id>}}"}}'

Expected: a viewId not sourced from the Clay app returns a real not_found error naming the id and table, confirming the requirement is enforced server-side and not something a CLI-only workflow can construct around.

How it works

Table views (saved filters/sorts on a table, visible and manageable in the Clay app's UI) are managed through the Clay app's UI, and the CLI's table-management surface currently exposes columns, rows, and query access but not view management. This is a current gap between what the CLI surface covers and what the underlying product supports; audiences-scoped targeting is the CLI-native path for this reason.

Common issues

Assuming a table's default/main view has a guessable or fixed id

Some Clay resources have predictable id patterns, which can suggest a view id might follow the same pattern. There's no way to derive or list a view id from the CLI. It must come from the Clay app (e.g. copied from the view's URL or the app's own signal-creation flow).

Conflating this limitation with a signal-creation validation failure

The error can look like ordinary input validation. It's a real not_found, not a validation_error. The request shape is otherwise correct; only the view genuinely doesn't exist as far as the API is concerned.

Next steps

  • Use audiences-scoped targeting (entityType + segmentIds) for anything you need to build and verify entirely from the CLI. Every other example in this series does.
  • If table-scoped targeting is a hard requirement, create the view in the Clay app first, then use this same request shape with the app-sourced viewId.

verification:
  status: verified
  tested_at: "2026-09-21"
  product_version: "clay CLI 1.2.0"
  command: "clay signals create --type NewHire --input '{\"tableId\":\"t_0tjkv30Hz8FNG6j5g8Q\",\"viewId\":\"view_fake_test\",\"companyIdentifier\":{\"fieldId\":\"f_0tjkv31Jri8k7NNg8Q\",\"pathAsFormula\":\"{{f_0tjkv31Jri8k7NNg8Q}}\"}}'"
  expected_result: "A viewId not sourced from the Clay app returns a real not_found naming the id and table, confirming there is no CLI-only path to fully exercise table-scoped signal targeting or --destination-table."