All posts
Workflow

Reddit JSON API: the no-auth workflow for buyer-thread alerts

By Bazzly Team4 min read

Append .json to any Reddit URL to pull posts and comments without OAuth, then pipe buying-intent threads straight into a Slack channel.

Reddit JSON API: the no-auth workflow for buyer-thread alerts

Reddit has a quietly excellent feature that almost nobody outside r/redditdev talks about: you can append .json to the end of any public Reddit URL and get a clean JSON response back. No OAuth dance. No client ID. No registered app. Just an HTTP GET and a User-Agent header.

That single fact is enough to build a working buyer-thread monitor in an afternoon. This post is the workflow we run when we need a quick-and-dirty scanner for a new niche before deciding whether it's worth a heavier setup.

What .json actually gives you

Take any Reddit URL and stick .json on the end:

  • https://www.reddit.com/r/SaaS/new.json → newest posts in r/SaaS
  • https://www.reddit.com/r/SaaS/search.json?q=stripe+alternative&restrict_sr=1&sort=new → search results, newest first
  • https://www.reddit.com/r/SaaS/comments/abc123.json → a specific thread with its comment tree
  • https://www.reddit.com/user/some_user/comments.json → a user's recent comments

The response is a Reddit Listing object: an envelope (kind: "Listing") wrapping an array of children. Each child has a data block with the fields you actually care about: title, selftext, author, created_utc, permalink, num_comments, score, subreddit.

No signing. No tokens to refresh. The only requirement Reddit enforces is a non-default User-Agent string. Use the same browser-style fake one everyone uses and you'll get a 429 within a few minutes; set something descriptive like buyer-thread-monitor/0.1 by yourusername and the rate limiter is generous.

The rate limit you should plan around

Unauthenticated requests get 10 requests per minute per IP, per Reddit's published guidance. That's enough for a 5-subreddit monitor polling every 60 seconds with room to spare. It is not enough for a 200-subreddit fan-out. If you cross that line you'll want OAuth (60 req/min) or the official Python wrapper. For a buyer-thread scanner targeting 3 to 8 niche subs, no-auth is fine.

Reddit also occasionally tightens specific endpoints. The team announced upcoming changes to the comment-id endpoint on r/redditdev, so if you build anything that hammers /comments/<id>.json directly, subscribe to that sub.

The workflow, end to end

Rendering diagram…

Five moving parts. Let's walk through each.

1. The fetcher

import requests

HEADERS = {"User-Agent": "buyer-thread-monitor/0.1 by u/yourname"}

def fetch_new(subreddit, limit=25):
    url = f"https://www.reddit.com/r/{subreddit}/new.json?limit={limit}"
    r = requests.get(url, headers=HEADERS, timeout=10)
    r.raise_for_status()
    return [c["data"] for c in r.json()["data"]["children"]]

That's it. Loop over fetch_new("SaaS") and you have the 25 newest posts as plain dicts.

2. Buyer-intent scoring

This is where most home-built monitors fall over. A naive keyword match on "stripe" floods your Slack with every billing rant in the subreddit. You want phrases that signal someone is actively shopping.

The pattern we use is two-tier:

  • Strong signals (any one of these is enough): "looking for", "recommend", "alternative to", "any tool that", "how do you handle", "what do you use for", "willing to pay", "would pay".
  • Topic match (must also hit one): your product's category terms, e.g. "crm", "onboarding", "billing", "analytics".

A post needs one strong signal AND one topic term to clear the bar. That cuts noise by about 90% in our experience and surfaces threads where someone is asking the question your product answers. The same logic underpins spotting 'first dollar' threads on r/SaaS if you want a deeper look at intent phrasing.

STRONG = ["looking for", "recommend", "alternative to", "any tool that",
          "what do you use for", "willing to pay"]
TOPIC = ["crm", "onboarding", "billing"]

def is_buyer_thread(post):
    blob = (post["title"] + " " + post.get("selftext", "")).lower()
    return any(s in blob for s in STRONG) and any(t in blob for t in TOPIC)

3. Dedupe

Reddit's /new.json returns the same posts on every poll until they age out. Keep a simple set of post["id"] values you've already alerted on. SQLite, Redis, or a flat file all work. Expire entries after 48 hours so the store stays small.

4. Slack delivery

Create an incoming webhook on a private channel, then POST a formatted message:

def notify(post):
    url = f"https://reddit.com{post['permalink']}"
    payload = {
        "text": f"*New buyer thread in r/{post['subreddit']}*\n"
                f"<{url}|{post['title']}>\n"
                f"by u/{post['author']} - {post['num_comments']} comments"
    }
    requests.post(SLACK_WEBHOOK_URL, json=payload, timeout=5)

The single most important field to include is the full Reddit URL. You want a one-click jump from Slack to the thread, because the value of a buyer thread decays fast. A reply in the first hour gets read; a reply on day three gets ignored.

5. The scheduler

Run the whole loop on a 60-second cron, GitHub Actions schedule, or a tiny VPS systemd timer. For 5 subreddits you're at 5 requests/minute, well under the limit.

What to monitor besides /new

/new.json is the workhorse, but two other endpoints earn their keep:

  • /r/<sub>/search.json?q=<phrase>&restrict_sr=1&sort=new lets you watch a single high-signal phrase across a sub without grepping every post. Good for tracking competitor mentions.
  • /user/<username>/comments.json is how you watch a specific power user who routinely asks the kind of question your product solves. Niche, but devastating when it hits.

A related r/redditdev thread covers the mechanics of the .json suffix and what fields you get if you want to poke around the response shape before you write code.

When to graduate from this setup

This no-auth pattern is right for the first 30 days of a new monitoring project. It breaks down when:

  • You need to scan more than ~10 subs at once (rate limit).
  • You need historical data older than the last ~1000 posts (Reddit caps Listing pagination).
  • You want vote and comment counts updated on threads you've already seen (you'd be re-fetching constantly).
  • You want to track keyword hits in comments, not just posts, across a wide surface.

At that point you either move to authenticated API access via PRAW, or you hand it off. If running and tuning a scanner like this isn't where you want to spend your week, Bazzly does the watching across many subs and surfaces the buyer threads directly. Either path beats refreshing /new in a browser tab.

A note on what counts as legitimate use

A scanner that polls public Reddit JSON endpoints at low volume, with a descriptive User-Agent, is not a grey-hat operation. It's the same data Reddit serves to logged-out browser visitors. What gets accounts banned is the reply layer downstream: identical comments at industrial scale, fake accounts upvoting each other, or DM blasts to everyone who matched a keyword. The scanner is fine. The discipline you apply to the replies is what matters, and that includes basics like the karma minimums most subs enforce before your comments are even visible.

Get the alerts right first. Then write replies a human would write. Then post them from an account that has standing in the sub. In that order, this workflow turns Reddit into one of the highest-signal lead channels you'll have.

Related reading