{
  "openapi": "3.0.1",
  "info": {
    "title": "Reddit Scraper & API: Posts, Comment Trees, Search, Monitoring",
    "description": "Scrape Reddit posts, complete comment trees, searches, subreddits and users without login or API key. Whole threads as Markdown for LLMs, comment search, strict keyword matching and new-only monitoring. Errors and filtered posts are not charged.",
    "version": "0.2",
    "x-build-id": "cHqejdQXTvn55SRDD"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/quarra~reddit-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-quarra-reddit-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/quarra~reddit-scraper/runs": {
      "post": {
        "operationId": "runs-sync-quarra-reddit-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/quarra~reddit-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-quarra-reddit-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "subreddits": {
            "title": "Subreddits",
            "type": "array",
            "description": "Subreddit names (technology, r/technology), URLs, or several joined by + (pics+homelab, one listing). Posts are listed with the sort and time range below.",
            "items": {
              "type": "string"
            }
          },
          "searchQueries": {
            "title": "Search queries",
            "type": "array",
            "description": "Keywords searched on Reddit, one query per line, as typed in Reddit's search box. Quotes keep a phrase together (\"home assistant\"); Strict search below enforces every word.",
            "items": {
              "type": "string"
            }
          },
          "commentSearchQueries": {
            "title": "Comment search",
            "type": "array",
            "description": "Find COMMENTS containing your keywords, anywhere on Reddit (or in the subreddit above), one query per line: each comment with its text, score, date, parentId and its post's title and URL. Strict search and excluded keywords apply to the comment's text. Reddit's comment search ignores dates except with Search sort New: use New with a time range or date window to monitor.",
            "items": {
              "type": "string"
            }
          },
          "searchSubreddit": {
            "title": "Search only inside this subreddit",
            "type": "string",
            "description": "Optional. Restrict every search query and comment search to one subreddit (selfhosted, r/selfhosted or its URL)."
          },
          "strictSearch": {
            "title": "Strict search (exact words only)",
            "type": "boolean",
            "description": "Reddit's search returns loosely related posts (for home assistant, 17 of the top 100 contain it). When on, a post is kept only if its title or text contains EVERY word of the query, as whole words (ai never matches said; case and accents ignored). \"Quotes\" require a phrase, -word excludes, OR and parentheses group alternatives. Other sorts of the same time range are read to reach your limit. Rejected posts are never charged (counted in OUTPUT as filteredOut).",
            "default": false
          },
          "strictMatchIn": {
            "title": "Strict search and excluded keywords look in",
            "enum": [
              "titleOrText",
              "title"
            ],
            "type": "string",
            "description": "Where the words of a strict search and the excluded keywords must (or must not) appear.",
            "default": "titleOrText"
          },
          "usernames": {
            "title": "Users",
            "type": "array",
            "description": "Reddit usernames (spez, u/spez, @spez) or profile URLs: profile card plus post and comment history.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Reddit URLs",
            "type": "array",
            "description": "Any Reddit URL, one per line (plain strings; {\"url\": …} objects are accepted too). A post URL, redd.it link, share link, gallery or v.redd.it link, or comment permalink returns the post and its COMPLETE comment tree. Subreddit (or just r/name, u/name), search (posts, comments, communities) and user URLs work too.",
            "items": {
              "type": "string"
            }
          },
          "refreshPosts": {
            "title": "Posts to refresh (no comments)",
            "type": "array",
            "description": "Post URLs, redd.it links or post IDs (1abc234) to re-read without their comments: current score, comment count, flair, edited or removed status. 100 posts per request (1,000 posts = 10 requests). Only maxItems limits this list.",
            "items": {
              "type": "string"
            }
          },
          "maxPostsPerSource": {
            "title": "Max posts per subreddit, search or user",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Posts per subreddit or search query, comments per comment search, posts and comments per user history. Reddit lists ~1,000 posts per subreddit sort and ~250 per search; enable 'Go beyond Reddit's listing cap' for more. With 'Only new', this is the window watched.",
            "default": 100
          },
          "maxItems": {
            "title": "Max results in total",
            "minimum": 1,
            "type": "integer",
            "description": "Optional hard cap for the whole run, counted in charged results (posts + comments + profiles). Respected exactly. Empty = no global cap."
          },
          "sort": {
            "title": "Subreddit sort",
            "enum": [
              "hot",
              "new",
              "top",
              "rising",
              "controversial"
            ],
            "type": "string",
            "description": "How subreddit posts are ordered. Use Top or Controversial with a time range. For monitoring, New is the fastest and cheapest.",
            "default": "hot"
          },
          "searchSort": {
            "title": "Search sort",
            "enum": [
              "relevance",
              "hot",
              "top",
              "new",
              "comments"
            ],
            "type": "string",
            "description": "How search results are ordered. Comment searches use Relevance, Top or New (Hot and Most comments fall back to Relevance).",
            "default": "relevance"
          },
          "timeFilter": {
            "title": "Time range",
            "enum": [
              "hour",
              "day",
              "week",
              "month",
              "year",
              "all"
            ],
            "type": "string",
            "description": "Used by the Top and Controversial subreddit sorts and by searches (comment search: with the New sort only).",
            "default": "all"
          },
          "postedAfter": {
            "title": "Posted after",
            "type": "string",
            "description": "Only items created after this date (2026-09-01, or relative: 7 days). Applies to posts, user history and listing URLs."
          },
          "postedBefore": {
            "title": "Posted before",
            "type": "string",
            "description": "Only items created before this date."
          },
          "includeNsfw": {
            "title": "Include NSFW",
            "type": "boolean",
            "description": "Include posts marked NSFW (18+). Off by default.",
            "default": false
          },
          "excludeKeywords": {
            "title": "Excluded keywords",
            "maxItems": 200,
            "type": "array",
            "description": "Drop every post whose title or text contains one of these words or phrases, one per line (whole words, case and accents ignored; a comma belongs to the phrase, as in 10,000 views). Dropped items are not charged. Comment trees are not filtered; comments found by comment search are.",
            "items": {
              "type": "string"
            }
          },
          "postTypes": {
            "title": "Post types",
            "type": "array",
            "description": "Keep only these post types (mediaType). Empty = all types. Dropped posts are not charged.",
            "items": {
              "type": "string",
              "enum": [
                "text",
                "link",
                "image",
                "gallery",
                "video",
                "embed"
              ],
              "enumTitles": [
                "Text",
                "Link",
                "Image",
                "Gallery",
                "Video",
                "Embed (YouTube, …)"
              ]
            }
          },
          "flairs": {
            "title": "Post flairs",
            "maxItems": 200,
            "type": "array",
            "description": "Keep only posts with one of these flairs, written as on Reddit (Question, Help; case and accents ignored). Empty = all flairs. Dropped posts are not charged. In a search, the flair:\"…\" operator lets Reddit filter first.",
            "items": {
              "type": "string"
            }
          },
          "deepScrape": {
            "title": "Go beyond Reddit's listing cap",
            "type": "boolean",
            "description": "When you need more posts than Reddit lists (~1,000 per subreddit sort, ~250 per search), combine extra sorts and time ranges and keep unique posts only. Posts outside the chosen sort may be added: use the date filters for a precise window.",
            "default": false
          },
          "includeComments": {
            "title": "Include comments of every post",
            "type": "boolean",
            "description": "For every post found in subreddits, searches, user histories and listing URLs, also scrape its complete comment tree (each comment has parentId and depth). Post URLs always include their comments.",
            "default": false
          },
          "maxCommentsPerPost": {
            "title": "Max comments per post",
            "minimum": 0,
            "type": "integer",
            "description": "Empty = the complete thread, even with tens of thousands of comments. 0 returns the post only. With Only new, each run returns up to this many comments of a thread that earlier runs did not return."
          },
          "maxCommentDepth": {
            "title": "Max comment depth",
            "minimum": 0,
            "type": "integer",
            "description": "Empty = all levels. 0 = top-level comments only, 1 = plus direct replies, and so on. Deeper branches are not even requested (faster)."
          },
          "commentSort": {
            "title": "Comment sort",
            "enum": [
              "confidence",
              "top",
              "new",
              "controversial",
              "old",
              "qa"
            ],
            "type": "string",
            "description": "Order of comments inside each thread (Best is Reddit's default).",
            "default": "confidence"
          },
          "commentsPostedAfter": {
            "title": "Comments posted after",
            "type": "string",
            "description": "Only comments written after this date (2026-10-01, or 12 hours), in threads and user histories. The tree is still walked, so a new reply under an old comment is found (reading stops after 10,000 comments in a row outside your dates); only matching comments are saved and charged."
          },
          "commentsPostedBefore": {
            "title": "Comments posted before",
            "type": "string",
            "description": "Only comments written before this date."
          },
          "includeUserProfile": {
            "title": "Include user profile card",
            "type": "boolean",
            "description": "For each user: one profile record (karma, account age, verified, followers) before their history.",
            "default": true
          },
          "userContent": {
            "title": "User history",
            "enum": [
              "overview",
              "submitted",
              "comments"
            ],
            "type": "string",
            "description": "Which part of a user's history to scrape.",
            "default": "overview"
          },
          "outputFormat": {
            "title": "Output format",
            "enum": [
              "items",
              "threadMarkdown"
            ],
            "type": "string",
            "description": "Thread Markdown: one record per post with its whole comment tree as indented Markdown (author, score, date, text), about 7 times fewer characters than the same thread as JSON. A thread too big for one record (over ~20,000 comments) comes as numbered parts. Same price: 1 post + 1 comment per comment included. Profiles stay normal records.",
            "default": "items"
          },
          "onlyNew": {
            "title": "Only new since the last run (monitoring)",
            "type": "boolean",
            "description": "Remember what earlier runs of the same watch returned and output only new posts and new comments (with Include comments, also comments that earlier runs did not return under posts already seen; with Max comments per post, each run adds up to that many of them per thread, oldest included). Nothing already delivered is charged again, even after a run that timed out, was aborted or overlapped another. One run per watch at a time: a second one does nothing and charges nothing. Memory: key-value store quarra-reddit-watch of your account. Set a watch name, then schedule the Actor.",
            "default": false
          },
          "watchName": {
            "title": "Watch name",
            "type": "string",
            "description": "Name of this watch's memory for 'Only new'. Recommended: runs with the same name share it even when you add or remove sources. Empty: the memory belongs to this exact set of inputs and filters, so adding a source starts a new watch that returns everything again (limits, output format and proxy don't count)."
          },
          "proxyConfiguration": {
            "title": "Connection",
            "type": "object",
            "description": "Connection. Keep the default (automatic). Costs are included in the price.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}