Skip to content
Back to skills

Reddit Researcher

ASecurity

Search and read public Reddit posts, subreddits, and comments via the unauthenticated JSON API. Safe read-only access with SSRF-prevention hostname allowlist.

  • 40 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
developmentjavascriptrustgojavabashnodenodejsawsapi

Works with

  • cursor
  • api

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add oimiragieo/agent-studio --skill reddit-researcher --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Reddit Researcher?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Reddit Researcher
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/oimiragieo-reddit-researcher/badge)](https://www.skillsdirectory.com/skills/oimiragieo-reddit-researcher)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: reddit-researcher
version: 1.0.0
description: Search and read public Reddit posts, subreddits, and comments via the unauthenticated JSON API. Safe read-only access with SSRF-prevention hostname allowlist.
category: integration
trigger: when user wants to research Reddit discussions, find posts in a subreddit, search Reddit for topics, read Reddit comments, or gather community sentiment from Reddit
tools: [WebFetch, WebSearch]
dependencies: []
tags: [reddit, research, social-media, integration, read-only, public-api]
model: sonnet
invoked_by: both
user_invocable: true
error_handling: graceful
verified: false
source: builtin
trust_score: 100
provenance_sha: 9af60d6bb6fffa11
---

<!-- Agent: nodejs-pro | Task: #7 | Session: 2026-03-09 -->

# Reddit Researcher Skill

## Purpose

Fetch and analyze public Reddit content without authentication using the Reddit public JSON API. Enables research agents to read subreddit posts, search Reddit globally or within a subreddit, and fetch individual post comments — all through the stable `.json` endpoint pattern.

**No API key. No OAuth. No registration.** Reddit's public JSON API is accessible anonymously for read-only operations.

---

## When to Use

- Researching community sentiment on a topic
- Finding relevant discussions in a specific subreddit
- Gathering examples, opinions, or use cases from Reddit
- Monitoring a subreddit for recent posts
- Fetching comments on a specific post for analysis

---

## Iron Laws

1. **ALWAYS validate Reddit URLs against the allowlist before WebFetch** — only `reddit.com`, `www.reddit.com`, and `old.reddit.com` are permitted; reject anything else to prevent SSRF attacks.
2. **ALWAYS append `.json` to Reddit URLs before fetching** — never fetch HTML pages; the `.json` suffix returns structured data that can be parsed reliably.
3. **ALWAYS include a User-Agent header** — Reddit blocks requests without a proper User-Agent; use `agent-studio-reddit-researcher/1.0`.
4. **NEVER make more than 10 WebFetch calls per minute** — unauthenticated rate limit is 10 req/min; add 1-2 second delays for multi-call workflows; search endpoints are more restrictive (~3-5 req/min).
5. **NEVER write to Reddit** — this skill is strictly read-only; no POST requests, no upvoting, no commenting, no authentication flows.

---

## API Reference

| Endpoint                                                             | Description             | Notes                             |
| -------------------------------------------------------------------- | ----------------------- | --------------------------------- |
| `https://www.reddit.com/r/{sub}.json`                                | Hot posts in subreddit  | Default sort: hot                 |
| `https://www.reddit.com/r/{sub}/hot.json`                            | Hot posts (explicit)    |                                   |
| `https://www.reddit.com/r/{sub}/new.json`                            | New posts               |                                   |
| `https://www.reddit.com/r/{sub}/top.json?t=week`                     | Top posts by time       | t=hour/day/week/month/year/all    |
| `https://www.reddit.com/r/{sub}/about.json`                          | Subreddit metadata      | subscriber count, description     |
| `https://www.reddit.com/search.json?q={query}`                       | Global search           |                                   |
| `https://www.reddit.com/r/{sub}/search.json?q={query}&restrict_sr=1` | Subreddit-scoped search |                                   |
| `https://www.reddit.com/r/{sub}/comments/{id}.json`                  | Post with comments      | Returns array[2]: post + comments |

**Query Parameters:**

- `limit` — number of results (max 100, default 25; keep at 25 or less to stay within rate limits)
- `after` / `before` — pagination cursors (`t3_postid` format)
- `t` — time filter for `/top`: `hour`, `day`, `week`, `month`, `year`, `all`
- `restrict_sr=1` — restrict search to current subreddit

**Required Headers:**

```
User-Agent: agent-studio-reddit-researcher/1.0
```

---

## SSRF Guard Pattern

Always validate URLs using `new URL().hostname` before passing to WebFetch. Do not use regex or string-contains matching — those fail on encoded URLs and normalization tricks.

```javascript
const ALLOWED_REDDIT_HOSTS = new Set(['reddit.com', 'www.reddit.com', 'old.reddit.com']);

function validateRedditUrl(href) {
  let parsed;
  try {
    parsed = new URL(href);
  } catch {
    throw new Error('Invalid URL');
  }
  if (!['http:', 'https:'].includes(parsed.protocol)) {
    throw new Error('Only http/https allowed');
  }
  if (!ALLOWED_REDDIT_HOSTS.has(parsed.hostname)) {
    throw new Error(`Hostname ${parsed.hostname} not in allowlist`);
  }
  return parsed.href;
}
```

**Additional blocks (OWASP-recommended):**

- Block `file://`, `gopher://`, `dict://` schemes
- Block `127.0.0.1`, `localhost`, `0.0.0.0`
- Block `169.254.169.254` (AWS/cloud metadata endpoint)

---

## Rate Limit Guidance

| Endpoint Type             | Limit        | Notes                               |
| ------------------------- | ------------ | ----------------------------------- |
| General listing endpoints | 10 req/min   | Rolling window                      |
| Search endpoints          | ~3-5 req/min | More restrictive                    |
| WebFetch built-in cache   | 15-min TTL   | Repeated calls to same URL are free |

**Safe multi-call pattern:** Add 1-2 second delays between calls. Use `limit=25` to get enough results per call without needing rapid pagination.

---

## Response Structure

**Post listing (`data.children[].data`):**

```json
{
  "id": "abc123",
  "title": "Post title here",
  "selftext": "Post body text",
  "url": "https://www.reddit.com/r/sub/comments/abc123/...",
  "author": "username",
  "score": 42,
  "num_comments": 10,
  "created_utc": 1234567890,
  "subreddit": "subredditname"
}
```

**Comments response:** Array of two elements — `[0]` is the post, `[1]` is the comment tree.

---

## Usage Examples

### Search a subreddit for a topic

```
Invoke: WebFetch
URL: https://www.reddit.com/r/MachineLearning/search.json?q=transformer+architecture&restrict_sr=1&limit=10
Headers: User-Agent: agent-studio-reddit-researcher/1.0
```

### Get hot posts from a subreddit

```
Invoke: WebFetch
URL: https://www.reddit.com/r/programming/hot.json?limit=25
Headers: User-Agent: agent-studio-reddit-researcher/1.0
```

### Fetch a specific post with comments

```
Invoke: WebFetch
URL: https://www.reddit.com/r/programming/comments/abc123.json
Headers: User-Agent: agent-studio-reddit-researcher/1.0
```

### Global Reddit search

```
Invoke: WebFetch
URL: https://www.reddit.com/search.json?q=claude+code+agent&limit=25
Headers: User-Agent: agent-studio-reddit-researcher/1.0
```

---

## Anti-Patterns

| Anti-Pattern                               | Why It Fails                                           | Correct Approach                                                |
| ------------------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------- |
| Fetching reddit.com without `.json` suffix | Returns HTML, not structured data                      | Always append `.json` to the URL path                           |
| Using regex to validate URLs               | Fails on encoded/normalized URLs; SSRF bypass possible | Use `new URL(href).hostname` and check against allowlist Set    |
| No User-Agent header                       | Reddit blocks anonymous requests; returns 429 or HTML  | Always include `User-Agent: agent-studio-reddit-researcher/1.0` |
| Rapid successive requests (>10/min)        | Rate limit triggers 429 responses                      | Add 1-2s delays; use `limit=100` to reduce call count           |
| Attempting write operations                | Reddit's public JSON API is read-only without OAuth    | Use only GET endpoints; never attempt POST/PUT/DELETE           |

---

## Enforcement Hooks

- **Pre-execute** (`hooks/pre-execute.cjs`): Validates input schema (AJV) and checks SSRF allowlist on any url field. Exits with code `2` on violation (fail-closed).
- **Post-execute** (`hooks/post-execute.cjs`): Emits observability event via `send-event.cjs`. Fails open (exit `0`) on error to avoid blocking skill execution.

---

## Memory Protocol (MANDATORY)

**Before starting:**

```bash
cat .claude/context/memory/learnings.md
```

**After completing:**

- New Reddit API pattern -> `.claude/context/memory/learnings.md`
- Issue found (rate limit, API change) -> `.claude/context/memory/issues.md`
- Decision made -> `.claude/context/memory/decisions.md`

> ASSUME INTERRUPTION: If it is not in memory, it did not happen.

Files in this skill

  • SKILL.md8.6 KB
  • commands/reddit-researcher.md2.1 KB
  • hooks/post-execute.cjs1.1 KB
  • hooks/pre-execute.cjs4.3 KB
  • references/research-requirements.md1.3 KB
  • rules/reddit-researcher.md1 KB
  • schemas/input.schema.json1.1 KB
  • schemas/output.schema.json1.7 KB
  • scripts/main.cjs6.2 KB
  • templates/implementation-template.md336 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…