{"openapi":"3.1.0","info":{"title":"threadapi","version":"1.0.0","summary":"Reddit posts, comment trees, subreddit listings and search, as JSON or Markdown.","description":"threadapi reads public Reddit for programs and AI agents.\n\n**Authentication.** Send your API key as `Authorization: Bearer <key>` (or `X-Api-Key: <key>`).\nCreate keys in the dashboard at https://threadapi.dev/app.\n\n**Credits.** A post costs 1 credit for up to 500 comments, and 1 more for each further 100\ncomments returned. Subreddit listings and searches cost 1 credit. Failed requests are free.\nEvery successful response carries `X-Credits-Used`.\n\n**Errors** share one shape: `{\"error\": {\"code\", \"message\", \"retryable\"}}`. Retry a request only\nwhen `retryable` is true, after the `Retry-After` header if there is one.\n","contact":{"name":"threadapi","url":"https://threadapi.dev","email":"support@threadapi.dev"}},"servers":[{"url":"https://api.threadapi.dev"}],"security":[{"bearer":[]},{"apiKey":[]}],"tags":[{"name":"Reddit"}],"paths":{"/v1/reddit/post":{"get":{"operationId":"getPost","tags":["Reddit"],"summary":"Get a post and its comments","description":"Returns the post, its comment tree (up to `max_comments`, widest first: all top-level\ncomments before replies), and a digest: the original poster's replies, the most upvoted\ncomments, and the ones Reddit marks controversial. A comment permalink in `url`, or\n`comment`, focuses the response on that comment.\n\nPricing: 1 credit for up to 500 comments, plus 1 per further 100 returned. `max_comments`\ndefaults to 200, which always costs 1 credit. If the balance covers fewer pages than asked\nfor, the response holds what it covers and `meta.limited_by_balance` is true.\n","parameters":[{"name":"url","in":"query","description":"A reddit.com post URL (any subdomain), a redd.it link, a `t3_` fullname or a post ID. Either `url` or `id` is required.","schema":{"type":"string"},"example":"https://www.reddit.com/r/programming/comments/1x144ok/how_big_is_a_git_commit/"},{"name":"id","in":"query","description":"Post ID, the same as `url`.","schema":{"type":"string"},"example":"1x144ok"},{"name":"comment","in":"query","description":"A comment ID to focus on, returning its ancestor chain and direct replies.","schema":{"type":"string"},"example":"pezplxi"},{"name":"context","in":"query","description":"Number of ancestor context levels to include when focused on a comment (0 to 8, default 3).","schema":{"type":"integer","minimum":0,"maximum":8,"default":3}},{"name":"max_comments","in":"query","description":"Most comments to return. 0 returns the post alone.","schema":{"type":"integer","minimum":0,"maximum":2000,"default":200}},{"name":"format","in":"query","description":"`json` (post, graph and meta), `md` (one Markdown document for an LLM) or `graph` (discussion graph and meta only).","schema":{"type":"string","enum":["json","md","graph"],"default":"json"}}],"responses":{"200":{"description":"The post.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Comments-Returned":{"description":"Comments in the response.","schema":{"type":"integer"}},"X-Has-More":{"description":"Whether a larger `max_comments` would return more comments.","schema":{"type":"boolean"}},"X-Cache-Tier":{"description":"Where the post came from. `MISS` and `PARTIAL` mean some of it was fetched from Reddit now.","schema":{"type":"string","enum":["L1_TINYLFU","L2_BADGER","PARTIAL","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostResponse"}},"text/markdown":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/RedditRefused"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/post/duplicates":{"get":{"operationId":"getPostDuplicates","tags":["Reddit"],"summary":"Get duplicate posts and crossposts","description":"Returns other discussions and crossposts for a post (/duplicates/<id>.json). 1 credit per call.","parameters":[{"name":"id","in":"query","description":"Reddit post ID (e.g. `1x1ai6v` or `t3_1x1ai6v`). Required if `url` is not provided.","schema":{"type":"string"},"example":"1x1ai6v"},{"name":"url","in":"query","description":"Reddit post URL. Required if `id` is not provided.","schema":{"type":"string"},"example":"https://www.reddit.com/r/SaaS/comments/1x1ai6v/slug/"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"Duplicate posts.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/RedditRefused"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/things":{"get":{"operationId":"getThings","tags":["Reddit"],"summary":"Look up posts and comments by ID","description":"Looks up to 100 Reddit items (posts and comments) by fullname (`t1_`, `t3_`), bare ID, or URL.\nReturns items in the order requested, noting any missing IDs. 1 credit per call.\n","parameters":[{"name":"ids","in":"query","required":true,"description":"Comma-separated list of up to 100 Reddit IDs or URLs.","schema":{"type":"string"},"example":"t3_1x1ai6v,t1_pezplxi"}],"responses":{"200":{"description":"The requested items.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Cache tier (`MISS`).","schema":{"type":"string","enum":["MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThingsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/subreddit":{"get":{"operationId":"listSubreddit","tags":["Reddit"],"summary":"List a subreddit's posts","description":"1 credit per call.","parameters":[{"name":"sub","in":"query","required":true,"description":"Subreddit name, with or without `r/`.","schema":{"type":"string"},"example":"golang"},{"$ref":"#/components/parameters/SubredditSort"},{"$ref":"#/components/parameters/Time"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"The posts.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/RedditRefused"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/subreddit/about":{"get":{"operationId":"getSubredditAbout","tags":["Reddit"],"summary":"Get subreddit details and rules","description":"Returns subreddit description, subscriber count, settings, and moderation rules. 1 credit per call.","parameters":[{"name":"sub","in":"query","required":true,"description":"Subreddit name, with or without `r/`.","schema":{"type":"string"},"example":"golang"}],"responses":{"200":{"description":"Subreddit metadata and rules.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the data came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subreddit"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/RedditRefused"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/subreddit/comments":{"get":{"operationId":"getSubredditComments","tags":["Reddit"],"summary":"Get recent comments in a subreddit","description":"Returns recent comments from a subreddit (/r/{sub}/comments.json). 1 credit per call.","parameters":[{"name":"sub","in":"query","required":true,"description":"Subreddit name (e.g. `golang` or `r/golang`).","schema":{"type":"string"},"example":"golang"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"Subreddit comments.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentListing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/subreddits":{"get":{"operationId":"getSubreddits","tags":["Reddit"],"summary":"List subreddits","description":"Returns popular or new subreddits (/subreddits/{popular,new}.json). 1 credit per call.","parameters":[{"name":"sort","in":"query","description":"Subreddit listing sort.","schema":{"type":"string","enum":["popular","new"],"default":"popular"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"Subreddit listing.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubredditListing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/user":{"get":{"operationId":"getUser","tags":["Reddit"],"summary":"Get Reddit user profile","description":"Returns user karma breakdown, created timestamp, badges, and suspension status. 1 credit per call.","parameters":[{"name":"name","in":"query","required":true,"description":"Reddit username (3 to 20 letters, numbers, underscores, or dashes).","schema":{"type":"string"},"example":"spez"}],"responses":{"200":{"description":"User profile.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the data came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/user/posts":{"get":{"operationId":"getUserPosts","tags":["Reddit"],"summary":"Get user submissions","description":"Returns posts submitted by a user. 1 credit per call.","parameters":[{"name":"name","in":"query","required":true,"description":"Reddit username.","schema":{"type":"string"},"example":"spez"},{"name":"sort","in":"query","schema":{"type":"string","enum":["new","hot","top","controversial"],"default":"new"}},{"$ref":"#/components/parameters/Time"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"Submitted posts.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/user/comments":{"get":{"operationId":"getUserComments","tags":["Reddit"],"summary":"Get user comments","description":"Returns comments submitted by a user. 1 credit per call.","parameters":[{"name":"name","in":"query","required":true,"description":"Reddit username.","schema":{"type":"string"},"example":"spez"},{"name":"sort","in":"query","schema":{"type":"string","enum":["new","hot","top","controversial"],"default":"new"}},{"$ref":"#/components/parameters/Time"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"Submitted comments.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the listing came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentListing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/search":{"get":{"operationId":"search","tags":["Reddit"],"summary":"Search posts","description":"1 credit per call.","parameters":[{"name":"q","in":"query","required":true,"description":"Search query, 1 to 256 characters.","schema":{"type":"string","maxLength":256},"example":"best crm for small agency"},{"name":"type","in":"query","description":"Type of content to search: post (default), subreddit, or user.","schema":{"type":"string","enum":["post","subreddit","user"],"default":"post"}},{"name":"sub","in":"query","description":"Only search this subreddit.","schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["relevance","new","top","comments"],"default":"relevance"}},{"$ref":"#/components/parameters/Time"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"The search results.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Where the search results came from (`L1_LISTING` or `MISS`).","schema":{"type":"string","enum":["L1_LISTING","MISS"]}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Listing"},{"$ref":"#/components/schemas/SubredditListing"},{"$ref":"#/components/schemas/UserListing"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/reddit/search/comments":{"get":{"operationId":"searchComments","tags":["Reddit"],"summary":"Search comments","description":"Searches Reddit comments across Reddit or scoped to a subreddit. A page holds what Reddit's comment search page shows, about a dozen comments; there is no `limit`. Pass `after` for the next page. 1 credit per call.","parameters":[{"name":"q","in":"query","required":true,"description":"Search query, 1 to 500 characters.","schema":{"type":"string","maxLength":500},"example":"postgres replica lag"},{"name":"sub","in":"query","description":"Only search this subreddit.","schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["relevance","new","top"],"default":"relevance"}},{"$ref":"#/components/parameters/Time"},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/NSFW"}],"responses":{"200":{"description":"The comments.","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"},"X-Cache-Tier":{"description":"Cache tier (`MISS`).","schema":{"type":"string","enum":["MISS"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentListing"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"403":{"$ref":"#/components/responses/RedditRefused"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/v1/monitors":{"post":{"operationId":"createMonitor","tags":["Monitors"],"summary":"Create a keyword monitor","description":"Creates a new keyword monitor across Reddit posts and/or comments.\nBilled 10 credits upfront for the first 24 hours. Daily match volume and webhooks are free.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","keywords"],"properties":{"name":{"type":"string","example":"Mentions of restic"},"keywords":{"type":"array","items":{"type":"string"},"example":["restic","\"borg backup\""]},"exclude":{"type":"array","items":{"type":"string"},"example":["hiring"]},"subreddits":{"type":"array","items":{"type":"string"},"example":["selfhosted","DataHoarder"]},"posts":{"type":"boolean","default":true},"comments":{"type":"boolean","default":true},"nsfw":{"type":"boolean","default":false},"webhook_url":{"type":"string","example":"https://example.com/hook"},"webhook_kind":{"type":"string","enum":["generic","slack","discord"]}}}}}},"responses":{"201":{"description":"Created monitor and HMAC secret","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"monitor":{"$ref":"#/components/schemas/Monitor"},"webhook_secret":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"operationId":"listMonitors","tags":["Monitors"],"summary":"List user monitors","description":"Returns all monitors configured by the authenticated user. Free (0 credits).","responses":{"200":{"description":"List of monitors","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Monitor"}},"limit":{"type":"integer"},"used":{"type":"integer"},"daily_match_cap":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/monitors/{id}":{"get":{"operationId":"getMonitor","tags":["Monitors"],"summary":"Get a monitor and its stats","description":"Returns monitor configuration and 24h/7d delivery and match statistics. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Monitor with statistics","content":{"application/json":{"schema":{"type":"object","properties":{"monitor":{"$ref":"#/components/schemas/Monitor"},"stats":{"$ref":"#/components/schemas/MonitorStats"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}},"patch":{"operationId":"updateMonitor","tags":["Monitors"],"summary":"Update a monitor","description":"Updates monitor settings. Changing the webhook URL clears any webhook_failing status. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}},"exclude":{"type":"array","items":{"type":"string"}},"subreddits":{"type":"array","items":{"type":"string"}},"posts":{"type":"boolean"},"comments":{"type":"boolean"},"nsfw":{"type":"boolean"},"webhook_url":{"type":"string","nullable":true},"webhook_kind":{"type":"string","enum":["generic","slack","discord"],"nullable":true}}}}}},"responses":{"200":{"description":"Updated monitor","content":{"application/json":{"schema":{"type":"object","properties":{"monitor":{"$ref":"#/components/schemas/Monitor"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}},"delete":{"operationId":"deleteMonitor","tags":["Monitors"],"summary":"Delete a monitor","description":"Soft-deletes a monitor. Charging stops immediately. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Monitor deleted","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"deleted"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}}},"/v1/monitors/{id}/pause":{"post":{"operationId":"pauseMonitor","tags":["Monitors"],"summary":"Pause a monitor","description":"Pauses a monitor. Stops match tracking and daily charges. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Monitor paused","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"paused"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}}},"/v1/monitors/{id}/resume":{"post":{"operationId":"resumeMonitor","tags":["Monitors"],"summary":"Resume a monitor","description":"Resumes a paused monitor. Immediately charges 10 credits for the next 24 hours.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Resumed monitor","headers":{"X-Credits-Used":{"$ref":"#/components/headers/CreditsUsed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"monitor":{"$ref":"#/components/schemas/Monitor"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/OutOfCredits"},"404":{"description":"Monitor not found"}}}},"/v1/monitors/{id}/rotate-secret":{"post":{"operationId":"rotateMonitorSecret","tags":["Monitors"],"summary":"Rotate webhook HMAC secret","description":"Generates and returns a new HMAC secret for generic webhooks. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"New secret","content":{"application/json":{"schema":{"type":"object","properties":{"webhook_secret":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}}},"/v1/monitors/{id}/test":{"post":{"operationId":"testMonitor","tags":["Monitors"],"summary":"Test webhook delivery","description":"Sends a sample test match to the configured webhook URL. Rate limited to 5 per minute. Free (0 credits).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Test delivery outcome","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean"},"status":{"type":"integer"},"error":{"type":"string","nullable":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/monitors/{id}/matches":{"get":{"operationId":"getMonitorMatches","tags":["Monitors"],"summary":"Get matches for a monitor","description":"Oldest first by default, for polling: pass the ID of the last match you received as\n`after` and you get what arrived since. `after` in the response is set only when more\nmatches are waiting right now. `order=newest` lists newest first, paged with `before`.\nFree (0 credits).\n","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"order","in":"query","description":"`oldest` (default) or `newest`.","schema":{"type":"string","enum":["oldest","newest"],"default":"oldest"}},{"name":"after","in":"query","description":"With `order=oldest`, a match ID; returns the matches after it.","schema":{"type":"string"}},{"name":"before","in":"query","description":"With `order=newest`, a match ID; returns the matches before it.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum items to return (1-200, default 100).","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}}],"responses":{"200":{"description":"List of matches","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MonitorMatch"}},"after":{"type":"string","description":"With `order=oldest`, the cursor for the next page when one is waiting."},"before":{"type":"string","description":"With `order=newest`, the cursor for the next, older page."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Monitor not found"}}}},"/mcp":{"post":{"operationId":"mcp","summary":"MCP server (Streamable HTTP)","description":"A remote Model Context Protocol server with seven tools: `get_reddit_post`,\n`get_reddit_items`, `list_subreddit_posts`, `get_subreddit`, `get_reddit_user`,\n`search_reddit` and `get_monitor_matches`. Authenticate with an API key, or let your MCP client sign\nin with OAuth. Tool calls are billed like the REST routes they map to.\n","responses":{"200":{"description":"A JSON-RPC response."},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"},"apiKey":{"type":"apiKey","in":"header","name":"X-Api-Key"}},"headers":{"CreditsUsed":{"description":"Credits this request cost.","schema":{"type":"integer"}}},"parameters":{"SubredditSort":{"name":"sort","in":"query","schema":{"type":"string","enum":["hot","new","top","rising","controversial"],"default":"hot"}},"Time":{"name":"t","in":"query","description":"Time window for `sort=top` or `controversial` (and search).","schema":{"type":"string","enum":["hour","day","week","month","year","all"]}},"Limit":{"name":"limit","in":"query","description":"Posts to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},"After":{"name":"after","in":"query","description":"Fullname of the last item on the previous page (e.g. `t3_1x2y3z`) for pagination.","schema":{"type":"string"}},"NSFW":{"name":"nsfw","in":"query","description":"Include NSFW posts. Default is false (NSFW posts are filtered out).","schema":{"type":"boolean","default":false}}},"responses":{"BadRequest":{"description":"A parameter is missing or invalid (`invalid_request`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"The key is missing, invalid or revoked (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"OutOfCredits":{"description":"The account has no credits left (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RedditRefused":{"description":"Reddit does not show this content to logged-out readers, e.g. a private or quarantined subreddit (`reddit_refused`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Reddit has no such post or subreddit (`not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests for this key (`rate_limited`), or a free key's daily limit (`daily_limit_reached`). Wait for `Retry-After`.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"A temporary problem reaching Reddit (`upstream_busy`, `upstream_timeout`, `upstream_error`). Retry shortly; nothing was billed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","retryable"],"properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string"},"retryable":{"type":"boolean"},"retry_after":{"type":"integer","description":"Seconds to wait before retrying."}}}}},"PostResponse":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/Post"},"discussion_graph":{"$ref":"#/components/schemas/DiscussionGraph"},"meta":{"$ref":"#/components/schemas/PostMeta"}}},"PostMeta":{"type":"object","properties":{"comments_returned":{"type":"integer","description":"Comments in the response."},"comments_total":{"type":"integer","description":"Reddit's comment count, deleted and hidden comments included."},"has_more":{"type":"boolean","description":"A larger max_comments would return more."},"max_comments":{"type":"integer"},"credits_used":{"type":"integer"},"cache":{"type":"string"},"limited_by_balance":{"type":"boolean"},"focus_comment_id":{"type":"string","description":"Comment ID when a comment permalink was requested."}}},"Post":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domain":{"type":"string"},"is_self":{"type":"boolean"},"flair":{"type":"string"},"spoiler":{"type":"boolean"},"stickied":{"type":"boolean"},"locked":{"type":"boolean"},"removed":{"type":"boolean"},"subreddit":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"},"score":{"type":"integer"},"upvote_ratio":{"type":"number"},"num_comments":{"type":"integer"},"url":{"type":"string"},"permalink":{"type":"string"},"selftext":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"is_video":{"type":"boolean"},"over_18":{"type":"boolean"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gallery"]},"url":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"caption":{"type":"string"}}}},"poll":{"type":"object","properties":{"total_votes":{"type":"integer"},"is_closed":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"vote_count":{"type":"integer"}}}}}},"crosspost_of":{"type":"object","properties":{"id":{"type":"string"},"subreddit":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"},"permalink":{"type":"string"}}},"comments":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}}},"Comment":{"type":"object","properties":{"id":{"type":"string"},"parent_id":{"type":"string","description":"t3_<post id> for a top-level comment, t1_<comment id> for a reply."},"author":{"type":"string"},"score":{"type":"integer"},"body":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"depth":{"type":"integer"},"is_submitter":{"type":"boolean","description":"Written by the original poster."},"controversy":{"type":"integer"},"replies":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}}},"DiscussionGraph":{"type":"object","properties":{"post_id":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"},"author_followups":{"type":"array","description":"The original poster's own comments in the thread.","items":{"$ref":"#/components/schemas/Comment"}},"most_upvoted":{"type":"array","description":"Highest-score comments excluding OP, AutoModerator and deleted comments.","items":{"$ref":"#/components/schemas/Comment"}},"controversial":{"type":"array","description":"Comments with controversiality flag or negative score, excluding OP.","items":{"$ref":"#/components/schemas/Comment"}},"total_analyzed":{"type":"integer"}}},"Listing":{"type":"object","required":["sort","count","items","filtered_nsfw"],"properties":{"subreddit":{"type":"string","nullable":true},"query":{"type":"string","nullable":true},"sort":{"type":"string"},"count":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"after":{"type":"string","nullable":true},"filtered_nsfw":{"type":"integer"},"degraded":{"type":"boolean"}}},"ThingItem":{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["post","comment"]},"post":{"$ref":"#/components/schemas/Post"},"comment":{"$ref":"#/components/schemas/CommentItem"}}},"ThingsResponse":{"type":"object","required":["items","missing"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ThingItem"}},"missing":{"type":"array","items":{"type":"string"}}}},"CommentItem":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"post_id":{"type":"string"},"post_title":{"type":"string"},"subreddit":{"type":"string"},"author":{"type":"string"},"score":{"type":"integer"},"body":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"permalink":{"type":"string"},"parent_id":{"type":"string"},"is_submitter":{"type":"boolean"},"controversiality":{"type":"integer"}}},"SubredditRule":{"type":"object","properties":{"kind":{"type":"string"},"short_name":{"type":"string"},"description":{"type":"string"},"violation_reason":{"type":"string"},"priority":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"Subreddit":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"public_description":{"type":"string"},"description":{"type":"string"},"subscribers":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"over_18":{"type":"boolean"},"type":{"type":"string"},"url":{"type":"string"},"icon":{"type":"string"},"rules":{"type":"array","items":{"$ref":"#/components/schemas/SubredditRule"}}}},"User":{"type":"object","properties":{"name":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"link_karma":{"type":"integer"},"comment_karma":{"type":"integer"},"total_karma":{"type":"integer"},"is_employee":{"type":"boolean"},"is_mod":{"type":"boolean"},"has_verified_email":{"type":"boolean"},"icon":{"type":"string"},"suspended":{"type":"boolean"}}},"CommentListing":{"type":"object","required":["sort","count","items","filtered_nsfw"],"properties":{"subreddit":{"type":"string","nullable":true},"query":{"type":"string","nullable":true},"sort":{"type":"string"},"count":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CommentItem"}},"after":{"type":"string","nullable":true},"filtered_nsfw":{"type":"integer"},"degraded":{"type":"boolean"}}},"SubredditListing":{"type":"object","required":["sort","count","items","filtered_nsfw"],"properties":{"query":{"type":"string","nullable":true},"sort":{"type":"string"},"count":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Subreddit"}},"after":{"type":"string","nullable":true},"filtered_nsfw":{"type":"integer"},"degraded":{"type":"boolean"}}},"UserListing":{"type":"object","required":["sort","count","items","filtered_nsfw"],"properties":{"query":{"type":"string","nullable":true},"sort":{"type":"string"},"count":{"type":"integer"},"items":{"type":"array","items":{"$ref":"#/components/schemas/User"}},"after":{"type":"string","nullable":true},"filtered_nsfw":{"type":"integer"},"degraded":{"type":"boolean"}}},"Monitor":{"type":"object","required":["id","name","keywords","status","include_posts","include_comments","nsfw","next_charge_at","created_at","updated_at"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}},"exclude":{"type":"array","items":{"type":"string"}},"subreddits":{"type":"array","items":{"type":"string"}},"include_posts":{"type":"boolean"},"include_comments":{"type":"boolean"},"nsfw":{"type":"boolean"},"webhook_url":{"type":"string","nullable":true},"webhook_kind":{"type":"string","enum":["generic","slack","discord"],"nullable":true},"status":{"type":"string","enum":["active","paused","paused_balance","deleted"]},"webhook_failing":{"type":"boolean"},"next_charge_at":{"type":"string","format":"date-time"},"last_match_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"MonitorMatch":{"type":"object","required":["id","monitor_id","thing_id","kind","subreddit","author","title","body","permalink","post_id","created_utc","matched_terms","suppressed","delivery_status","created_at"],"properties":{"id":{"type":"string"},"monitor_id":{"type":"string"},"thing_id":{"type":"string"},"kind":{"type":"string","enum":["post","comment"]},"subreddit":{"type":"string"},"author":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"permalink":{"type":"string"},"post_id":{"type":"string"},"created_utc":{"type":"string","format":"date-time"},"matched_terms":{"type":"array","items":{"type":"string"}},"suppressed":{"type":"boolean"},"delivery_status":{"type":"string","enum":["none","pending","delivered","failed","skipped"]},"delivered_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"MonitorStats":{"type":"object","required":["matches_today","suppressed_today","matches_7d","delivery_failures_24h"],"properties":{"matches_today":{"type":"integer"},"suppressed_today":{"type":"integer"},"matches_7d":{"type":"integer"},"last_match_at":{"type":"string","format":"date-time","nullable":true},"delivery_failures_24h":{"type":"integer"}}}}}}