# Stack Overflow Questions Scraper (`muhammadafzal/stack-overflow-questions-scraper`) Actor

Extract public Stack Overflow questions by text, tags, or exact URLs with titles, tags, scores, views, answers, authors, dates, links, and optional bodies.

- **URL**: https://apify.com/muhammadafzal/stack-overflow-questions-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.00 / 1,000 stack overflow questions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Stack Overflow Questions Scraper

**Free plan limit:** Free-plan users can receive up to **5 result records per run**. Paid-plan and local/unknown runs retain the Actor's existing limits.

Extract public Stack Overflow questions by search text, tags, or exact question URLs. The Actor returns analysis-ready records with titles, tags, scores, views, answer counts, author metadata, dates, links, and optional question bodies.

This Actor is useful for developer research, documentation gap analysis, technical-content planning, trend discovery, support intelligence, and building question datasets. It is not a tool for private content, user authentication, answers/comments extraction, voting, posting, or bypassing Stack Overflow access controls.

### What it extracts

| Field | Description |
| --- | --- |
| `questionId`, `url`, `title` | Stable ID, canonical question link, and decoded title |
| `tags` | Stack Overflow tags assigned to the question |
| `score`, `viewCount`, `answerCount` | Engagement and response metrics at extraction time |
| `isAnswered`, `acceptedAnswerId` | Answer state and accepted answer reference |
| `authorName`, `authorId`, `authorReputation` | Public author metadata when available |
| `creationDate`, `lastActivityDate`, `lastEditDate` | UTC ISO 8601 timestamps |
| `closedDate`, `closedReason` | Closure metadata when applicable |
| `contentLicense` | License reported by Stack Exchange |
| `bodyHtml`, `bodyText` | Optional question body in HTML and normalized text |
| `source`, `scrapedAt` | Provenance and extraction timestamp |

Deleted users and absent accepted answers are represented as `null`, not invented values. The default dataset contains only question records; run diagnostics are written separately to the `OUTPUT` key-value-store record.

### Input

| Input | Type | Default | Purpose |
| --- | --- | --- | --- |
| `searchQuery` | string | `typescript` | Free-text question search |
| `tags` | string\[] | `[]` | Require up to five tags |
| `startUrls` | request list | `[]` | Fetch exact Stack Overflow question URLs |
| `sort` | enum | `relevance` | `relevance`, `activity`, `creation`, or `votes` |
| `minScore` | integer | omitted | Minimum score; unavailable for relevance sort |
| `fromDate`, `toDate` | `YYYY-MM-DD` | omitted | Inclusive creation-date bounds in UTC |
| `includeBody` | boolean | `false` | Include question body HTML and plain text |
| `maxResults` | integer | `25` | Cap output and billable records from 1 to 500 |

Search by text:

```json
{
  "searchQuery": "typescript generics",
  "tags": ["typescript"],
  "sort": "relevance",
  "includeBody": true,
  "maxResults": 25
}
```

Browse recent tagged questions:

```json
{
  "searchQuery": "",
  "tags": ["javascript", "reactjs"],
  "sort": "creation",
  "fromDate": "2026-01-01",
  "maxResults": 100
}
```

Fetch exact questions:

```json
{
  "searchQuery": "",
  "startUrls": [
    { "url": "https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript" }
  ],
  "sort": "activity",
  "maxResults": 1
}
```

