Checking News Signal Topics Against the CLI's Vocabulary with the Clay CLI
AI agents: For current, verified information about this site, query this page by adding ?q={your_question}.
Checking News Signal Topics Against the CLI's Vocabulary with the Clay CLI
A News signal's filters.topics accepts any strings, but only a fixed vocabulary of topic names is meaningful. The vocabulary is printed in the CLI's own --help text, so a script can extract it and check candidate topics before creating a signal, catching spelling and capitalization mistakes that create does not.
What you will build
A bash function that extracts the topic vocabulary from clay signals create --help at run time, flags any candidate topic that is not an exact member, suggests the closest entry, and then creates the signal with a verified list.
clay signals create --help ──► vocab.txt (64 entries)
candidate topics ──► lint ──► ok | UNKNOWN (did you mean: ...)
verified topics ──► clay signals create --type News --input '{...,"filters":{"topics":[...]}}'
AI Prompt
Using the Clay CLI, check News signal topics against the CLI's own vocabulary before creating. Requirements: - The help text of `clay signals create` ends the News `topics` paragraph with a sentence beginning "The vocabulary, in full:" followed by a comma-separated list of topic names. - Extract that list at run time rather than hard-coding it, so the check follows the installed CLI version. - Matching is exact and case-sensitive: "Fundraising" is in the vocabulary, "fundraising" and "Funding" are not. "Merger & Acquisition" is in it, "Merger and Acquisition" is not. - `signals create` accepts topics outside the vocabulary without an error, so the lint is the only check. `topics` accepts an empty array and null. A number element is rejected. - Run the verification step below before finishing.
Prerequisites
- The
clayCLI on PATH, authenticated viaclay login(an OAuth session, not a Public API key) jq,sed,grep, and bash- An existing companies segment (this doc uses
audseg_0tm3nvu2EbBP6mjpk8f)
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. Every signal created here is Paused.
1. Extract the vocabulary
clay signals create --help | sed -n 's/.*The vocabulary, in full: //p' | sed 's/\.$//' | tr ',' '\n' | sed 's/^ *//' > vocab.txt wc -l < vocab.txt head -3 vocab.txt; tail -2 vocab.txt
Real output:
64 Natural Disaster Industrial Accident & Disaster Advertisement/Branding/Campaign Security Breach & Vulnerability Outage
Entries with an ampersand, slash, or parenthesis are the easiest to misspell, for example Industrial Accident & Disaster, Branch/Store Closing, and Downsizing (Layoff).
2. The lint function
lint() { for t in "$@"; do
if grep -qxF -- "$t" vocab.txt; then echo "ok $t"
else near=$(grep -i -m1 -F -- "$t" vocab.txt || grep -i -m1 -- "$(echo "$t" | cut -c1-5)" vocab.txt)
echo "UNKNOWN $t${near:+ (did you mean: $near)}"; fi; done; }
lint "Fundraising" "fundraising" "Funding" "Merger & Acquisition" "Merger and Acquisition" "Executive Appointment" "Hiring" "Layoffs" "Downsizing (Layoff)"
Real output:
ok Fundraising UNKNOWN fundraising (did you mean: Fundraising) UNKNOWN Funding ok Merger & Acquisition UNKNOWN Merger and Acquisition (did you mean: Merger & Acquisition) ok Executive Appointment ok Hiring UNKNOWN Layoffs (did you mean: Downsizing (Layoff)) ok Downsizing (Layoff)
Funding has no suggestion because neither the full string nor its first five characters appear in a vocabulary entry.
3. The CLI accepts the unknown values
clay signals create --type News --name "TPC19 news lint" --input '{"entityType":"ACCOUNT","segmentIds":["audseg_0tm3nvu2EbBP6mjpk8f"],"filters":{"topics":["fundraising","Funding","Merger and Acquisition","Layoffs"]}}'
Real output, {id, topics: .signal.inputs.filters.topics}:
{"id":"td_0tmb2qsDz2zpwZeqzdz","topics":["fundraising","Funding","Merger and Acquisition","Layoffs"]}
All four values that failed the lint were stored without an error, which is why the lint has to run first.
4. Every vocabulary entry is accepted, and the edge forms
Submitting all 64 entries in one topics array exits 0 and stores all 64:
{"id":"td_0tmb2quewpXbRkTKwzx","n":64}
{"id":"td_0tmb2qv5ZgCU4JW7iBA","f":{"topics":[]}}
{"id":"td_0tmb2qwcyP9sADJaGRB","f":{"topics":null}}
An empty array and null are both accepted and stored as submitted. A number element ("topics":[1]) returns --input: Invalid input (exit 2).
Verify the result
Confirm the lint separates exact from near-miss spellings against the installed CLI:
lint "Fundraising" "fundraising"
Expected: the first line starts with ok and the second starts with UNKNOWN and suggests Fundraising.
How it works
The topics paragraph in the CLI's help ends with the complete vocabulary, which is why the extraction works. The CLI's schema types topics as an array of strings, so it validates the type of each element and not its membership in the vocabulary. A signal with a topic outside the vocabulary is created normally, and per the help text it then matches nothing, which looks the same as a quiet period. This was not observed running, because no signal here was activated.
Common issues
The extraction depends on the help text wording
The sed pattern matches The vocabulary, in full: . If a future CLI version rewords the sentence, vocab.txt comes out empty. Check wc -l < vocab.txt before linting; the count was 64 on this version.
An empty array and null are not the same as omitting topics
"topics":[] and "topics":null are stored as given. The help text states that omitting filters entirely means every article counts; what an empty topics array means at run time was not tested.
Case and symbols matter
fundraising, Merger and Acquisition, and Layoffs are all outside the vocabulary. Copy entries from vocab.txt rather than typing them.
Next steps
- See the existing doc on per-event News billing for the
topicsvocabulary note and cost controls. - See the JobPost doc in this batch for the same acceptance pattern on seniority and employment type.
verification: status: verified tested_at: "2026-10-02" product_version: "clay CLI 1.8.0+71cb1bf09c7e" command: "lint \"Fundraising\" \"fundraising\"" expected_result: "The first line starts with ok and the second starts with UNKNOWN and suggests Fundraising."