RedditAnswer

Reddit search API: how to search comments as JSON

Reddit's API search covers posts, subreddits and users, not comments. We pulled 499 supabase comments from 5 subreddits in 5 calls, back to 2022.

5 min read

Short answer

  • Reddit's search endpoint, GET /search, documents three result types: subreddits, posts and users. None is comments, and PRAW's search returns posts only.
  • ToolzerHub's /v1/reddit/search takes type=comments and returns each comment's full text and its post title. One call returned 100 comments, and 99 contained the word searched.
  • One call stops after 12 Reddit result pages, 65 to 102 results. One call per subreddit went further: 5 calls, 499 comments, back to 2022, at 1 credit each.
On this page

Reddit's API documents no comment search. Its search endpoint, GET /search, takes a type of sr, link or user: subreddits, posts and people. Our Reddit search API returns comments too, with the full comment text and the post title.

What Reddit's own search covers

Reddit's API lists GET [/r/subreddit]/search for subreddits, posts and users. It returns up to 100 results a request and sorts by relevance, hot, top, new or comments, with a time window. PRAW, Reddit's main Python wrapper, calls the same endpoint, and subreddit.search() returns posts. Once you have a post you can pull its comments, but you can't ask for every comment that contains a word.

If Reddit has approved your app and you search posts, use its endpoint. Our Reddit API pricing post covers its free limit and commercial use.

Search Reddit comments with ToolzerHub

We make ToolzerHub. Our Reddit API has /v1/reddit/search with type set to posts, comments, communities, people or media. Each call is a GET with the x-api-key header and costs 1 credit, whatever count you ask for.

bash
export TOOLZERHUB_API_KEY=your_key
curl -H "x-api-key: $TOOLZERHUB_API_KEY" \
  "https://api.toolzerhub.com/v1/reddit/search?q=supabase&type=comments&count=100"

One of the 100 comments that came back, without fullname, subreddit_id and nsfw:

json
{
  "kind": "comment",
  "id": "pf1m7ij",
  "post_fullname": "t3_1x2c958",
  "post_title": "Deno is joining Cloudflare - and being discontinued in 2027",
  "subreddit": "Supabase",
  "author": "revadike",
  "permalink": "/r/Supabase/comments/1x2c958/deno_is_joining_cloudflare_and_being_discontinued/pf1m7ij/",
  "created_at": "2026-10-10T13:34:01.674000+0000",
  "body": "Good, I think edge functions were probably one of the biggest pain points with supabase. This looks promising!"
}

body is the whole comment, not a snippet: the longest of the 100 ran to 7,681 characters. They came from 65 subreddits. Comment rows carry no score. Post results (type=posts) carry title, score and comment_count but no text.

How far one call goes

count accepts up to 200, but one call stops after 12 of Reddit's search pages. Asking for 100 gave 65 posts for "supabase", and asking for 200 gave 102 comments for "notion". There is no cursor for the next batch and no sort or time filter. Results come in Reddit's order, not newest first, so filter on created_at yourself.

Reddit's query syntax goes through untouched. supabase subreddit:webdev with type=comments returned 25 of 25 comments from r/webdev, and one call per subreddit gets past the 12-page stop. Search matches the word, not the brand, so for a brand that is also a word, add subreddit: or a longer phrase.

Save the comments that mention a word to CSV

The script runs one search, or one per subreddit you list, skips results it has already written in this run, and saves each comment (or post) to a CSV with a link to it on Reddit.

python
import csv
import os
import sys
import time

import requests

URL = "https://api.toolzerhub.com/v1/reddit/search"
HEADERS = {"x-api-key": os.environ.get("TOOLZERHUB_API_KEY", "")}
FIELDS = ["created_at", "subreddit", "author", "kind", "title", "text", "score", "link"]


def search(q, kind, count, tries=3):
    # 429, 5xx and dropped connections are retried; failed calls cost no credits.
    params = {"q": q, "type": kind, "count": count}
    for attempt in range(tries):
        last = attempt == tries - 1
        try:
            r = requests.get(URL, headers=HEADERS, params=params, timeout=180)
        except requests.RequestException:
            if last:
                raise
            time.sleep(10 * (attempt + 1))
            continue
        if r.status_code in (429, 500, 502, 503, 504) and not last:
            time.sleep(10 * (attempt + 1))
            continue
        r.raise_for_status()
        return r.json()["data"]["results"]


def row(item):
    comment = item["kind"] == "comment"
    return {
        "created_at": (item.get("created_at") or "")[:19].replace("T", " "),
        "subreddit": item.get("subreddit"), "author": item.get("author"), "kind": item["kind"],
        "title": item.get("post_title") if comment else item.get("title"),
        "text": (item.get("body") or "").replace("\n", " "),  # posts come without text
        "score": item.get("score"),
        "link": "https://www.reddit.com" + item["permalink"] if item.get("permalink")
        else "https://www.reddit.com/comments/" + item["post_fullname"][3:],  # the post, not the comment
    }


def main(query, kind="comments", count="100", subreddits="", out="reddit_search.csv"):
    # One call per subreddit goes deeper than one call across all of Reddit.
    subs = [s.strip().removeprefix("r/") for s in subreddits.split(",") if s.strip()]
    queries = [f"{query} subreddit:{s}" for s in subs]
    seen = set()
    with open(out, "w", newline="", encoding="utf-8-sig") as f:  # -sig: Excel reads UTF-8
        writer = csv.DictWriter(f, fieldnames=FIELDS)
        writer.writeheader()
        for q in queries or [query]:
            results = search(q, kind, int(count))
            for item in results:
                if item["id"] not in seen:
                    seen.add(item["id"])
                    writer.writerow(row(item))
            print(f"{q}: {len(results)} results")
    print(f"wrote {len(seen)} rows to {out}")


if __name__ == "__main__":
    if len(sys.argv) < 2:
        sys.exit('usage: python reddit_search.py "supabase" [comments|posts] [count] [sub1,sub2] [file.csv]')
    if not HEADERS["x-api-key"]:
        sys.exit("set TOOLZERHUB_API_KEY first")
    main(*sys.argv[1:])

python reddit_search.py "supabase" comments 100 "Supabase,webdev,SaaS,SideProject,nextjs" made 5 calls and wrote 499 comments in 120 seconds, against 100 from the single call across all of Reddit.

  • 495 of the 499 comments contained "supabase", under 246 different post titles.
  • r/Supabase's 100 comments were all recent. In r/webdev, r/SideProject and r/nextjs the 100, and in r/SaaS the 99, reached back to October 2022.

Results are not ordered by date, so a rerun returns mostly the same comments. To track new mentions, keep the comment ids you have already saved and drop them on the next run.

What it costs

Each call is 1 credit and returns up to about 100 results, so the run above cost 5 credits. You get 100 free credits a month; $19 buys 10,000 credits that never expire, and plans for higher volume cover more subreddits. Set your key and run the script on your first word.

To read a subreddit's posts and a thread's comments with a free script instead, see our Reddit scraper in Python. For public Telegram channels, see Telegram channel messages as JSON.

We are not affiliated with Reddit.

Get this data from your own code

The Reddit API returns it as JSON with one x-api-key header. 100 free credits monthly.