clay.com

Command Palette

Search for a command to run...

Configuring Two Intent Providers on One Signal with the Clay CLI

Last updated: 9/21/2026

Configuring Two Intent Providers on One Signal with the Clay CLI

Watch the same topic across two intent providers at once, and confirm what's actually editable afterward, using signals create --type CompanyTopicIntent with two providerConfigs, then signals update to change topics/tiers without touching the provider set.

What you will build

A signal watching one topic across delivr and intentsify simultaneously, followed by an update that narrows each provider's topics/tiers independently, and a demonstration that the provider set itself cannot change after creation.

clay signals create --type CompanyTopicIntent --input '{"providerConfigs":[{provider:delivr},{provider:intentsify}]}'
    ↓
clay signals update <id> --input '{"providerConfigs":[...]}'   (narrows topicIds/tiers, succeeds)
    ↓
clay signals update <id> --input '{"providerConfigs":[...,{provider:bombora}]}'   (adds a provider, rejected)

AI Prompt

Using the Clay CLI, configure two intent providers on one topic-intent
signal, then update it.

Requirements:
- `providerConfigs` is an array; pass multiple entries to watch several
  providers at once with one signal, each with its own topicIds/tiers.
- The provider set is fixed the moment the signal is created. `signals
  update --input '{"providerConfigs":[...]}'` can change an existing
  provider's topicIds/tiers, but adding or removing a provider entry is
  rejected outright: "Topic intent providers cannot be changed after
  creation". This applies even when the update still includes all
  originally-configured providers plus one more.
- Every run charges per record checked, per topic, per provider; a
  two-provider signal costs roughly double a single-provider one for the
  same segment and topic count, independent of whether either provider
  finds anything.
- Use `clay signals search-topics` first to get real per-provider topic
  ids: delivr/intentsify ids are opaque, bombora ids are literal topic
  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)
  • An existing companies or people audience segment (matching the topic-intent type you use)

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. Resolve real ids for both providers

clay signals search-topics --query 'artificial intelligence' --entity-type person | jq '.data[0].matches'

Real output, this query happens to have both delivr and intentsify matches:

{"delivr": [{"id": "4eyes_119811", "name": "Artificial Intelligence"}], "intentsify": [{"id": "14583", "name": "Artificial Intelligence Software"}, {"id": "6453", "name": "Artificial Intelligence"}]}

2. Create the signal with both providers configured

clay signals create --type PersonTopicIntent --input '{
  "entityType": "CONTACT",
  "segmentIds": ["audseg_0tjs3u3yAgacWPpe926"],
  "providerConfigs": [
    {"provider": "delivr", "topicIds": ["4eyes_119811"], "tiers": ["high", "medium"]},
    {"provider": "intentsify", "topicIds": ["14583", "6453"], "tiers": ["high"]}
  ]
}' --name "TPC Batch3: AI topic intent (2 providers)"

Both configs persist independently, each with its own topicIds/tiers.

3. Narrow topics/tiers on both: this succeeds

clay signals update <signal-id> --input '{"providerConfigs":[
  {"provider":"delivr","topicIds":["4eyes_119811"],"tiers":["high"]},
  {"provider":"intentsify","topicIds":["6453"],"tiers":["high","medium"]}
]}' | jq '.signal.inputs.providerConfigs'

Real output, showing the changes persisted (intentsify's topicIds narrowed from 2 to 1, tiers widened on both):

[
  {"provider": "delivr", "topicIds": ["4eyes_119811"], "tiers": ["high"]},
  {"provider": "intentsify", "topicIds": ["6453"], "tiers": ["high", "medium"]}
]

4. Try to add a third provider: this is rejected

clay signals update <signal-id> --input '{"providerConfigs":[
  {"provider":"delivr","topicIds":["4eyes_119811"],"tiers":["high"]},
  {"provider":"intentsify","topicIds":["6453"],"tiers":["high"]},
  {"provider":"bombora","topicIds":["Sales Intelligence"]}
]}'

Real output:

{"error": {"code": "validation_error", "message": "Topic intent providers cannot be changed after creation"}}

Verify the result

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

clay signals update <signal-id> --input '{"providerConfigs":[{"provider":"delivr","topicIds":["4eyes_119811"],"tiers":["high"]},{"provider":"intentsify","topicIds":["6453"],"tiers":["high"]},{"provider":"bombora","topicIds":["x"]}]}'

Expected: narrowing topicIds/tiers on the signal's existing providers succeeds and persists; adding a provider not present at creation is rejected with a validation_error naming the rule, regardless of whether the existing providers are also included in the same update.

How it works

Each provider carries its own detection baseline and refresh cadence, so a signal picking up a new provider mid-life would mean its historical event stream suddenly includes intent detected by a system that wasn't watching before, a discontinuity in what "this signal's data" means. Locking the provider set at creation avoids that; the tradeoff is that broadening provider coverage always means creating a new signal, not editing the existing one.

Common issues

Assuming a provider can be added later, since topics/tiers can

Since providerConfigs as a whole is editable via signals update, it's natural to assume every part of it is. In practice, only topicIds/tiers on existing provider entries are editable. The set of providers is locked at creation regardless of what else the update includes.

Underestimating cost when adding a second provider

Cost might seem to scale with topics or records checked rather than provider count, but it multiplies per provider on top of per-topic, per-record: a two-provider signal roughly doubles the cost of a single-provider one for the same scope.

Next steps

  • If you need a new provider on an existing use case, create a fresh signal rather than trying to migrate the old one.
  • Check tiers narrowing (dropping to ["high"] only) as a cheaper lever than removing a whole provider.

verification:
  status: verified
  tested_at: "2026-09-21"
  product_version: "clay CLI 1.2.0"
  command: "clay signals update td_0tlqavs8wSiEmaihq9w --input '{\"providerConfigs\":[{\"provider\":\"delivr\",\"topicIds\":[\"4eyes_119811\"],\"tiers\":[\"high\"]},{\"provider\":\"intentsify\",\"topicIds\":[\"6453\"],\"tiers\":[\"high\",\"medium\"]},{\"provider\":\"bombora\",\"topicIds\":[\"Sales Intelligence\"]}]}'"
  expected_result: "Narrowing topicIds/tiers on delivr and intentsify (the signal's original providers) persists correctly; adding bombora as a third provider is rejected with 'Topic intent providers cannot be changed after creation', even though the update still includes both original providers."