Reddit profile API: 6 new reads, people not posts
Reddit profile API: spez + 23 posts for 1 credit. Comment search 14/1 isn't history: 5 dated comments cost 10. Subreddit search 25, 5 of 25 ids repeated.
A Reddit profile API is how you follow a person, not a thread. On 8 September 2026 we called production: GET /v1/reddit/profile?handle=spez returned the account card for 1 credit (karma 940,980, cake day 2005-06-06, bio "Reddit CEO"). profile/posts returned 23 submissions for 1 credit.
Four more new reads ship with it — comment search, subreddit discovery, and media search (all 1 credit a page this harvest), plus metered comment history at 2 credits per comment (limit=5 billed 10). The cheap author:spez comment search returned 14 rows whose newest was 30 July; the 10-credit history page's five comments are all 5 August. Search is not history.
Official Reddit docs name user listings and a single GET /search. They do not print len(items) or credits per call. PRAW's quick start prints link_karma and a post's comment tree. This post is SocialCrawl's measured people reads behind x-api-key — not Devvit, not the official Data API.
Search page-size and thread comments — the reddit search api story — are a different post.
Stack: Python 3.10+ · requests · GET https://www.socialcrawl.dev/v1/reddit/… · header x-api-key. Print len(items) and credits_used. Live catalogue: /docs/reddit. Platform hub: /platforms/reddit. Credits: /pricing.
How do you read a Reddit profile (and the posts that account wrote)?
A reddit user profile api call returns the canonical author object; profile/posts returns that account's submissions. author.id is the bare username — the same handle the sibling reads take. No remap.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/profile?handle=spez"import os
import requests
BASE = "https://www.socialcrawl.dev"
r = requests.get(
f"{BASE}/v1/reddit/profile",
params={"handle": "spez"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
r.raise_for_status()
payload = r.json()
author = payload["data"]["author"]
print(author["id"], author["likes_count"], payload.get("credits_used"))
# spez, 940980, 1This harvest (request_id req-o6ZvUhjCKniBuhgN, cached=false):
| Field | Live 2026-09-08 |
|---|---|
author.id / author.username | spez |
author.display_name | t2_1w72 (Reddit fullname) |
author.bio | Reddit CEO |
author.joined_at | 2005-06-06T04:00:00.000000+0000 |
author.likes_count (total karma) | 940,980 |
ext.post_karma / ext.comment_karma / ext.awardee_karma | 184,487 / 756,493 / 0 (sum equals likes_count) |
ext.trophy_count | 52 |
author.followers | null (Reddit publishes no public follower count) |
author.avatar_url | populated |
| credits_used | 1 |
Trimmed author object under the unified schema:
{
"id": "spez",
"username": "spez",
"display_name": "t2_1w72",
"bio": "Reddit CEO",
"followers": null,
"likes_count": 940980,
"joined_at": "2005-06-06T04:00:00.000000+0000",
"ext": {
"post_karma": 184487,
"comment_karma": 756493,
"awardee_karma": 0,
"trophy_count": 52
}
}A reddit user api that only prints link_karma stops at the card. The karma split is the rest of the profile.
The reddit account posts api — reddit user post search against a known username — uses the same handle:
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/profile/posts?handle=spez"GET /v1/reddit/profile/posts?handle=spez returned 23 posts, dropped=0, has_more=false, next_cursor=null, 1 credit (request_id req-PyKS7G1J9RUkMenv). Newest 2026-08-05 (“Modernizing Reddit’s infrastructure with you”, 331 likes / 445 comments). Oldest on the page 2015-07-11. ext.subreddit was populated on 16/23, null on 7/23, empty string on 0/23. Null means the post sat on the user’s profile page, not that the field is broken.
Row 0 (profile-page post):
{
"id": "1vgbkge",
"url": "https://www.reddit.com/user/spez/comments/1vgbkge/modernizing_reddits_infrastructure_with_you/",
"author": { "username": "spez" },
"engagement": { "likes": 331, "comments": 445, "shares": null },
"published_at": "2026-08-05T16:03:56.264Z",
"ext": {
"subreddit": null,
"title": "Modernizing Reddit’s infrastructure with you"
}
}Print len(items) and the pagination block. has_more=false is what this call returned. It is not a page-size constant, and it is not “every post spez has ever made.”
reddit.com/dev/api names user methods; PRAW's quick start prints name + link_karma and never loops redditor.submissions. Neither prints credits_used=1.
Can you search Reddit comment text without opening threads?
A reddit comment search api searches comment text. You don't need a post id. Official GET /search does not list a comment-index method; trees are GET /comments/{article} plus morechildren. Thread expansion (/v1/reddit/post/comments) is a different post. This is a reddit comments api for the index. To scrape reddit comments yourself, follow a separate walkthrough.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/search/comments?query=best+mechanical+keyboard"r = requests.get(
f"{BASE}/v1/reddit/search/comments",
params={"query": "best mechanical keyboard"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
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"))
# 22, 1, TrueTopical query=best+mechanical+keyboard returned 22 comments, 1 credit, has_more=true (request_id req-6sDLTdBCzFkIGXUR). Sample row 0: ext.subreddit=GamingLaptops, post title “Money is not object: best gaming laptop”, ext.subreddit_subscribers=402826. Each hit carries the parent post inline (ext.post_title, ext.subreddit, ext.post_score), so a bare comment body is readable. Open the permalink at comment.url. Do not paste ext.post_url — on this sample it embedded a t3_ fullname in the path.
Same endpoint, author operator:
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/search/comments?query=author:spez"query=author:spez returned 14 comments, 1 credit, has_more=true (request_id req-DvUIutwnvTUYxMKX). Newest on the page 2026-07-30, oldest 2026-06-04. parent_id null on all 14. Dates are not newest-first (July cluster, then June). All 14 authors are spez.
{
"id": "p0ri6c3",
"url": "https://www.reddit.com/r/RDDT/comments/1vb4oe8/comment/p0ri6c3/",
"parent_id": null,
"text": "Thank you for your support of RDDT…",
"author": { "username": "spez" },
"engagement": { "likes": 15 },
"published_at": "2026-07-30T22:37:36.676Z",
"ext": {
"post_title": "Reddit Announces Q2’26 Earnings (plus AMA!)",
"subreddit": "RDDT",
"subreddit_subscribers": 12585
}
}Same endpoint, Hangul query: query=기계식 키보드 returned 4 comments, 1 credit, has_more=false (request_id req-H7R0Vm7C6Q8szT2Z), all ext.subreddit=Mogong. Comment search can also return loosely related hits rather than empty — judge relevance on the rows, not the count.
This 14-row author: page is a relevance subset. History is a different read.
How do you find a subreddit when you don't know its name?
Until now, you needed the community's name to read it. Reddit subreddit search is the topic-to-name hop — the API version of a subreddit finder, not a consumer app. A reddit user search still needs the handle; this hop is for the community.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/subreddits/search?query=machine+learning"page1 = requests.get(
f"{BASE}/v1/reddit/subreddits/search",
params={"query": "machine learning"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
page1.raise_for_status()
p1 = page1.json()
print(len(p1["data"]["items"]), p1.get("credits_used"))
# 25, 1
cursor = (p1.get("pagination") or {}).get("next_cursor")
page2 = requests.get(
f"{BASE}/v1/reddit/subreddits/search",
params={"query": "machine learning", "cursor": cursor},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
p2 = page2.json()
ids1 = {row["author"]["id"] for row in p1["data"]["items"]}
ids2 = [row["author"]["id"] for row in p2["data"]["items"]]
print(len(ids2), len(ids1.intersection(ids2)))
# 25, 5GET /v1/reddit/subreddits/search?query=machine+learning returned 25 communities, 1 credit, has_more=true (request_id req-q8qaH8RShZp1qwQI). Rank 1: author.id=MachineLearning, 3,070,326 subscribers, url https://www.reddit.com/r/MachineLearning. author.id is the bare community name — the same string /v1/reddit/subreddit and /v1/reddit/subreddit/details take. No remap.
| # | author.id | subscribers |
|---|---|---|
| 1 | MachineLearning | 3,070,326 |
| 2 | learnmachinelearning | 676,458 |
| 3 | machinelearningnews | 151,586 |
| 4 | MLQuestions | 113,445 |
| 5 | ResearchML | 22,407 |
ext.weekly_active_users / weekly_contributions / rules_text / language are null on these discovery rows — those fill on /v1/reddit/subreddit/details. Do not treat a discovery row as a full community card.
Page 2 of the same query also returned 25, 1 credit, has_more=true (req-AKrr3z8fPrDzMtOZ). 5 of those 25 ids were already on page 1: Learning, AIJobs, learndatascience, elearning, machinetranslation. Page 2 otherwise opened with science, technology, datascience. De-duplicate on author.id before treating a walk as 50 communities. This is one query, two pages — not a published repeat rate.
The official catalog lists GET /subreddits/search; PRAW's quick start only does reddit.subreddit("known_name"). Neither prints 25 / 1 credit or the repeat-row caveat.
What does Reddit media search return for 1 credit?
A reddit media search api returns image/video-scoped posts — same post schema, not a new object type. The official catalog has no named “search media” method; media is a filter on GET /search.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/search/media?query=mechanical+keyboard+build"r = requests.get(
f"{BASE}/v1/reddit/search/media",
params={"query": "mechanical keyboard build"},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
payload = r.json()
items = payload["data"]["items"]
print(len(items), payload.get("credits_used"))
# 25, 1GET /v1/reddit/search/media?query=mechanical+keyboard+build returned 25 posts, 1 credit, has_more=true, dropped=0 (request_id req-MkoYw012z9QhfH0m). content.thumbnail_url populated on 25/25. content.media_urls type on this page: string on 24, null on 1, array on 0. Callers that assume a list should wrap a string.
Row 0 (the null case): title “First Mechanical keyboard build”, ext.subreddit=MechanicalKeyboards, YouTube link in the body, thumbnail populated, media_urls=null, 4 likes / 4 comments.
Row 1 (string case):
{
"id": "1thgcsn",
"url": "https://www.reddit.com/r/PHMechanicalKeyboard/comments/1thgcsn/first_custom_mechanical_keyboard_deep_and_thocky/",
"content": {
"media_urls": "https://packaged-media.redd.it/fyj7uj0dz12h1/dl/m2-res_640p.mp4",
"thumbnail_url": "https://external-preview.redd.it/…",
"duration_seconds": 31
},
"ext": {
"subreddit": "PHMechanicalKeyboard",
"title": "First Custom Mechanical Keyboard (Deep and Thocky)"
}
}Do not describe media_urls as an array from this evidence.
When is comment history worth 2 credits a comment?
A reddit comment history api reads the account’s own listing, newest first, with real parent ids. The 1-credit author search above is a relevance sample of the search index. Same handle, same hour, two jobs.
/v1/reddit/search/comments?query=author:spez | /v1/reddit/profile/comments?handle=spez&limit=5 | |
|---|---|---|
| What it reads | Comment search index (relevance-ranked subset) | The account’s own listing, newest first |
len(items) this call | 14 | 5 |
| credits_used | 1 | 10 (2 per comment) |
has_more | true (pages with cursor) | false (no cursor; raise limit to go deeper) |
| Newest on this response | 2026-07-30T22:39:07Z | 2026-08-05T18:31:50Z |
| Oldest on this response | 2026-06-04T00:24:28Z | 2026-08-05T16:24:51Z |
| Order | Not chronological | Newest first |
parent_id | null on all 14 | populated on all 5 |
| Includes the 5 Aug comments? | No | Yes — all five |
Run search/comments?query=author:username (1 credit) first. Pay for history when you need the listing, in date order, with real parent ids. The history page’s five comments are newer than every row on the 1-credit search page. Search has_more=true, so this is not “search stopped at 14 forever.” The first search page is a relevance subset that did not contain the account's newest comments.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/reddit/profile/comments?handle=spez&limit=5"r = requests.get(
f"{BASE}/v1/reddit/profile/comments",
params={"handle": "spez", "limit": 5},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=30,
)
payload = r.json()
items = payload["data"]["items"]
print(len(items), payload.get("credits_used"))
# 5, 10limit is a depth control (1–100), not a page size. No cursor. credits_used == 2 × items.length held on this call (5 × 2 = 10). Raising limit reaches further back in one call, at 2 credits per comment returned. Keep limit small; this harvest used 5.
All five history rows sit under post 1vgbkge, all ext.is_submitter=true, all ext.subreddit=u_spez, window ~2 hours on 5 August (request_id req-8XgsIGNYx7uPAv6r). Row 2: “If we replace every line of code but the output is the same, is it still old Reddit?”
How do you start using this?
Get an API key. The free pack needs no card — the current credit amount lives on /pricing. The first billed call is the profile read above, then profile/posts. The reddit api python path is requests with one API key in x-api-key. Print len(data["data"]["items"]) and credits_used on list endpoints; print data["data"]["author"] on the profile card.
import os
import requests
BASE = "https://www.socialcrawl.dev"
headers = {"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]}
profile = requests.get(
f"{BASE}/v1/reddit/profile",
params={"handle": "spez"},
headers=headers,
timeout=30,
)
profile.raise_for_status()
card = profile.json()
print(card["data"]["author"]["id"], card.get("credits_used"))
posts = requests.get(
f"{BASE}/v1/reddit/profile/posts",
params={"handle": "spez"},
headers=headers,
timeout=30,
)
body = posts.json()
print(len(body["data"]["items"]), body.get("credits_used"))
# spez 1
# 23 1See your data in the visual explorer before writing a single line. Live catalogue: /docs/reddit. Platform hub: /platforms/reddit. Check GET /v1/credits/balance first. This harvest billed 18 credits on 8 September 2026: the six new reads (history at limit=5 for 10), a second subreddit-search page, and two extra comment-search queries. The six-endpoint spine alone is 15. Keep history limit small.
Frequently asked questions
How many credits does Reddit comment history cost?
GET /v1/reddit/profile/comments is metered at 2 credits per comment returned. This harvest: handle=spez&limit=5 returned 5 comments and billed 10. limit is a depth control (1–100), not a page size. The other five new reads each billed 1 credit on 8 September 2026. Start with search/comments?query=author:username at 1 credit.
Do I need Reddit OAuth to call a Reddit profile API?
No. These Reddit calls use x-api-key. You don't register a Reddit OAuth app. Official Data API access does require OAuth — a rate-limit and contract story in the Reddit Data API Wiki, expanded in the official Reddit API landscape and in Reddit OAuth and API keys.
How do I tell a missing Reddit user from a bad handle?
Call GET /v1/reddit/profile. A 23-character handle that fails format rules returned HTTP 400 (INVALID_REQUEST — “Invalid handle for reddit: must match platform handle rules.”) and 0 credits (thisuserdoesnotexistzzz, req-VGTNIIRe1iw9DYCc). A well-formed handle that does not exist returned HTTP 404 (RESOURCE_NOT_FOUND — “This Reddit account is suspended, deleted, or does not exist. Your credits have been refunded.”) and 0 credits (zzznobodyexists99, req-2X3zgAJAHfzxkcZe). Do not collapse 400 and 404. This harvest did not probe a real account that has never commented.
How does pagination work on these Reddit endpoints?
search/comments, subreddits/search, and search/media page with cursor at 1 credit a page (has_more / next_cursor). profile/comments does not page — raise limit (1–100). profile/posts this run returned 23 with has_more=false and next_cursor=null. On subreddits/search, de-duplicate on author.id: this walk repeated 5 of 25 ids on page 2.
Is author:username comment search the same as comment history?
No. search/comments?query=author:spez billed 1 credit for 14 relevance-ranked rows (newest on the page 30 July, parent_id null, has_more=true). profile/comments?limit=5 billed 10 credits for 5 chronological rows (all 5 August, real parent_id, no cursor). History’s comments are newer than every row on the search page. Search samples the index. Use search first.
The live catalogue is /docs/reddit. Reproduce the harvest curls; keep history limit small.
Related posts
Google Trends API: Empty Searches Cost 0 Credits
Empty Google Trends API searches now return 404 with 0 credits charged. Live production curls cover Trends empties, News ranks, and app filter refusals.
Google Trends API Python: ~4.6s Typical (Was ~9s)
A Google Trends API Python GET is ~4.6s typical (was ~9s on 22 billed calls). Live interest-over-time and related queries, same 5 credits, 2026-09-08 UTC.
Instagram API: About is back, 1 credit, named 404s
/v1/instagram/profile/about is back: United States, February 2012, 1 credit. Wrong Instagram API paths return did_you_mean at 0 credits. Checked 2026-09-08.
