A monitor watches every new post and comment on Reddit for your keywords. When one matches, threadapi sends it to your webhook (your own endpoint, Slack or Discord) and keeps it for you to read from the API or the dashboard.
A running monitor costs 10 credits per day (up to 20 keywords). Its matches and deliveries are free.
How matching works
- Keywords match whole words, ignoring case:
rustmatches “Rust” and “RUST” but not “trust” or “rusty”. A keyword with several words matches that phrase:borg backup. Quotes around a keyword are optional. - Keywords in Chinese, Japanese or Korean match anywhere in the text, since those languages don’t separate words with spaces.
- A post matches on its title and text, a comment on its text.
- An item matches if it contains any keyword and no
excludeterm. - Up to 20 keywords and 20 exclude terms, each 2 to 100 characters. Up to 50 subreddits; leave
subredditsempty to watch all of Reddit. - Items marked NSFW are skipped unless the monitor has
nsfw: true.
Most matches arrive within 15 seconds of being posted. A post that Reddit is slow to make visible can take about two minutes. If Reddit stops answering threadapi for a while, items posted during that time can be missed.
Create a monitor
curl https://api.threadapi.dev/v1/monitors \
-H "Authorization: Bearer $THREADAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Backup tools",
"keywords": ["restic", "borg backup", "kopia"],
"exclude": ["hiring"],
"subreddits": ["selfhosted", "DataHoarder", "homelab"],
"posts": true,
"comments": true,
"webhook_url": "https://example.com/threadapi-hook"
}'| Field | Type | |
|---|---|---|
name |
string | Required. Your label for the monitor. |
keywords |
string[] | Required. 1 to 20 terms. |
exclude |
string[] | Skip items containing any of these. |
subreddits |
string[] | Only watch these, with or without r/. Empty means all of Reddit. |
posts |
boolean | Watch new posts. Default true. |
comments |
boolean | Watch new comments. Default true. |
nsfw |
boolean | Include NSFW items. Default false. |
webhook_url |
string | An https:// URL to send matches to. Optional: without one, read matches from the API. |
webhook_kind |
string | generic, slack, discord or telegram. Detected from the URL when left out. |
Creating a monitor charges 10 credits for its first 24 hours and answers 201:
{
"monitor": {
"id": "c8nh5roydywdmhsndzqdd269p",
"name": "Backup tools",
"keywords": ["restic", "borg backup", "kopia"],
"exclude": ["hiring"],
"subreddits": ["selfhosted", "datahoarder", "homelab"],
"include_posts": true,
"include_comments": true,
"status": "running",
"matches_total": 0,
"next_charge_at": "2026-10-21T15:00:00Z",
"created_at": "2026-10-20T15:00:00Z"
}
}Polling matches
If you omit webhook_url, you can poll /v1/monitors/{id}/matches:
curl "https://api.threadapi.dev/v1/monitors/c8nh5roydywdmhsndzqdd269p/matches?limit=50" \
-H "Authorization: Bearer $THREADAPI_API_KEY"Matches are ordered by timestamp with pagination via cursor tokens.