Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/threadsnoop-com:threadsnoop-com-posts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: ThreadSnoop Reddit Read Posts API
version: 1.0.0
description: 'Read-only access to Reddit: posts, comments, comment trees, subreddit search, subreddit rules, and user profiles. Pay-as-you-go, 1 credit = 1 request, 100 free Reddit searches on signup. No writes, votes, DMs, or auth-ed Reddit actions — read-only, permanently. See https://threadsnoop.com/docs for the human-readable guide.'
contact:
email: hello@threadsnoop.com
servers:
- url: https://api.threadsnoop.com
security:
- ApiKeyHeader: []
- BearerAuth: []
tags:
- name: Posts
paths:
/v1/posts:
get:
operationId: listPosts
summary: List or fetch Reddit posts
description: 'Two modes on one endpoint. Listing mode: pass `subreddit` and/or `author` (at least one required) to page through posts, newest-first by default. Batch mode: pass `ids` (comma-separated post ids, capped at 100) to fetch specific posts by id in a single request — all other listing params (`after`, `before`, `sort`, `q`) are ignored in this mode, and the response has `cursor: null` / `has_more: false` since there is no next page for a fixed id list. 1 credit per request in either mode (batch mode is 1 upstream call regardless of how many ids you ask for).'
parameters:
- $ref: '#/components/parameters/Subreddit'
- $ref: '#/components/parameters/Author'
- name: ids
in: query
description: Comma-separated post ids to fetch directly (batch mode). Truncated to the first 100 if more are given. When present, `subreddit`/`author`/`after`/`before`/`sort`/`q` are ignored. If even one id in the list is invalid or malformed, the whole call returns a 400 (credit refunded) rather than silently skipping the bad id — verify ids came from a real search result first.
schema:
type: string
example: 1abcxyz,1defghi
- $ref: '#/components/parameters/After'
- $ref: '#/components/parameters/Before'
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Sort'
- $ref: '#/components/parameters/Fields'
- $ref: '#/components/parameters/Q'
responses:
'200':
description: A page of posts.
content:
application/json:
schema:
$ref: '#/components/schemas/PostListEnvelope'
example:
data:
- id: 1abcxyz
title: Anyone know a tool that watches Reddit for me?
selftext: Tired of manually searching every day...
author: some_founder
created_utc: 1753000000
subreddit: SaaS
permalink: /r/SaaS/comments/1abcxyz/anyone_know_a_tool_that_watches_reddit_for_me/
url: https://www.reddit.com/r/SaaS/comments/1abcxyz/anyone_know_a_tool_that_watches_reddit_for_me/
num_comments: 4
score: 12
hide_score: false
_threadsnoop:
cursor: 1753000000
has_more: true
credits_used: 1
credits_remaining: 332
headers:
x-credits-used:
$ref: '#/components/headers/CreditsUsed'
x-credits-remaining:
$ref: '#/components/headers/CreditsRemaining'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'429':
$ref: '#/components/responses/RateLimited'
'502':
$ref: '#/components/responses/UpstreamUnavailable'
tags:
- Posts
components:
parameters:
Fields:
name: fields
in: query
description: 'Comma-separated field allowlist forwarded upstream. Confirmed-safe for posts: id,title,selftext,author,created_utc,subreddit,score,num_comments,url,over_18,link_flair_text,spoiler. Confirmed-safe for comments: id,body,author,created_utc,subreddit,link_id,parent_id,score. This is NOT the full Reddit object schema — many real fields are rejected upstream (e.g. permalink, hide_score, domain, ups, stickied) with a 400 naming exactly which field was invalid; if unsure, omit fields entirely and read the full untrimmed object instead of guessing names.'
schema:
type: string
After:
name: after
in: query
description: Lower bound on created_utc. Accepts an epoch-seconds integer or a relative form like `7d`, passed through as-is.
schema:
type: string
example: 7d
Q:
name: q
in: query
description: 'Client-side exact-phrase filter (with basic plural flexibility), applied ONLY to the single page this call fetches (limit, default 25, max 100) — not a search across the whole after/before window. A page with zero matches does NOT mean no matches exist in your date range: cursor/has_more always reflect the RAW page, not the filtered subset, so check has_more and keep paginating with the returned cursor. For an active subreddit one page can span just minutes, so scanning several days for a specific phrase often takes many calls; every page costs 1 credit whether it matched or not. See the pagination guide.'
schema:
type: string
Limit:
name: limit
in: query
description: Page size.
schema:
type: integer
minimum: 1
maximum: 100
default: 25
Author:
name: author
in: query
description: Reddit username (without u/). At least one of subreddit/author/ids is required.
schema:
type: string
Before:
name: before
in: query
description: Upper bound on created_utc. Same accepted forms as `after`.
schema:
type: string
Subreddit:
name: subreddit
in: query
description: Subreddit name (without r/). At least one of subreddit/author/ids is required.
schema:
type: string
example: SaaS
Sort:
name: sort
in: query
description: Sort order by created_utc.
schema:
type: string
enum:
- asc
- desc
default: desc
responses:
Unauthorized:
description: Missing, invalid, or revoked API key. Not charged (no key to attribute usage to).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: invalid or revoked api key
PaymentRequired:
description: Insufficient credit balance. Not charged (the debit is the balance check — it never went through).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: insufficient credits — top up at https://threadsnoop.com/api
RateLimited:
description: 'Rate limit exceeded — either your key''s own 2 req/s (burst 10) limit, or the shared global upstream ceiling (marked by the `x-ratelimit-scope: global` header, present only for the global case). Not charged.'
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
x-ratelimit-scope:
description: Present and set to `global` only when the shared upstream ceiling (not your per-key limit) was hit.
schema:
type: string
enum:
- global
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: rate limit exceeded
BadRequest:
description: Invalid or missing parameters. Not charged.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: at least one of subreddit, author, or ids is required
UpstreamUnavailable:
description: The upstream data source was unreachable or errored after the connector's retry policy was exhausted. Any credit debited for this request is automatically refunded. When the upstream is busy, a Retry-After header gives the number of seconds to wait before retrying.
headers:
Retry-After:
description: Seconds to wait before retrying. Present when the upstream reported it was busy.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: upstream temporarily unavailable — credit refunded
headers:
CreditsUsed:
description: Credits charged for this request (0 or 1).
schema:
type: integer
CreditsRemaining:
description: Balance remaining after this request.
schema:
type: integer
schemas:
PostListEnvelope:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Post'
_threadsnoop:
$ref: '#/components/schemas/Envelope'
Envelope:
type: object
properties:
cursor:
type:
- integer
- 'null'
description: created_utc of the last row in this page (raw page, pre-filter if q= was used). Pass as `after` (sort=asc) or `before` (sort=desc) to fetch the next page. Null when the page was empty or the endpoint isn't paginated.
has_more:
type: boolean
credits_used:
type: integer
credits_remaining:
type: integer
required:
- credits_used
- credits_remaining
Post:
type: object
description: Full Reddit post object, untrimmed unless you pass `fields=`. The properties below are the ones ThreadSnoop's connector reads directly; additional standard Reddit post fields pass through unmodified.
properties:
id:
type: string
title:
type: string
selftext:
type: string
author:
type: string
created_utc:
type: integer
subreddit:
type: string
permalink:
type: string
description: Relative path on reddit.com. Prepend https://www.reddit.com for a clickable URL.
url:
type: string
description: Absolute URL — the external link for a link post, or the same permalink (fully qualified) for a self post.
num_comments:
type: integer
description: 0 during the ~36h hide_score blackout on fresh posts — use /v1/comments/tree for a real count.
score:
type: integer
description: Pinned at 1 during the ~36h hide_score blackout on fresh posts.
hide_score:
type: boolean
additionalProperties: true
Error:
type: object
required:
- error
properties:
error:
type: string
securitySchemes:
ApiKeyHeader:
type: apiKey
in: header
name: x-api-key
BearerAuth:
type: http
scheme: bearer
description: 'Authorization: Bearer <your key>. Equivalent to x-api-key; either header works.'