POST /v1/queries with different
terms, and GET /v1/mentions with two filters.
1. Search for the sentence, not the name
A brand query looks for one token. A discovery query looks for the phrases people type when they are stuck:terms are OR’d into one upstream call, so several phrasings of the same
complaint cost one poll, not three. match: "contains" rather than "word":
these are phrases, and people do not type them the way you wrote them.
Write the phrases in the words your customers use, not the words you use.
“Brand monitoring” is your category; “I keep missing when people mention us”
is their problem.
2. Poll the places people describe problems in prose
Five sources carry that kind of sentence. Enable them together:3. Switch the readings on
A phrase query catches everyone who used the phrase, and most of them are not prospects: someone answering, someone quoting, someone complaining about a different tool. Two readings sort them, and they are what step 4 filters on.sentimentEnabled reads every mention as positive, neutral, negative,
question or mixed. aiEnabled also writes the intent — what the item is
trying to do: purchase_intent, comparison, question, complaint, praise
or other.
Both cost credits per classified item. Without them, step 4 has nothing to
filter on.
4. Read back only what needs you
GET /v1/mentions filters on both readings. Each is repeatable, and repeated
values are OR’d:
Repeated values of one key are OR’d; different keys are AND’d. So
?source=reddit&source=hackernews&sentiment=negative&intent=complaint reads:
on Reddit or Hacker News, negative, and a complaint. source, sentiment and
intent are all repeatable.
unread is the wire spelling of “not yet classified” — a real filter value, not
an absence. It is how you find what your readings have not caught up with.
Cutting the mentions nobody reacted to
engagement_min keeps mentions with at least that many interactions — likes,
replies, reposts, comments or score, whichever the Source reports. It is the
noise gate for a busy Source: on a typical month of X mentions, roughly seven in
ten have no interactions at all, so ?engagement_min=1 alone removes most of
what you would otherwise page through.
Three things it does not do, each of which will otherwise surprise you:
- It never counts views. A view is not an interaction, and on the Sources that report one it is an order of magnitude bigger than every other counter — including it would make this a filter on reach.
- It leaves out mentions with no counters at all, rather than treating them
as zero. RSS items and AI answers report no audience, and mentions recorded
before 4 September 2026 predate the field. None of them were measured, so none
can satisfy a threshold.
?engagement_min=0is therefore narrower than no filter: it asks for everything that was counted. - The numbers are captured when we collect a mention, and never refreshed. A post caught two minutes after it went up is measured with the counters it had then. So a threshold reads against your most recent mentions, which are the ones with the least time to have earned anything.
engagement below is for.
Asking a different question of each Source
engagement_min thresholds one number for everything, and the sum it thresholds
is lossy: a post with a hundred replies and no likes clears engagement_min=100
exactly as a post with a hundred likes does, and those are not the same
mentions. It was liked and it was argued with is the distinction a sum
erases.
engagement is a rule, and it is repeatable:
- Metrics are
likes,replies,reposts,comments,scoreandviews, plustotalfor the same interaction sumengagement_minreads.engagement_min=10is exactlyengagement=*:total>=10. - Operators are
>=,>,=,<and<=. The number is whole and may be negative — Reddit and Lemmy net downvotes out, so?engagement=reddit:score<0is a real question: the mentions that were argued with. *stands for any Source no named rule already covers. Pair it withtotal—?engagement=*:total>=25is “at least 25 interactions, wherever it was said”, which isengagement_minwith an operator of your choosing. A named counter under*is legal but rarely what you mean:*:likes>=100drops every Source that does not count likes, by the rule below.
- A Source no rule names passes.
?engagement=x:likes>=100narrows X and leaves Hacker News exactly as it was. Without that, every rule would also be a Source filter in disguise — and?source=already exists for that. A named rule overrides*for its own Source, and several rules on one Source are ANDed. - A metric that was never counted satisfies nothing —
<included. This is theengagement_minrule above, one level down and sharper: YouTube reports no likes at all, so?engagement=youtube:likes<10returns none of your YouTube mentions rather than all of them. Only a metric the Source actually reports can be filtered on.
engagement or engagement_min, never both: they are two spellings of one
filter, and a request carrying both is a 400.
Every mention comes back with both readings on it, so you can sort further
without a second call:
5. Qualify each one with your own question
The readings say what an item is. To ask whether it is your problem, give the query an agent step — one instruction and a schema, applied to every item it catches:agent, spelled with your own field
names:
current_workaround is the one with commercial value beyond triage: what
someone names as their current answer is what your reply has to be better than.
See AI for the schema’s field types and what an agent pass costs.
6. Get told instead of polling
Do not poll/v1/mentions on a timer. A query delivers what it catches to a
webhook, and every mention arrives with its readings already on it
— so the filter that reads well in step 4 becomes a condition in your own
handler.
What this does not do
It finds people describing a problem. It does not find customers, and it does not tell you they want to buy — aproblem_fit of true is a reading of
one post, not a qualified lead. Treat the output as a list of conversations
worth joining, and expect to discard some of it.