Reddit search API: 25 posts per credit
Reddit search API now returns 25 posts per credit on three English queries (was ~7). Korean search billed 1. Comments flattened 647 at 5 credits, depth 9.
On 5 September 2026, three English Reddit search API queries on GET /v1/reddit/search each returned 25 posts for 1 credit. The 2026-09-03 labeled before was about 7 a page. A Korean query (기계식 키보드, sort=new) that used to return an empty, refunded page now returned 22 posts and billed 1 credit. One advanced comments call flattened 647 comments, nested to ext.depth 9, and billed 5 credits.
Official Reddit docs document how to ask — GET /search, then loop GET /api/morechildren — behind OAuth and 100 queries per minute. They do not print len(items) or credits per page. This post is not Devvit, and it is not the official Data API. It is the measured page-size for SocialCrawl's Reddit search, plus the comments and subreddit field-density siblings. For the official reddit api landscape, including that 100 QPM figure, see Reddit data API. For keys, OAuth, and rate limits, see Reddit API key limits. The $0.24 / 1,000 figure from June 2023 is historical; current Data API Terms do not restate a per-call price.
Stack: Python 3.10+ · requests · GET https://www.socialcrawl.dev/v1/reddit/… · header x-api-key. Print len(items) and credits_used. Pagination is one billed page per call (after on search and subreddit; cursor on comments). Free plan: 100 credits, no card. Live catalogue: /platforms/reddit. Per-path docs: /docs/reddit.
How many posts does a Reddit search API return per credit?
Three English queries each returned 25 posts for 1 credit. Call the search path and print the length of data.items plus the envelope credits_used. Page size is not a caller limit. The platform decides; a thin result set returns a thin page.
Live numbers from the 2026-09-05 harvest (00:45–00:47 UTC, nine production calls, 13 credits). The before-figure of about 7 a page is labeled from the 2026-09-03 summary and was not re-measured today. That is 25 vs about 7, still 1 credit. With the "about" on that labeled before, 25 / 7 is about 3.57× — not a precise multiple.
| Query | page_len | credits_used | has_more | request_id |
|---|---|---|---|---|
best mechanical keyboard | 25 | 1 | true | req-RZGwUkq5KzWaLMTD |
python web scraping | 25 | 1 | true | req-3x4e9CmHOyfQbUss |
best programming languages | 25 | 1 | true | req-MdeEthMIrO7GUhfE |
English mean = 25. All three hits sat on the ceiling this run. That is not a promise. Page size varies between calls — print len(items) every time. An optional trim=true contrast on the first query also returned 25 (24-id overlap with the full call). That is not a 7-vs-25 proof.
Official GET /search is filed as a listing with after / before. No measured yield. PRAW 8.0.3's ListingGenerator defaults to 100 content entries and paginates under the hood; the quick start never calls .search(). We did not extract an official limit default or max from the live catalog body, so those numbers are not printed here.
Python requests against the first fixture:
import os
import requests
BASE = "https://www.socialcrawl.dev"
r = requests.get(
f"{BASE}/v1/reddit/search",
params={"query": "best mechanical keyboard"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=60,
)
r.raise_for_status()
payload = r.json()
items = payload["data"]["items"]
pag = payload.get("pagination") or {}
print(len(items), payload.get("credits_used"), pag.get("has_more"))
# 25, 1, TrueCurl twin of the same GET:
curl "https://www.socialcrawl.dev/v1/reddit/search?query=best%20mechanical%20keyboard" \
-H "x-api-key: YOUR_KEY"This harvest recorded credits_used=1, pagination.has_more=true, and a next_cursor on the 25-row page (request_id req-RZGwUkq5KzWaLMTD). Pass pagination.next_cursor / after for page 2. This harvest did not fetch page 2.
Head row, 1w4c63y on r/keyboards, under the unified schema — not a dump:
{
"id": "1w4c63y",
"author": { "username": "freecoinsbabyhe" },
"engagement": { "likes": 6, "comments": 36, "shares": null },
"ext": {
"subreddit": "keyboards",
"title": "What's The Best Mechanical Keyboard In 2026? (Price, Switches)",
"upvote_ratio": 0.875,
"flair": "Discussion",
"content_language": "en"
}
}engagement.shares is present on the search row and null. It is numeric on post detail. Do not average shares across a search page.
Do Korean and other non-Latin Reddit searches still return empty?
Not on this reddit keyword search fixture. query=기계식 키보드 with sort=new returned 22 posts, billed 1 credit, has_more=false (the whole result set), request_id req-CCL9dE8QRxgRDwJI. The labeled before (2026-09-03) was 0 posts, refunded to 0 credits. A results page now bills the usual 1.
19 of 22 titles contain Hangul. The same query, in a different script, used to cost nothing because it returned nothing. We did not call Japanese, Arabic, or Cyrillic queries this run. Empty-page refunds used to hide those misses; a 22-row page at 1 credit is the working proof for Hangul sort=new only.
Field coverage on the newest sort=new leaves is thinner, which is not an empty page. content_language was ko on 5 rows, en on 7, and null on 10. Avatars were present on 15/22; upvote_ratio on 15/22. This harvest measured this Korean query only.
r = requests.get(
f"{BASE}/v1/reddit/search",
params={"query": "기계식 키보드", "sort": "new"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=60,
)
r.raise_for_status()
payload = r.json()
print(len(payload["data"]["items"]), payload.get("credits_used"))
# 22, 1curl "https://www.socialcrawl.dev/v1/reddit/search?query=%EA%B8%B0%EA%B3%84%EC%8B%9D%20%ED%82%A4%EB%B3%B4%EB%93%9C&sort=new" \
-H "x-api-key: YOUR_KEY"
How many comments does a Reddit comments API return for 5 credits?
This harvest flattened 647 comments for 5 credits on one thread. GET /v1/reddit/post/comments is always 5 credits, creditTier: advanced. The wave did not change the price. One billed GET auto-expands the whole tree, which is why the path sits on advanced and why the meter did not move.
Official shape is two methods: GET /comments/ for the article id, then GET /api/morechildren. PRAW's MoreComments.comments() is one extra round-trip per leftover node. If you want to scrape reddit comments yourself, that walk is the how to scrape Reddit path. This harvest is one billed GET.
Live 2026-09-05, Xbox Cloud Gaming thread (1w6p54w on r/technology). Parent listing row reported 1,320 comments:
Top-level data.items | 480 |
| Flattened tree | 647 |
ext.depth max | 9 (histogram 479 / 62 / 44 / 19 / 18 / 12 / 5 / 4 / 3 / 1 at depths 0–9) |
data.truncated | false |
next_cursor | null |
credits_used | 5 |
request_id | req-NZaBS71FJdlft25W |
647 comments / 5 credits = 129.4 comments per credit on this thread. Search = 25 posts per credit. 647 is this thread, not a promise for every thread.
Labeled before, other threads, 2026-09-03: 168 on one; 687 / 949 / 1,553 on larger ones; nested to depth 8. A 2026-09-04 check returned 96 comments and billed 5. Live depth on this thread is 9. Those counts are other threads, not a 4× on this one.
Comment bodies now arrive as Reddit's own markdown source. This tree had 8 comments with markdown bold markers and 2 with markdown links. First comment: p7orkjh / @HG21Reaper / "And that is the end of cloud gaming." / 7,568 likes / depth 0.
Two completeness caveats, then the flatten helper:
- The bigger comment response is not a superset of the old one. On a large thread both responses are partial and they stop in different places. Labeled 2026-09-03: between 77 and 103 comments per thread that the previous response carried are absent from the new one. Do not diff two captures and treat missing ids as a regression.
data.truncatedcan be true with nonext_cursor, which means the thread is incomplete and this endpoint cannot fetch the rest. This run wastruncated: falsewith no cursor, and still only 647 of the listing's 1,320. Reddit's own count includes removed, deleted, and filtered replies that no listing returns.
THREAD = (
"https://www.reddit.com/r/technology/comments/1w6p54w/"
"microsoft_announces_big_changes_to_xbox_cloud/"
)
def flatten_comments(nodes):
flat = []
for node in nodes or []:
flat.append(node)
flat.extend(flatten_comments(node.get("replies") or []))
return flat
r = requests.get(
f"{BASE}/v1/reddit/post/comments",
params={"url": THREAD},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=60,
)
r.raise_for_status()
payload = r.json()
flat = flatten_comments(payload["data"]["items"])
depths = [((c.get("ext") or {}).get("depth") or 0) for c in flat]
print(len(flat), payload.get("credits_used"), max(depths, default=0))
# 647, 5, 9curl "https://www.socialcrawl.dev/v1/reddit/post/comments?url=https://www.reddit.com/r/technology/comments/1w6p54w/microsoft_announces_big_changes_to_xbox_cloud/" \
-H "x-api-key: YOUR_KEY"Expect 647, 5 on this fixture. Other threads return other trees.
What extra fields do Reddit search and subreddit rows now carry?
Row density did not move on subreddit listings. Field density did, on both the search path and the subreddit path. The reddit post api follow-up now reports shares as share counts, not crossposts. Counts below are non-null and non-empty. Link posts have no body, so ext.selftext is legitimately null on those rows.
| Call | n | selftext | avatar | media_urls | upvote_ratio | flair | content_language |
|---|---|---|---|---|---|---|---|
search best mechanical keyboard | 25 | 23 | 25 | 7 | 25 | 23 | 25 |
search python web scraping | 25 | 25 | 25 | 1 | 25 | 11 | 25 |
search best programming languages | 25 | 21 | 25 | 0 | 25 | 11 | 25 |
search 기계식 키보드 sort=new | 22 | 14 | 15 | 8 | 15 | 14 | 12 |
subreddit technology | 19 | 0 | 18 | 19 | 19 | 19 | 18 |
subreddit MechanicalKeyboards | 24 | 1 | 22 | 24 | 24 | 24 | 19 |
On search, content.media_urls is an array (one mechanical-keyboard row had 14 image URLs). On subreddit listings, it is a string: the linked article on r/technology, a gallery or image URL on r/MechanicalKeyboards. Not every search row has images. Subreddit media is not always an array.
include_body=true still works and is rarely needed now, because bodies arrive on the rows themselves. When there is nothing extra to fetch, those extra credits refund in full. /docs/reddit still says feed and search leave the body out; that line is stale. The harvest is current.
Post detail on the same 1w4c63y keyboard URL (GET /v1/reddit/post, request_id req-Vh5FZG0Gdom8eiv7): 1 credit, engagement.shares = 14 (numeric). Same field, different metric — shares, not crossposts. On every search row this run, engagement.shares was null (opportunistic; do not average). ext.selftext was 535 characters, likes 6, comments 36, upvote ratio 0.875, flair Discussion, content language en.
A labeled 2026-09-03 reliability note, not re-measured this run: peak post-detail failure was 12.64% and is now near zero.
Why didn't subreddit listings get more rows?
They didn't. r/technology returned 19 rows (request_id req-H65Zh8fV5urAVoLt). r/MechanicalKeyboards returned 24 (request_id req-t3g7LMCltAcNLgZ1). Both still 1 credit, both has_more=true. Both sit in the same 15–25 band as before.
Rows were not widened, on purpose. Fields are added to the rows you already get; rows are not. Those are 19 and 24, not a new "up to 25" density claim. A wider page would mix promoted posts into the organic ranking with no field to separate them.
r = requests.get(
f"{BASE}/v1/reddit/subreddit",
params={"subreddit": "technology"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
r.raise_for_status()
payload = r.json()
print(len(payload["data"]["items"]), payload.get("credits_used"))
# 19, 1curl "https://www.socialcrawl.dev/v1/reddit/subreddit?subreddit=technology" \
-H "x-api-key: YOUR_KEY"How did we measure this — and can you reproduce it from Python?
The reddit api python path for this harvest is requests, one key, one billed page. PRAW still needs client_id / client_secret / user_agent even for public reads.
| Metric | Page length (or flattened comment count) per billed call |
| Formula (lists) | page_len = Array.isArray(data.items) ? data.items.length : 0 |
| Formula (comments) | Walk data.items and every nested replies[]. Count each comment node once. Depth is comment.ext.depth. |
| Credits | Envelope credits_used (cache hits and refunds are 0; none of those this run) |
| Sample | 3 English search queries; 1 Korean search (sort=new); 2 subreddit listings; 1 post URL from a search row; 1 large comment thread from the r/technology listing; optional trim=true contrast |
| Date pulled | 2026-09-05 (00:45–00:47 UTC) |
| Endpoints | /v1/reddit/search (1 cr), /v1/reddit/subreddit (1 cr), /v1/reddit/post (1 cr), /v1/reddit/post/comments (5 cr, advanced). Not called: omni-search, transcript, ads. |
| This-run spend | 13 credits (credits_used sum). Starting balance 140,193 → ending 140,021; the 172 delta is concurrent measurement on the same key, so this harvest is 13, not 172. |
Anyone with a SocialCrawl API key can rerun GET https://www.socialcrawl.dev/v1/reddit/search?query=best%20mechanical%20keyboard with x-api-key, then print(len(data["items"]), credits_used) — expect a page around the mid-20s at 1 credit, not a fixed 25. Same call with 기계식 키보드 plus sort=new should return rows and bill 1. Flatten helper and the Korean GET are in the sections above.
Same density-wave family as TikTok API documentation: 150 followers per credit.
What do short pages, truncated threads, and refunds actually mean?
- Page size varies. Three English searches hit 25; Korean hit 22. Print
len(items)in every sample. - Comments are not a superset of the old tree (2026-09-03). Do not diff two captures and treat missing ids as a regression.
data.truncatedcan be true with nonext_cursor. This run:truncated: false, no cursor, still 647 of 1,320.- Korean search now bills 1 when it returns rows. Empty pages used to refund to 0. Newest
sort=newrows may lack avatar / upvote ratio / content language. - Subreddit listings were not widened. Promoted-post mixing. Live: 19 and 24.
engagement.shareson search rows is opportunistic and was null on every search row this run. Numeric on post detail (14). Do not average.trim=truedid not shorten the page this run. Not a 7-vs-25 proof.- Comments cost 5 credits, advanced, unchanged. Not 1.
No 4xx/5xx, no refunds, no cache hits this run. Cache hits bill 0; empty pages refund; bad params return 400 and are unbilled (product contract — not observed this harvest). Per-key limits: 600 requests/minute, 50 concurrent (pricing).
Where to go after the first 25-row search page
- Reddit endpoint catalogue:
/docs/reddit - Live platform page:
/platforms/reddit - Official-API landscape: Reddit data API
- DIY scrape path, including a reddit scraper api walkthrough: how to scrape Reddit
- Vendor comparison: best Reddit data APIs
- Key / limits: Reddit API key limits
- Sibling density post: TikTok: 150 followers per credit
Reproduce with four GETs: English search best mechanical keyboard, Korean 기계식 키보드 sort=new, subreddit technology, comments on the Xbox Cloud Gaming URL. Try the same GET in the visual explorer before writing a single line.
Frequently asked questions
How many posts does a Reddit search API return per credit?
Live 25 on three English queries (best mechanical keyboard, python web scraping, best programming languages), 1 credit each, 2026-09-05. Page size varies — read len(items), do not assume 25. Korean 기계식 키보드 sort=new returned 22 at 1 credit.
Did Reddit search page size change?
Yes. Labeled before (2026-09-03) was about 7 a page. Live 25 on three English queries, still 1 credit. Harvest date 2026-09-05. Print len(items).
How many comments does 5 credits return now?
Live 647 flattened (ext.depth max 9) on the r/technology Xbox Cloud Gaming thread, 5 credits, advanced, unchanged. Listing count was 1,320; truncated: false. Never 1 credit. 647 is this thread, not a promise for every thread.
Do Korean Reddit searches still come back empty?
No on this fixture. 기계식 키보드 sort=new returned 22 posts and billed 1 (2026-09-05). Labeled before: empty page, refunded to 0. 19/22 titles contain Hangul. Newest rows may lack content_language (null on 10/22).
Did subreddit listings get more rows too?
No. r/technology 19, r/MechanicalKeyboards 24, still 1 credit — same 15–25 band. Fields added (avatar, media, upvote ratio, flair, content language). A wider page would mix promoted posts into the organic ranking with no field to separate them.
Is include_body still required on search?
Rarely. Search and subreddit rows now carry ext.selftext when the post has a body (23/25 on the mechanical-keyboard page). include_body=true still works; unused extra credits refund in full.
Why is a bigger comment page not a superset of the old one?
On a large thread both responses are partial and stop in different places. Labeled 2026-09-03: 77–103 comments per thread from the previous response are absent from the new one. data.truncated can be true with no next_cursor, meaning this endpoint cannot fetch the rest. This run's thread was truncated: false and still returned 647 of 1,320.
Related posts
Financial Data API: 1,255 Daily Bars, Both Closes
Financial data API: 1,255 AAPL daily bars with both closes, plus statements, an 81-contract options chain, and ticker news. Live from GET /v1/finance/.
Instagram Email Finder: 1 Credit, Email When Public
9/9 Instagram about lookups returned country (1 credit). Public email on 3/9 — null when unpublished. YouTube about costs 60 credits. Captured 2026-09-05.
Scrape Threads: 55 Posts for 3 Credits + Comments
Scrape Threads with one API: 55 posts for 3 credits via multi-window search. Plus comments, carousel slides, and phrase expand that turned 0 hits into 44.
