Keyword health
See which keywords cost more than they're worth, where their noise comes from, and fix them with one PATCH.
You pay for every matched mention, relevant or not. The health report tells you whether a keyword is worth what it costs, where its noise comes from, and which change would reduce it, with an estimate of what that change would have saved.
const { data: health } = await rumoro.getKeywordHealth({ path: { id: 'kw_...' }, query: { range: '30d' } });range is 7d, 30d (the default) or 90d. It counts UTC days up to today, by the time of the match. Reading the report changes nothing and costs nothing.
Status
The first status that applies is used.
| Status | When |
|---|---|
paused | Muted by you, stopped by an empty balance, or stopped by the noise brake |
capped | At its monthly mention cap, including the 200 of the welcome credit. It matches again on the 1st (UTC) or when the cap goes up. |
noisy | 20 or more scored matches, of which less than 30% are relevant (relevance 40 or higher, or marked relevant) |
new | Younger than 7 days and not noisy, or changed in the last 7 days with fewer than 20 scored matches since |
quiet | At least 7 days old, with no relevant match in the period |
healthy | None of the above |
reasons explains the status in plain words. It also points out a platform where 90% or more of at least 10 scored matches were noise, and a keyword that takes half or more of the workspace's matches.
In GET /v1/keywords, each keyword has stats.health. It uses the same rules over 14 days, so it can differ from a 30-day report.
Judged since your last change
When you change a keyword's matching rules, platforms or context, or unmute it, the status, reasons, noise analysis and suggestions only look at matches since that change, if it falls in the period. stats.judgedSince shows when that was, and null means the whole period counts.
Suggestions need 20 scored matches in that time. After a change they wait for 20 new ones, and reasons says so. A report never suggests again what you just applied.
Numbers
stats always covers the whole period. It has matches, relevant, filtered (noise), unscored, noiseShare, workspaceShare, byPlatform, weekly (per 7 days) and cost, which matches the keyword's row in GET /v1/usage/breakdown.
Where the noise comes from
The report takes the newest scored posts of the period, up to 200 noise and 200 relevant ones, under the keyword's current rules and platforms. Reviews are left out, because they match by app and not by text.
noiseTermslists up to 10 words or two-word phrases that appear in at least 3 noise posts and are at least twice as common there (noisePosts,relevantPosts,lift). Words from the keyword itself never appear.noiseAuthorslists people with at least 3 noise posts and no relevant one, with theentrythatmatching.excludedAuthorswould save. When a link doesn't point to one person, such as a GitHub app, the entry is their name.
Suggestions
Each suggestion has a patch you can send to PATCH /v1/keywords/{id} unchanged. Lists in it are complete, so your existing entries are included.
Types
type | What it does |
|---|---|
platforms | Removes platforms where 90% or more of at least 10 scored matches were noise, but never all of them. A keyword that tracked every platform gets an explicit list, so platforms added later are not included. |
excluded_terms | Adds the fewest noise terms that cover the noise, which together appear in at most 2% of relevant posts. It needs at least 20 relevant posts, or none at all. |
excluded_authors | Adds the authors who only brought noise |
required_terms | For a keyword without required terms, one word that appears in 90% or more of its relevant posts and removes at least half of the noise. Sets requiredMode to any. |
context | A new context for the classifier. It changes how new matches are scored, not what is matched or billed. Without ai=true it is only offered for noisy keywords, as the current context plus "Ignore posts about …" with the three biggest noise terms. |
Effect
Every suggestion except context has an effect. Rumoro runs the new rules over the sample and scales the result up to the whole period when the sample is smaller (exact tells you which). centsSaved is the removed matches at $0.008 each.
{
"type": "excluded_terms",
"values": ["moving", "database"],
"why": "Exclude \"moving\", \"database\": common in its noise, absent from its relevant matches. In the last 30 days it would have removed 38 noise matches and 0 relevant ones.",
"patch": { "matching": { "excludedTerms": ["moving", "database"] } },
"effect": { "noiseRemoved": 38, "relevantRemoved": 0, "centsSaved": 30, "sample": { "noiseRemoved": 38, "noise": 41, "relevantRemoved": 0, "relevant": 26 }, "exact": true },
"source": "rules"
}Apply one
Send the patch as it is.
await rumoro.updateKeyword({ path: { id: 'kw_...' }, body: { matching: { excludedTerms: ['moving', 'database'] } } });New rules apply from the next check, and mentions you already have stay. A keyword stopped by the noise brake starts again when its required or excluded terms, platforms or context change, as long as the balance covers another day. Excluding authors alone doesn't restart it, so send "muted": false as well.
A context written by a model
With ai=true, a language model writes the context from the term, the current context and sample posts. ai.status tells you what happened.
ai.status | Meaning |
|---|---|
off | Not requested |
generated | Written just now |
cached | The same keyword and period, unchanged, within the last 24 hours |
unavailable | No noise to learn from, or no usable answer. A noisy keyword gets the rule-based context instead. |
rate_limited | More than 20 model calls in the last hour for this workspace |
Limits
Reports are kept for 5 minutes and model contexts for 24 hours. Changing the keyword starts fresh. A workspace can read 30 reports a minute through the API, MCP and dashboard together, cached ones included. After that it gets 429 rate_limited with Retry-After.
Elsewhere
The Keywords list marks noisy and quiet keywords, and each keyword's Health, last 30 days section has an Apply button for every suggestion. In the CLI, run rumoro keywords:health kw_... --range 30d. In MCP, use get_keyword_health and send patches with update_keyword.