SnoopScan
Endpoints

Mentions

Watch Reddit, Hacker News, Bluesky, YouTube, Threads, GitHub and the web for your keywords.

Mentions watches public posts for the words you give it and sorts each one by what the person wants. You can use it from the Mentions pages in your account, from code, or from an AI assistant over MCP.

POST/v1/mentions/watches GET/v1/mentions

Your key needs the mentions scope. Watches run on a Mentions plan, which sets how many keywords you can watch and how often they are checked. See Authentication for keys and scopes.

The places and the kinds

Places (platforms): reddit, hackernews, bluesky, youtube, threads.

Kinds (category): buying_intent is a person who wants to buy, bug_report, complaint, question, praise, competitor for a post that names one of your competitor keywords, and other. Each mention carries evidence, the words that put it in its kind, so you can see why.

Try keywords first

POST /v1/mentions/test shows what keywords would have found in the last 7 days. Nothing is saved and nothing is sent.

import requestsr = requests.post(    'https://api.snoopscan.com/v1/mentions/test',    headers={'Authorization': 'Bearer sk_YOUR_KEY'},    json={        'keywords': [            'Acme',            'acme.com'        ],        'competitors': [            'Beta'        ],        'exclude': [            'jobs'        ],        'platforms': [            'reddit',            'hackernews'        ]    },)print(r.json())
const r = await fetch('https://api.snoopscan.com/v1/mentions/test', {  method: 'POST',  headers: { Authorization: 'Bearer sk_YOUR_KEY', 'Content-Type': 'application/json' },  body: JSON.stringify({      "keywords": [          "Acme",          "acme.com"      ],      "competitors": [          "Beta"      ],      "exclude": [          "jobs"      ],      "platforms": [          "reddit",          "hackernews"      ]  }),});console.log(await r.json());
curl -X POST https://api.snoopscan.com/v1/mentions/test \  -H 'Authorization: Bearer sk_YOUR_KEY' \  -H 'Content-Type: application/json' \  -d '{    "keywords": [        "Acme",        "acme.com"    ],    "competitors": [        "Beta"    ],    "exclude": [        "jobs"    ],    "platforms": [        "reddit",        "hackernews"    ]}'
The same request as saving a watch, without a name.
{    "success": true,    "data": {        "mentions": [            {                "platform": "reddit",                "url": "https://www.reddit.com/r/SaaS/comments/abc123/looking_for_a_status_page_tool/",                "author": "dana_reyes",                "title": "Looking for a status page tool",                "text": "We outgrew our spreadsheet. Looking for something like Acme that is cheaper for a small team.",                "postedAt": "2026-10-19T08:41:12Z",                "engagement": {                    "score": 14,                    "comments": 6                },                "matchedKeyword": "Acme",                "category": "buying_intent",                "evidence": "looking for"            }        ],        "count": 1,        "errors": {},        "queries": 2    }}
A success returns the mentions found, how many, and a plain message for any place that did not answer.

Save a watch

POST /v1/mentions/watches saves a watch. A watch takes up to 20 keywords, competitors included. Checks run every intervalMinutes (5 to 10,080, default 15). Pass a webhook URL and each new mention is posted there as mention.created, signed with your key's signing secret.

