Read Reddit posts and comment threads without a Reddit account
The Reddit API returns subreddit posts, comments, search and user data as clean JSON.
11 active endpoints, on 1, 2, 3 and 5 credit tiers.
- POST/reddit/v1/subreddit_posts
- POST/reddit/v1/multi_subreddit_posts
- POST/reddit/v1/post_comments
- POST/reddit/v1/search
- POST/reddit/v1/user
- POST/reddit/v1/subreddit_about
- POST/reddit/v1/communities
- +4 more
What Reddit endpoints does ReefAPI ship?
11 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Reddit API
3 of 11 endpoints, ready to run
The posts in one subreddit, body text included on every row. sort=new is the monitoring surface; sort=top with a time window is the archive.
{ "ok": true, "meta": { "api": "reddit", "endpoint": "subreddit_posts", "mode": "live", "latency_ms": 2568.7, "record_count": 25, "cache_hit": false, "completeness_pct": 100 }, "data": { "posts": [ { "id": "1vzq6rc", "fullname": "t3_1vzq6rc", "title": "Google testing a new search CAPTCHA?", "subreddit": "webscraping", "score": 14, "upvote_ratio": 0.89, "num_comments": 4, "created_utc": 1787826624, "url": "https://i.redd.it/gqnnwo0bawlh1.jpeg", "permalink": "https://www.reddit.com/r/webscraping/comments/1vzq6rc/google_testing_a_new_search_captcha/", "selftext": "Ran into this new CAPTCHA in Google Search today for the first time. All you have to do is wait a few seconds until the button becomes active. Not sure what it’s actually checking yet, or if it’s just an intentional delay to filter out bots.\n\n", "flair": null, "over_18": false, "spoiler": false, "stickied": false, "locked": false, "is_self": false, "is_video": false, "domain": "i.redd.it", "thumbnail": "https://preview.redd.it/gqnnwo0bawlh1.jpeg?width=140&height=64&auto=webp&s=ce41d753ca2a16a26ca3f3801051c2d93e2b60ad", "num_crossposts": 0, "total_awards_received": 0, "edited": false }, { "id": "1vzho1h", "fullname": "t3_1vzho1h", "title": "Rust DataDome fetcher + deobfuscator + VM disassembler +slider/tags", "subreddit": "webscraping", "score": 33, "upvote_ratio": 0.96, "num_comments": 13, "created_utc": 1787798324, "url": "https://github.com/drakoarmy/datadome-rs", "permalink": "https://www.reddit.com/r/webscraping/comments/1vzho1h/rust_datadome_fetcher_deobfuscator_vm/", "selftext": "", "flair": null, "over_18": false, "spoiler": false, "stickied": false, "locked": false, "is_self": false, "is_video": false, "domain": "github.com", "thumbnail": "https://external-preview.redd.it/cg21HDoH_nY1xtbbafBhgTOOh03G93yiZd8QkHypviw.png?width=140&height=70&auto=webp&s=df35ce1876a3f7722a84c72c1d3b5dae32e2505e", "num_crossposts": 0, "total_awards_received": 0, "edited": false }, { "id": "1vzem8x", "fullname": "t3_1vzem8x", "title": "Is there alternative to scrape images from imago.images.com?", "subreddit": "webscraping", "score": 3, "upvote_ratio": 1, "num_comments": 4, "created_utc": 1787790113, "url": "https://www.reddit.com/r/webscraping/comments/1vzem8x/is_there_alternative_to_scrape_images_from/", "permalink": "https://www.reddit.com/r/webscraping/comments/1vzem8x/is_there_alternative_to_scrape_images_from/", "selftext": "I used to scrape images via Smartframe and it work just fine, but more recently they changed something, perhaps turn off the whole Smartframe thing, idk. Do anyone figured out this? Perhaps they changed the Customer-ID thingy.", "flair": "Getting started 🌱", "over_18": false, "spoiler": false, "stickied": false, "locked": false, "is_self": true, "is_video": false, "domain": "self.webscraping", "thumbnail": null, "num_crossposts": 0, "total_awards_received": 0, "edited": false } ], "after": "t3_1vp886q", "before": null, "count": 25 } }
How the Reddit API works
Reddit is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 184 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Watch a list of subreddits, then open the thread that matters
Monitoring Reddit is one call, not one call per community, and reading a thread properly is two. This is the loop, with the numbers measured while writing it.
{"subreddits": "webscraping,python,rust", "sort": "new", "limit": 60}Sixty rows merged newest-first across three communities in 2.6 seconds. The response hands back newest_utc — keep it.
{"subreddits": "...", "sort": "new", "since_utc": 1787835755}The same call in polling mode, with the newest_utc you kept, returns only what has appeared since. That is the whole monitoring loop.
{"post_id": "<id from the feed>", "limit": 500}A 1,177-comment thread returned 81 top-level comments plus 500 collapsed more_ids in 3.5 seconds.
{"post_id": "...", "more_ids": "<100 of them>"}Ninety-four more comments in about a second. Repeat until more_ids runs out and you hold the whole tree.
A feed you can poll every minute and a complete thread when one is worth reading, with no account of yours involved in either.
curl -X POST https://api.reefapi.com/reddit/v1/subreddit_posts \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"subreddit":"python","limit":10}'{
"ok": true,
"data": { … },
"meta": {
"api": "reddit",
"endpoint": "subreddit_posts",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}Reddit fullname prefixes, and which action hands you which one
Reddit gives every object a type-prefixed "fullname" alongside a bare base36 id, and the two are not interchangeable when you pass them back in. This table lists the prefixes that actually appeared in measured responses and the field each one arrives in. It also records what happens when you send a bad enum value versus a value that simply matches nothing, because those two failures look completely different.
| Prefix or field | What it identifies | Measured example |
|---|---|---|
| t3_ | A post. Every post row carries both id and fullname, and a comment's link_id points at it. | r/Python returned id 1vy0ywg with fullname t3_1vy0ywg |
| t1_ | A comment. Comment rows also carry parent_id, which is t3_ for a top-level comment and t1_ for a reply. | t1_fgs7erl with parent_id t3_f08dxb and link_id t3_f08dxb |
| t5_ | A subreddit. Only subreddit_about returns it. | r/Python returned fullname t5_2qh0y, subscribers 1507579 |
| user id | Base36 and unprefixed in the payload. There is no t2_ anywhere in the user record. | user with kind=about for spez returned id 1w72 |
| post_id parameter | Takes the bare post id, not the fullname. A full reddit URL is accepted too. | post_comments with post_id f08dxb resolved the AskReddit thread |
| created_utc | Unix seconds as a float, UTC, on posts, comments and subreddits alike. | 1581069212.0 on the post, 1201230879.0 for the r/Python subreddit itself |
| Bad enum value | Rejected before any fetch. INVALID_PARAM comes back with detail.param and detail.allowed listing the real vocabulary. | sort=bogus returned INVALID_PARAM in 1.9 ms |
| A flair that matches nothing | Not rejected. ok stays true, posts[] is empty, completeness_pct is 0.0, and pagination still offers a next_cursor. | flair=NoSuchFlairXyz on r/Python returned 0 posts with has_more true |
time only does anything when sort is top or controversial. Passing time=week alongside sort=hot is accepted and silently has no effect, so a "past week" feed that looks wrong is usually a sort that was never top in the first place.
How deep Reddit goes, what a burst does, and where the author disappears
Measured on 2026-08-28 against r/webscraping, a ten-community watchlist and a 1,177-comment thread. Two of these lines go against us.
You send a ReefAPI key and a subreddit name. There is no Reddit login, no registered OAuth client, no refresh token and no session of yours anywhere in the path — so there is no account of yours that can be rate-limited or banned for reading. On the rate-limit half of the question we ran the measurement rather than reassuring you: twelve different subreddit pulls, three at a time, all twelve answered between 1.1 and 2.6 seconds and not one came back throttled. Your own key's quota is the only ceiling you are under, and a failed call is not charged.
At 100 rows a page: page 1 covered 2026-07-09 to the moment it ran, page 5 reached back to 2026-01-27, and page 10 returned 87 rows with has_more false and a null next_cursor — the end of what the source will serve for that community. Eleven months on one query.
Against us. Asking for page 20 of the same subreddit returned the identical 87 rows page 10 had returned — all 87 ids matched — rather than an empty result. A loop that stops on a zero row count will never stop. Stop on has_more, which was correctly false on both.
At the default of one page per community the merge is right: three subreddits returned 60 rows newest-first in 2.6 seconds, and ten returned 100 rows drawn from nine of them with the newest post minutes old. Raising max_pages to three on that same ten-community call inverted it — the newest row was ten days old and only two of the ten were represented at all. Poll often at the default and move forward with since_utc; do not try to reach deeper inside a single poll.
Against us. Fifty comment-search results for one phrase carried author null on 50 of 50, while body, score, subreddit, permalink, the parent post's title and the timestamp were filled on all fifty. Posts and thread comments do carry the author — 80 of 81 on the thread we opened, the missing one a deleted account. If you need the author of a search hit, resolve its permalink through post_comments.
Those fifty comment hits spanned 2021-12-02 to the morning the call ran. Posts and comments both carry created_utc as a unix timestamp, so any row can be aged without a second lookup, and after_utc and before_utc narrow the window at the source.
post_comments returns the visible tree to the depth you ask for, from one level to fifty, plus the ids of every collapsed more node; load_more_comments expands a hundred of those ids per call. On the thread we opened that was 81 comments plus 500 ids in 3.5 seconds, then 94 more comments in about one. Nothing is silently dropped — the ids you have not expanded are listed in the response.
trending reads r/popular or r/all site-wide, communities searches subreddits by keyword and returns each one's subscriber count and over-18 flag, and subreddit_about returns subscribers, description and creation date for a single community. Fifty communities for one keyword came back in two seconds.
Public posts, public comments, public community metadata and public profile pages. Not private messages, not modmail, not moderator queues. The engine is explicit about that boundary rather than guessing at it: the extras action returns a community's rules and wiki, and states that the moderator list is mod-only on Reddit and not available to a logged-out reader.
What people build with Reddit
The jobs this data is most often used for.
endpoints
credits per call
Market researchers call subreddit_posts and search to track what communities say about a product.
RAG pipelines pull post_comments to ground an AI assistant in real Reddit discussion.
Social-listening tools use trending and user to monitor rising topics and influential accounts.
What Reddit data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 184 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/reddit/v1/subreddit_posts \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"subreddit":"python","limit":10}'import requests
r = requests.post(
"https://api.reefapi.com/reddit/v1/subreddit_posts",
headers={"x-api-key": REEF_KEY},
json={
"subreddit": "python",
"limit": 10
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Reddit.
Get a free key →What is the difference between id and fullname, and which one do I store?▾
id is the bare base36 key and fullname is the same key with a type prefix. A measured r/Python post came back as id 1vy0ywg and fullname t3_1vy0ywg; a comment on another thread as id fgs7erl and fullname t1_fgs7erl. Store the fullname if you are keeping posts and comments in one table, because the bare ids share a namespace and a comment id can collide with a post id. Pass the bare id back in: post_comments takes post_id f08dxb, not t3_f08dxb.
Is score the real number of upvotes?▾
No. Reddit deliberately fuzzes score, so it is an approximation and two reads seconds apart can disagree by a few points on a busy thread. upvote_ratio is the more stable signal and it sits right next to score on every post: a measured r/rust post had score 3 with upvote_ratio 1.0, and another had score 0 with upvote_ratio 0.33, which tells you far more about reception than the 0 does. For trend work, track the pair rather than score alone.
Does an empty selftext mean it is a link post?▾
No, and this one trips people up. A measured AskReddit post had is_self true and selftext "" because it is a title-only question, while a measured r/rust post had is_self false and domain i.redd.it (an image link) yet carried 573 characters of selftext underneath it. Classify a post from is_self and domain, and treat selftext as a body that may or may not be present in either case.
What do [deleted] and [removed] mean, and are they the same thing?▾
They are different, and a comment can be in three states. Inside a single measured thread, one comment came back with author "[deleted]" and body "[removed]" (a moderator removal), another with author "[deleted]" and body "[deleted]" (the user deleted it), and a third with author "[deleted]" but its body fully intact (the account went away, the comment stayed). These are literal string values, not nulls, so a filter on author != null will not catch any of them.
post_comments gave me 10 comments on a thread with 13,297. How do I get the rest?▾
The tree comes back with explicit stubs rather than silently truncating. At the top level the response carries more_ids and has_more (a measured AskReddit thread returned 241 ids there), and inside replies[] you get objects shaped {more_children: 65, more_ids: [...]} wherever Reddit collapsed a branch. Feed those ids into load_more_comments to expand a branch. A stub with more_children 0 and an empty more_ids is a leaf, not an error.
Which source should I use, and what does auto pick?▾
auto is the default and chooses between the live site and the archives based on what you asked for. Set source=live when you specifically need the newest posts and the live-only features, because flair filtering, page-based deep paging and the cursor in meta.pagination.next_cursor all apply to the live source; the archive sources page by after_utc and before_utc instead. Reach for the archives when you are pulling old threads, where coverage beats freshness.
How does deep paging work across the post actions?▾
Two ways, and they do not mix. page (1 to 20) chains the cursors server-side, so page 2 really is the batch after page 1 without you holding any state. Or take meta.pagination.next_cursor from the previous response and send it back as cursor. A measured r/Python top-of-week call returned next_cursor t3_1vxrna7 with has_more true, which is simply the fullname of the last row it handed you. Both stop at Reddit's own listing depth, not at a limit of ours.
Why does searching comments return less per row than post_comments does?▾
Because search with type=comment reads Reddit's live comment index, which is a discovery surface rather than a full record. Measured rows carry id, fullname, body, subreddit, permalink, link_id and post_title, but author, score, parent_id and depth all come back null. Treat it as a way to find which threads to open, then resolve the detail: post_comments returns author and score for every comment in a thread, and user with kind=comments returns them per account (a measured spez comment came back with author spez, score 8 and parent_id t1_p1wd2fi).
What is the Reddit API?▾
Reddit API is a ReefAPI endpoint group for posts, comments, subreddits and search. It returns live JSON through POST requests under /reddit/v1.
Is the Reddit API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Reddit calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Reddit login or account?▾
No login to Reddit is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Reddit data?▾
The page example is captured from a live subreddit_posts call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Reddit API use?▾
Reddit actions currently cost 1-5 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Reddit from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call reddit actions with the same key, credit pool and JSON envelope used by normal REST requests.
10 Social Media APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Reddit, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.