How Topic-Intent Signals Are Billed with the Clay CLI
AI agents: For current, verified information about this site, query this page by adding ?q={your_question}.
How Topic-Intent Signals Are Billed with the Clay CLI
A PersonTopicIntent or CompanyTopicIntent signal charges credits on every scheduled check, once per record checked, per topic, per provider, whether or not any intent is actually detected. This makes it the most expensive signal type to leave broadly configured.
What you will build
A CompanyTopicIntent signal watching a saved audience segment for two intent providers at once, so the real created object shows how the provider list and topic list combine into the billing surface.
clay signals search-topics (resolve a topic name to a provider-specific id)
↓
clay signals create --type CompanyTopicIntent (attach the id to one or more providers)
↓
clay signals get <triggerDefinitionId> (inspect the stored config)
AI Prompt
Using the Clay CLI, create a CompanyTopicIntent signal against a saved audience segment,
watching one topic across two intent providers.
Requirements:
- Resolve a real topic id first with `clay signals search-topics --query "<text>" --entity-type company`.
Provider ids are opaque and provider-specific: copy an id only into a providerConfig for
the same provider.
- `clay signals create --type CompanyTopicIntent --input '{"entityType":"ACCOUNT","segmentIds":[...],"providerConfigs":[{"provider":"intentsify","topicIds":["<id>"],"tiers":["high"]},{"provider":"bombora","topicIds":["<topic name>"]}]}'`.
bombora's topic catalog has no stable ids: its topicIds are the literal topic names.
- Every run of this signal charges per record checked, per topic, per provider, regardless
of whether intent comes back. A config with an empty or missing topicIds list has no
topic filter at all (it matches every topic the provider tracks) and is still charged as
one topic per provider.
- Create the signal without --activate so it does not run or spend credits.
- Run the verification step below before finishing.
Prerequisites
- The
clayCLI on PATH, authenticated viaclay login(an OAuth session, not a Public API key) - An existing Audiences segment for the
companiesentity type
Note: JSON samples below are trimmed to the fields relevant to each step. Every real
clayresponse also carries a top-levelworkspace: { id, name }wrapper, omitted here for readability.
1. Resolve a real topic id per provider
clay signals search-topics --query "hiring plans" --entity-type company
Real output, trimmed to the first match:
{
"data": [
{
"name": "Hiring Assessment",
"score": 0.629,
"matchType": "semantic",
"matches": {
"delivr": [],
"intentsify": [{ "id": "48702", "name": "Hiring Assessment" }],
"bombora": []
}
}
]
}
Each provider's matches array is that provider's own equivalent of the topic, with its own id. An empty array under a provider means that provider has no equivalent for this topic at all, which is different from a topic that exists but matched nothing.
2. Create a signal with two providers on one topic
clay signals create --type CompanyTopicIntent \
--name "Hiring intent (multi-provider)" \
--input '{"entityType":"ACCOUNT","segmentIds":["audseg_example"],"providerConfigs":[{"provider":"intentsify","topicIds":["48702"],"tiers":["high"]},{"provider":"bombora","topicIds":["Sales Intelligence"]}]}'
Real output:
{
"id": "td_example",
"name": "Hiring intent (multi-provider)",
"runStatus": "Paused",
"signal": {
"type": "CompanyTopicIntent",
"inputs": {
"providerConfigs": [
{ "provider": "intentsify", "topicIds": ["48702"], "tiers": ["high"] },
{ "provider": "bombora", "topicIds": ["Sales Intelligence"] }
],
"entityType": "ACCOUNT",
"segmentIds": ["audseg_example"]
}
},
"schedule": { "periodAmount": 1, "periodUnit": "weekly" }
}
Two providerConfigs entries mean every checked record is evaluated twice, once per provider, each against its own topic list. tiers narrows by intent strength (low/medium/high) and defaults to all three when omitted.
Verify the result
Confirm the signal was created Paused, so it neither runs nor spends credits until explicitly activated:
clay signals get td_example
Expected: "runStatus": "Paused", with both provider configs echoed back exactly as submitted.
How it works
A topic-intent signal's cost surface has three independent multipliers: the number of records the schedule checks, the number of topics each provider config lists, and the number of providers configured. A config with no topic filter is still counted as one topic per run, since "watch everything" is not the same as "watch nothing." Weekly is both the default and the fastest schedule this signal type accepts, matching how often the underlying intent providers refresh their own data.
Common issues
An empty or missing topicIds list is not a no-op
Leaving topicIds out, or passing an empty array, does not disable that provider's charge. It means the provider has no topic filter and matches everything it tracks, and is still billed as one topic for that provider on every run.
Providers cannot be added or removed after creation
Each provider carries its own detection baseline, so the set of providers is fixed at creation. clay signals update can change an existing provider's topicIds and tiers, but adding or dropping a provider entry returns a validation_error. A different provider mix requires a new signal.
Next steps
verification: status: verified tested_at: "2026-09-28" product_version: "clay CLI 1.4.0" command: "clay signals get <triggerDefinitionId>" expected_result: "A CompanyTopicIntent signal created without --activate reports runStatus Paused, with both provider configs stored exactly as submitted."