import requestsr = requests.post(    'https://api.snoopscan.com/v1/mentions/watches',    headers={'Authorization': 'Bearer sk_YOUR_KEY'},    json={        'name': 'Acme',        'keywords': [            'Acme',            'acme.com'        ],        'competitors': [            'Beta'        ],        'exclude': [            'jobs'        ],        'platforms': [            'reddit',            'hackernews',            'bluesky'        ],        'intervalMinutes': 15    },)print(r.json())
const r = await fetch('https://api.snoopscan.com/v1/mentions/watches', {  method: 'POST',  headers: { Authorization: 'Bearer sk_YOUR_KEY', 'Content-Type': 'application/json' },  body: JSON.stringify({      "name": "Acme",      "keywords": [          "Acme",          "acme.com"      ],      "competitors": [          "Beta"      ],      "exclude": [          "jobs"      ],      "platforms": [          "reddit",          "hackernews",          "bluesky"      ],      "intervalMinutes": 15  }),});console.log(await r.json());
curl -X POST https://api.snoopscan.com/v1/mentions/watches \  -H 'Authorization: Bearer sk_YOUR_KEY' \  -H 'Content-Type: application/json' \  -d '{    "name": "Acme",    "keywords": [        "Acme",        "acme.com"    ],    "competitors": [        "Beta"    ],    "exclude": [        "jobs"    ],    "platforms": [        "reddit",        "hackernews",        "bluesky"    ],    "intervalMinutes": 15}'
Returns the watch.
{    "success": true,    "data": {        "id": "wch_8f2c01a9d3",        "name": "Acme",        "keywords": [            "Acme",            "acme.com"        ],        "competitors": [            "Beta"        ],        "exclude": [            "jobs"        ],        "platforms": [            "reddit",            "hackernews",            "bluesky",            "youtube",            "threads"        ],        "categories": [            "bug_report",            "complaint",            "question",            "buying_intent",            "praise",            "competitor",            "other"        ],        "customWords": {},        "intervalMinutes": 15,        "webhook": null,        "active": true,        "createdAt": "2026-10-19T09:00:00Z",        "lastRunAt": null,        "nextRunAt": "2026-10-19T09:15:00Z",        "lastErrors": {}    }}
The first look reaches back 7 days and is not announced. After that, new mentions are announced as they are found.
RequestWhat it does
GET /v1/mentions/watchesYour watches.
GET /v1/mentions/watches/{id}One watch, with its mentions counted by status.
PATCH /v1/mentions/watches/{id}Change any field, or pause it with "active": false.
DELETE /v1/mentions/watches/{id}Delete a watch and its mentions.
POST /v1/mentions/watches/{id}/testRun a saved watch now over the last 7 days. Nothing is stored or sent.

Read what it found

GET /v1/mentions lists mentions, newest first. Filter with watch_id, category, platform, status and since. A full page carries a next link for the following one.

curl 'https://api.snoopscan.com/v1/mentions?category=buying_intent&status=new' \  -H 'Authorization: Bearer sk_YOUR_KEY'
{    "success": true,    "data": {        "mentions": [            {                "id": "men_3b91c7e2f4",                "watchId": "wch_8f2c01a9d3",                "platform": "reddit",                "url": "https://www.reddit.com/r/SaaS/comments/abc123/looking_for_a_status_page_tool/",                "author": "dana_reyes",                "title": "Looking for a status page tool",                "text": "We outgrew our spreadsheet. Looking for something like Acme that is cheaper for a small team.",                "postedAt": "2026-10-19T08:41:12Z",                "engagement": {                    "score": 14,                    "comments": 6                },                "matchedKeyword": "Acme",                "category": "buying_intent",                "evidence": "looking for",                "status": "new",                "foundAt": "2026-10-19T08:45:03Z"            }        ],        "next": null    }}
Each mention has its own id and status.

Mark a mention

PATCH /v1/mentions/{id} with a status of new, seen, done or irrelevant. Mentions you mark stay on record and drop out of the open list.

import requestsr = requests.patch(    'https://api.snoopscan.com/v1/mentions/men_3b91c7e2f4',    headers={'Authorization': 'Bearer sk_YOUR_KEY'},    json={        'status': 'done'    },)print(r.json())
const r = await fetch('https://api.snoopscan.com/v1/mentions/men_3b91c7e2f4', {  method: 'PATCH',  headers: { Authorization: 'Bearer sk_YOUR_KEY', 'Content-Type': 'application/json' },  body: JSON.stringify({      "status": "done"  }),});console.log(await r.json());
curl -X PATCH https://api.snoopscan.com/v1/mentions/men_3b91c7e2f4 \  -H 'Authorization: Bearer sk_YOUR_KEY' \  -H 'Content-Type: application/json' \  -d '{    "status": "done"}'
Returns the id and the new status.
{    "success": true,    "data": {        "id": "men_3b91c7e2f4",        "status": "done"    }}

Fields of a watch

FieldTypeWhat it does
name requiredstringA name for the watch, up to 120 characters.
keywordsarray of stringWords or phrases to look for. Whole words, any case.
competitorsarray of stringA post that matches one of these and none of keywords is sorted as competitor. Counted with keywords toward the limit of 20.
excludearray of stringWords that remove a post from the results when it contains any of them.
platformsarray of stringWhere to look. Default is all five.
categoriesarray of stringKinds to keep. Posts sorted elsewhere are dropped. Default is all.
customWordsobjectYour own words for a kind, added to the built-in ones. For example {"buying_intent": ["any tips"]}.
intervalMinutesintegerMinutes between checks, 5 to 10,080.
webhookstringA URL to post mention.created to for each new mention.
Checks use no credits. They are included in a Mentions plan. Trying keywords before you save needs an account with some credits left. See Credits.