STRUCTURED DATA API

Reddit Scraper API

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

A threaded discussion tree of nested reply cards with upvote arrows, gathered into structured data blocks

Scrape Reddit posts, comments, subreddits and users

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.

Post

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

Subreddit

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

User

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
The Reddit parser doesn't cover share links (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.

How to scrape Reddit with one API call

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.

What the Reddit scraper returns

The key fields per page type. Names are snake_case across every site; the full contract is in the API reference.

type: "post"

FieldWhat it holds
id, fullname, url, permalink, title, selftextThe post; selftext is the body (selftext_html too).
author, author_fullname, subreddit, subreddit_idWhere and who.
score, upvote_ratio, num_comments, total_awards_receivedEngagement.
created_utc, created_atEpoch seconds and ISO time.
link_flair_text, distinguished, locked, archivedFlair and flags.
domain, post_type, post_hint, thumbnail, images, media_url, hls_url, durationLink and media details; for hosted video media_url is an MP4 with audio and hls_url the stream.
commentsThe 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_countHow 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"

FieldWhat it holds
subredditname, title, public_description, weekly_active_users, weekly_contributions, created_at, subreddit_type, community_icon.
postsThe first 25 posts of the feed in Reddit's default Hot order, with the same fields as a post (without comments).
next_cursorReddit's cursor for the next page of the feed.

type: "user"

FieldWhat it holds
id, name, url, created_atThe account.
link_karma, comment_karma, total_karmaPost and comment karma, as the profile shows them.
is_gold, is_employeeReddit Premium and admin flags.
icon_imgAvatar.
posts, comments, next_cursorThe latest 25 items of the user's activity, split into posts and comments (with the thread title and link).

What's not included

Everything comes from what Reddit shows a logged-out visitor. That sets these limits.

The first ~25 comments of a thread. That's what Reddit's page shows logged out. 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.
Some fields are 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.
One page of feeds. A subreddit returns the first 25 posts in Hot order (a sort in the URL, like /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.
Slower than other sites. Each Reddit request loads the page in a real browser, so expect usually 12–20 seconds, occasionally up to about 35, rather than the few seconds other sites take.
Share links aren't resolved. /r/sub/s/… links from the Reddit app aren't covered by the Reddit parser; open them once to get the full post URL.
Need a page type or site that isn't supported? /ai/fields extracts the fields you describe in plain language from any public page, and /html returns the rendered HTML for your own parser.

Flat pricing: 50 credits per page

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.

PlanPriceCreditsPages
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.

What's charged

No structured data found on a page the parser doesn't cover: a 422, not charged.
Page couldn't be fetched: a 500, not charged.
Charged even without data: 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.

Also from the terminal, AI agents, and n8n

CLI

webscraping-ai has a data command; pass - to read URLs from stdin, one per line.

webscraping-ai data 'https://www.reddit.com/r/webscraping/'

MCP server

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.

n8n

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.

Frequently asked questions

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.

Get Reddit data as JSON today

Get started with 2,000 free API credits. No credit card required.

Icon