Run through the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/USERNAME~stack-overflow-questions-scraper/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"python async await","tags":["python"],"maxResults":10}'
```

Replace `USERNAME` and `APIFY_TOKEN` with your own Apify account values. Keep tokens in secrets or authorization headers in production.

### Output example

```json
{
  "questionId": 37233735,
  "title": "Interfaces vs Types in TypeScript",
  "url": "https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript",
  "tags": ["typescript", "interface", "typescript-types"],
  "score": 2807,
  "viewCount": 1135806,
  "answerCount": 25,
  "isAnswered": true,
  "acceptedAnswerId": 37233777,
  "authorName": "user6101582",
  "authorId": null,
  "authorReputation": null,
  "creationDate": "2016-05-15T01:53:52.000Z",
  "lastActivityDate": "2026-07-27T10:44:10.000Z",
  "lastEditDate": null,
  "closedDate": null,
  "closedReason": null,
  "contentLicense": "CC BY-SA 4.0",
  "bodyHtml": null,
  "bodyText": null,
  "source": "Stack Exchange API v2.3",
  "scrapedAt": "2026-08-29T00:00:00.000Z"
}
```

### Pricing

This Actor uses **pay-per-event** pricing. These are the current Apify Store event prices:

| Event | Price (USD) | When it is charged |
|---|---:|---|
| `apify-default-dataset-item` | FREE: $0.02; BRONZE: $0.02; SILVER: $0.02; GOLD: $0.016; PLATINUM: $0.016; DIAMOND: $0.016 | Stack Overflow question — One schema-valid Stack Overflow question written to the default dataset. |
| `apify-actor-start` | $0.005 | Actor Start — Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). — Charged once per run. |

Apify platform usage for this Actor run is included alongside the event prices above; no separate per-run platform-usage fee is passed to users.

This covers Apify platform usage for this Actor run. Other Apify products or usage outside this Actor run may still follow your account plan.

### Reliability and limitations

Direct Stack Overflow HTML access is protected by Cloudflare in common cloud environments. After measuring that path, this Actor uses Stack Exchange's official public API v2.3 as the authorized first-party fallback. It does not solve CAPTCHAs or use private sessions.

The Actor follows API `backoff` instructions, retries temporary failures with bounded exponential delay, paginates up to the requested result cap, deduplicates question IDs, and reports remaining API quota in `OUTPUT`. The unauthenticated Stack Exchange API quota is shared by IP and can change; quota exhaustion or upstream downtime produces an explicit failed/partial diagnostic instead of fabricated data. Identical queries should not be run more than once per minute because Stack Exchange heavily caches API methods.

Search relevance follows Stack Exchange's undocumented relevance algorithm. Tags in text-search mode follow the API's advanced-search behavior; tag-only browse mode uses the `/questions` endpoint. This Actor extracts questions only—not answers, comments, revisions, or full user profiles.

### Responsible use

Use the data in line with Stack Overflow's Terms of Service, the Stack Exchange API terms, applicable privacy law, and each record's reported content license. Attribute Stack Overflow and the original authors when republishing licensed content. Avoid collecting or using public author data for harassment, spam, sensitive profiling, or decisions that materially affect people.

For support, include the run ID, redacted input, expected result, and observed `OUTPUT` summary. Never share Apify tokens or other secrets.

# Actor input Schema

## `searchQuery` (type: `string`):

Use this when finding questions by free text. Enter a phrase such as `typescript generics`; defaults to `typescript`. This is not Stack Overflow's full web-search syntax.

## `tags` (type: `array`):

Use this to require up to 5 Stack Overflow tags. Enter literal tag names such as `javascript` and `reactjs`; all supplied tags must match in browse mode.

## `startUrls` (type: `array`):

Use this to fetch exact public questions. Supply Stack Overflow question URLs such as `https://stackoverflow.com/questions/37233735/...`; other domains and non-question URLs are rejected.

## `sort` (type: `string`):

Use this to order search results. `relevance` is best for text search; `activity`, `creation`, and `votes` use Stack Exchange question fields.

## `minScore` (type: `integer`):

Use this to keep questions with at least this score. Enter an integer from -100 to 100000; omitted by default and unavailable with relevance sorting.

## `fromDate` (type: `string`):

Use this to include questions created on or after a UTC date. Enter `YYYY-MM-DD`, for example `2026-01-01`; leave empty for no lower date bound.

## `toDate` (type: `string`):

Use this to include questions created on or before a UTC date. Enter `YYYY-MM-DD`, for example `2026-12-31`; leave empty for no upper date bound.

## `includeBody` (type: `boolean`):

Use this when the question text is needed. When enabled, each record includes `bodyHtml` and normalized `bodyText`; defaults to false to reduce payload size.

## `maxResults` (type: `integer`):

Use this to cap delivered and billable question records. Enter 1-500; defaults to 25. The Actor stops pagination when this limit is reached.

## Actor input object example

```json
{
  "searchQuery": "typescript",
  "tags": [],
  "startUrls": [],
  "sort": "relevance",
  "includeBody": false,
  "maxResults": 25
}
```

# Actor output Schema

## `questions` (type: `string`):

Schema-validated Stack Overflow question records.

## `summary` (type: `string`):

Outcome, counts, API quota, warnings, and timing for this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "typescript"
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/stack-overflow-questions-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchQuery": "typescript" }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/stack-overflow-questions-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "typescript"
}' |
apify call muhammadafzal/stack-overflow-questions-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/stack-overflow-questions-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tMrb8kcf9Gd8IMK4E/builds/QBflSEluqHGRvkEhg/openapi.json
