A Reddit scraper you call over HTTP: send a post, subreddit or user URL to /data and get the post with its nested comment tree, a subreddit's front page, or a user's karma and activity back as JSON. No Reddit API key or OAuth app. Flat 50 credits per page.
2,000 free API credits · No credit card required
Send the page's normal URL to /data. The page type is detected from the URL, and the response tells you which one it was in request_parameters.type.
type: "post"
Title, body, author, score, upvote ratio, comment count, flair, media and flags, plus the comment tree with replies nested (the first ~25 comments Reddit shows).
reddit.com/r/sub/comments/POST_ID/slug
redd.it/POST_ID
old.reddit.com/r/sub/comments/POST_ID
type: "subreddit"
Name, title, description, weekly visitors and contributions, creation date, type and icon, plus the first 25 posts of its feed (Reddit's default Hot order) and a cursor for the next page.
reddit.com/r/sub
old.reddit.com/r/sub
type: "user"
Post, comment and total karma, cake day, Premium and admin flags and avatar, plus the user's latest 25 posts and comments.
reddit.com/user/name
reddit.com/u/name
reddit.com/r/sub/s/…), search, and r/all, r/popular and the home feed. /data still takes these URLs: as on any site without a dedicated parser, an AI model learns the page's structure (the first request for a new kind of page can take up to about 45 seconds) and returns its key values, priced per site rather than at the flat 50 credits (see the API reference). If no structured data can be found, you get a 422 that isn't charged.
No selectors, proxies, or headless browser to run. The page-scraping options (js, proxy, headers…) don't apply; country picks the proxy country (default us).
curl -G "https://api.webscraping.ai/data" \
--data-urlencode "api_key=YOUR_API_KEY" \
--data-urlencode "url=https://www.reddit.com/r/webscraping/"
# Response (excerpt):
# {
# "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
# "provider": "reddit", "type": "subreddit"},
# "parse_status": "ok",
# "data": {
# "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
# "subreddit_type": "public", "url": "/r/webscraping/", ...},
# "posts": [
# {"id": "...", "title": "...", "author": "...", "score": 42,
# "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
# "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
# "created_at": "2026-09-25T14:03:11.000Z", ...},
# ...
# ],
# "next_cursor": "t3_..."
# }
# }
# pip install webscraping_ai
# https://pypi.org/project/webscraping-ai/
from webscraping_ai import Client
client = Client(api_key="YOUR_API_KEY")
result = client.data("https://www.reddit.com/r/webscraping/")
print(result["request_parameters"]["provider"], result["parse_status"])
print(result["data"])
# Response (excerpt):
# {
# "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
# "provider": "reddit", "type": "subreddit"},
# "parse_status": "ok",
# "data": {
# "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
# "subreddit_type": "public", "url": "/r/webscraping/", ...},
# "posts": [
# {"id": "...", "title": "...", "author": "...", "score": 42,
# "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
# "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
# "created_at": "2026-09-25T14:03:11.000Z", ...},
# ...
# ],
# "next_cursor": "t3_..."
# }
# }
// npm install webscraping-ai
// https://www.npmjs.com/package/webscraping-ai
import { WebScrapingAI } from 'webscraping-ai';
const client = new WebScrapingAI({ apiKey: 'YOUR_API_KEY' });
const result = await client.data({ url: 'https://www.reddit.com/r/webscraping/' });
console.log(result.request_parameters.provider, result.parse_status);
console.log(result.data);
// Response (excerpt):
// {
// "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
// "provider": "reddit", "type": "subreddit"},
// "parse_status": "ok",
// "data": {
// "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
// "subreddit_type": "public", "url": "/r/webscraping/", ...},
// "posts": [
// {"id": "...", "title": "...", "author": "...", "score": 42,
// "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
// "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
// "created_at": "2026-09-25T14:03:11.000Z", ...},
// ...
// ],
// "next_cursor": "t3_..."
// }
// }
<?php
// composer require webscraping-ai/webscraping-ai-php
// https://packagist.org/packages/webscraping-ai/webscraping-ai-php
require 'vendor/autoload.php';
use WebScrapingAI\Client;
$client = new Client('YOUR_API_KEY');
$result = $client->data(url: 'https://www.reddit.com/r/webscraping/');
echo $result['request_parameters']['provider'], ' ', $result['parse_status'], "\n";
print_r($result['data']);
// Response (excerpt):
// {
// "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
// "provider": "reddit", "type": "subreddit"},
// "parse_status": "ok",
// "data": {
// "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
// "subreddit_type": "public", "url": "/r/webscraping/", ...},
// "posts": [
// {"id": "...", "title": "...", "author": "...", "score": 42,
// "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
// "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
// "created_at": "2026-09-25T14:03:11.000Z", ...},
// ...
// ],
// "next_cursor": "t3_..."
// }
// }
# gem install webscraping_ai
# https://rubygems.org/gems/webscraping_ai
require 'webscraping_ai'
client = WebScrapingAI::Client.new(api_key: 'YOUR_API_KEY')
result = client.data('https://www.reddit.com/r/webscraping/')
puts "#{result['request_parameters']['provider']} #{result['parse_status']}"
puts result['data'].inspect
# Response (excerpt):
# {
# "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
# "provider": "reddit", "type": "subreddit"},
# "parse_status": "ok",
# "data": {
# "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
# "subreddit_type": "public", "url": "/r/webscraping/", ...},
# "posts": [
# {"id": "...", "title": "...", "author": "...", "score": 42,
# "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
# "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
# "created_at": "2026-09-25T14:03:11.000Z", ...},
# ...
# ],
# "next_cursor": "t3_..."
# }
# }
// go get github.com/webscraping-ai/webscraping-ai-go/v4
// https://pkg.go.dev/github.com/webscraping-ai/webscraping-ai-go/v4
package main
import (
"context"
"fmt"
webscrapingai "github.com/webscraping-ai/webscraping-ai-go/v4"
)
func main() {
client, _ := webscrapingai.NewClient(&webscrapingai.Config{APIKey: "YOUR_API_KEY"})
res, _ := client.Data(context.Background(), &webscrapingai.DataOptions{
URL: "https://www.reddit.com/r/webscraping/",
})
fmt.Println(res.RequestParameters.Provider, res.ParseStatus)
fmt.Println(string(res.Data)) // raw JSON; its shape depends on the provider and page type
}
// Response (excerpt):
// {
// "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
// "provider": "reddit", "type": "subreddit"},
// "parse_status": "ok",
// "data": {
// "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
// "subreddit_type": "public", "url": "/r/webscraping/", ...},
// "posts": [
// {"id": "...", "title": "...", "author": "...", "score": 42,
// "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
// "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
// "created_at": "2026-09-25T14:03:11.000Z", ...},
// ...
// ],
// "next_cursor": "t3_..."
// }
// }
// Maven: ai.webscraping:webscraping-ai:4.3.1
// https://central.sonatype.com/artifact/ai.webscraping/webscraping-ai
import ai.webscraping.Client;
import ai.webscraping.Config;
import ai.webscraping.option.DataOptions;
import ai.webscraping.result.DataResult;
Client client = new Client(Config.builder().apiKey("YOUR_API_KEY").build());
DataResult result = client.data(DataOptions.builder()
.url("https://www.reddit.com/r/webscraping/")
.build());
System.out.println(result.getRequestParameters().getProvider() + " " + result.getParseStatus());
System.out.println(result.getData());
// Response (excerpt):
// {
// "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
// "provider": "reddit", "type": "subreddit"},
// "parse_status": "ok",
// "data": {
// "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
// "subreddit_type": "public", "url": "/r/webscraping/", ...},
// "posts": [
// {"id": "...", "title": "...", "author": "...", "score": 42,
// "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
// "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
// "created_at": "2026-09-25T14:03:11.000Z", ...},
// ...
// ],
// "next_cursor": "t3_..."
// }
// }
// dotnet add package WebScrapingAI
// https://www.nuget.org/packages/WebScrapingAI
using WebScrapingAI;
var client = new WebScrapingAIClient(new WebScrapingAIClientOptions { ApiKey = "YOUR_API_KEY" });
var result = await client.DataAsync(new DataRequest {
Url = "https://www.reddit.com/r/webscraping/",
});
Console.WriteLine($"{result.RequestParameters.Provider} {result.ParseStatus}");
Console.WriteLine(result.Data);
// Response (excerpt):
// {
// "request_parameters": {"url": "https://www.reddit.com/r/webscraping/",
// "provider": "reddit", "type": "subreddit"},
// "parse_status": "ok",
// "data": {
// "subreddit": {"name": "webscraping", "title": "...", "weekly_active_users": 12000,
// "subreddit_type": "public", "url": "/r/webscraping/", ...},
// "posts": [
// {"id": "...", "title": "...", "author": "...", "score": 42,
// "upvote_ratio": 0.95, "num_comments": 17, "link_flair_text": "...",
// "permalink": "https://www.reddit.com/r/webscraping/comments/.../",
// "created_at": "2026-09-25T14:03:11.000Z", ...},
// ...
// ],
// "next_cursor": "t3_..."
// }
// }
Trimmed, and the counts are illustrative — they change constantly. Fields a page doesn't expose come back as null, though some flags come back false and lists come back empty. data can be null when parse_status is parse_failed or not_found, so check it before reading fields.
The key fields per page type. Names are snake_case across every site; the full contract is in the API reference.
type: "post"| Field | What it holds |
|---|---|
id, fullname, url, permalink, title, selftext | The post; selftext is the body (selftext_html too). |
author, author_fullname, subreddit, subreddit_id | Where and who. |
score, upvote_ratio, num_comments, total_awards_received | Engagement. |
created_utc, created_at | Epoch seconds and ISO time. |
link_flair_text, distinguished, locked, archived | Flair and flags. |
domain, post_type, post_hint, thumbnail, images, media_url, hls_url, duration | Link and media details; for hosted video media_url is an MP4 with audio and hls_url the stream. |
comments | The tree in Reddit's order: each comment has author, body, body_html, score, created_at, depth, is_submitter, distinguished, more_count and its replies. |
comments_returned, comments_truncated, more_comments_count | How many comments came back, whether anything was left out, and how many of the post's comments weren't returned. A comment's more_count is null when Reddit shows more replies under it without a count. |
type: "subreddit"| Field | What it holds |
|---|---|
subreddit | name, title, public_description, weekly_active_users, weekly_contributions, created_at, subreddit_type, community_icon. |
posts | The first 25 posts of the feed in Reddit's default Hot order, with the same fields as a post (without comments). |
next_cursor | Reddit's cursor for the next page of the feed. |
type: "user"| Field | What it holds |
|---|---|
id, name, url, created_at | The account. |
link_karma, comment_karma, total_karma | Post and comment karma, as the profile shows them. |
is_gold, is_employee | Reddit Premium and admin flags. |
icon_img | Avatar. |
posts, comments, next_cursor | The latest 25 items of the user's activity, split into posts and comments (with the thread title and link). |
Everything comes from what Reddit shows a logged-out visitor. That sets these limits.
comments_truncated tells you something was left out and more_comments_count how many comments weren't returned. The rest of a large thread isn't fetched.null. Reddit's public pages don't show them: upvote counts separate from score, edit times, crosspost counts, subreddit member counts (weekly visitors are returned instead) and parts of user profiles./top, is accepted but not applied); a user returns their latest 25 posts and comments. next_cursor is in the response, but there's no request parameter to fetch the next page with it yet./r/sub/s/… links from the Reddit app aren't covered by the Reddit parser; open them once to get the full post URL./ai/fields extracts the fields you describe in plain language from any public page, and /html returns the rendered HTML for your own parser.
Every supported Reddit page type costs the same, with no extra charge for proxies or retries. That's about $5.80 per 1,000 pages on the $29 plan.
Reddit costs more than the other /data sites (15 credits a page) because every Reddit page is loaded in a real browser.
| Plan | Price | Credits | Pages |
|---|---|---|---|
| Free | $0 | 2,000 | up to 40 |
| Personal | $29/mo | 250,000 | up to 5,000 |
| Plus | $99/mo | 1,000,000 | up to 20,000 |
| Startup | $249/mo | 3,000,000 | up to 60,000 |
The free plan's 2,000 credits renew monthly. All plans, including pay-as-you-go credits.
422, not charged.500, not charged.parse_status parse_failed (the page was fetched but couldn't be parsed) and not_found (the page doesn't exist) are successful requests and cost 50 credits, like ok.webscraping-ai has a data command; pass - to read URLs from stdin, one per line.
webscraping-ai data 'https://www.reddit.com/r/webscraping/'Claude, Cursor and other MCP clients get a webscraping_ai_data tool from the hosted MCP server (OAuth login, no API key to paste). Ask for a Reddit page's data in plain language and the agent calls it.
The WebScraping.AI n8n node has a Get Structured Data operation: feed it URLs from a sheet or a trigger and route the JSON onward, no code.
Do I need a Reddit API key?
No. You send the normal reddit.com URL and /data returns the post, comment and listing data from Reddit's public pages as JSON. There's no Reddit developer app, OAuth token or per-request Reddit API fee involved; you pay 50 credits per page.
Can I scrape Reddit comments?
Yes. A post URL returns the first ~25 comments Reddit shows, with replies nested under their parents in Reddit's order. When a thread is bigger, comments_truncated is true and more_comments_count says how many comments weren't returned.
Can I page through a subreddit?
A subreddit URL returns the first 25 posts of its feed in Reddit's default Hot order, plus next_cursor. Paging with that cursor, or picking another sort, isn't available as a request parameter yet.
Is there a free Reddit scraper API?
Yes, for trying it out: the free plan includes 2,000 API credits every month, which covers 40 Reddit pages at 50 credits each. No credit card is needed. Paid plans start at $29/mo for 250,000 credits, or buy pay-as-you-go credits with no subscription from a $20 top-up (100,000 credits, about 2,000 pages).
How much does the Reddit Scraper API cost?
A flat 50 credits per page, for every supported Reddit page type. On the $29/mo plan (250,000 credits) that is up to 5,000 pages, or about $5.80 per 1,000. Fetch failures return a 500 and aren't charged. Pages outside the supported Reddit page types go to the AI-learned path and are priced per site. parse_failed and not_found results are successful requests and are charged.
What happens if I send a URL the Reddit parser doesn't cover?
/data still answers it: an AI model learns the page's structure (the first request for a new kind of page can take up to about 45 seconds) and returns its key values, priced per site like any site without a dedicated parser. If no structured data can be found, you get a 422 that isn't charged; /ai/fields then extracts the fields you name, and /html returns the rendered page for your own parser.
One API key, one request format, the same response envelope.
Get started with 2,000 free API credits. No credit card required.