# People Also Ask Question Extractor (`junipr/people-also-ask-question-extractor`) Actor

Extract People Also Ask questions and visible answer/source snippets from SERP snapshots for content planning and FAQ research.

- **URL**: https://apify.com/junipr/people-also-ask-question-extractor.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 query snapshot scanneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## People Also Ask Question Extractor

Extract People Also Ask questions and visible answer/source snippets from SERP snapshots for content planning and FAQ research

### Who it is for

People Also Ask Question Extractor helps content teams, seo agencies, faq builders, editorial strategists extract People Also Ask questions and visible answer/source snippets from SERP snapshots for content planning and FAQ research. It produces schema-valid dataset rows, evidence-backed KVS reports, safe diagnostics, and capped pay-per-event pricing for predictable Apify Store runs.

Convert visible People Also Ask modules into structured questions with answer visibility, answer text when present, cited-source domain, deterministic intent cluster, rank, and duplicate group. It is useful for FAQ research and evidence-led editorial planning.

### Evidence contract

The actor emits only facts visible in supplied HTML, explicit input records, or a permitted public URL response. It never creates rankings, questions, modules, suggestions, titles, snippets, or page metadata to fill an evidence gap. A missing source produces a schema-valid status row explaining what input is needed.

Network access is conservative. Only HTTP and HTTPS URLs are accepted; localhost, loopback addresses, private IPv4 ranges, and disallowed domains are rejected. The runtime does not follow links discovered in a page. Challenge and access-denied pages are recorded as blocked evidence and are not solved or circumvented.

### Input modes

- Pass expanded or collapsed question blocks in `serpHtmlInputs` or `htmlInputs`.
- Visible answers are preserved; collapsed answers absent from the HTML remain null.
- `expandQuestionsWhenPossible` changes the diagnostic guidance only. The actor does not simulate browser clicks.
- `dedupeQuestions` and `maxQuestionsPerQuery` control output volume.

### Example input

```json
{
  "queries": [
    "project management software"
  ],
  "serpHtmlInputs": [
    {
      "sourceUrl": "https://example.com/serp",
      "query": "project management software",
      "html": "<article class=\"paa-item\" data-paa-question=\"How much does project software cost?\"><p class=\"answer\">Pricing varies by team size.</p><a href=\"https://vendor.example/pricing\">Pricing guide</a></article>"
    }
  ],
  "maxQuestionsPerQuery": 20,
  "dedupeQuestions": true,
  "maxChargeUsd": 50
}
```

### Dataset output

Each dataset item is one JSON object, which makes the result directly usable in Apify integrations, exports, webhooks, and downstream data pipelines.

- question text and visible position
- answer snippet and `answerVisible` boolean
- cited source title and domain when a link is present
- intent cluster and duplicate-group identifier
- query, source status, evidence excerpt, and recommendation

Common evidence fields include `sourceUrl`, `sourceType`, `pageTitle`, `issueCode`, `severity`, `evidenceSnippet`, `recommendation`, `httpStatus`, and `scannedAt`. Fields without source evidence are null rather than guessed.

### Reports and retained evidence

When `includeReport` is true, the actor writes a Markdown summary, CSV records, JSON issue rows, evidence excerpts, and run metadata to key-value storage. Set `includeRawSnapshots` only when retaining capped HTML is appropriate for your workflow; it is off by default.

The report metadata records the actor, timestamp, row count, issue codes, severity totals, consumed input fields, pricing mode, platform-usage setting, and maximum-charge default. This provides a compact audit trail for scheduled comparisons.

### Pricing

This actor uses pay per event. Apify platform-usage pass-through is off. Charges are accepted before the corresponding paid dataset row or report is written.

| Event | Price |
| --- | ---: |
| `actor-start` | $0.08000 |
| `query-snapshot-scanned` | $0.01000 |
| `live-serp-page-rendered` | $0.02750 |
| `paa-question-extracted` | $0.00950 |
| `report-generated` | $0.18000 |

`maxChargeUsd` is a strict pre-output budget. A value of zero prevents the first charge and therefore prevents paid output. If Apify rejects a charge, partially accepts it, or reports an event limit, the actor stops before writing the affected output and records billing status.

Higher-tier Store discounts are expected where supported. The event prices above remain the locked base prices.

### Limits and predictable runs

- `maxPages`, `maxSnapshots`, and actor-specific record caps limit work before analysis.
- `maxQueries` limits distinct search contexts.
- Public fetches are additionally constrained by `allowedDomains`, `timeoutMs`, `requestDelayMs`, and a fetch cap.
- Reports are optional and raw HTML retention is opt-in.
- Query-only input produces an explicit source-required row instead of an empty or fabricated result.
- Dataset rows and report files follow the declared Actor schemas.

### Responsible use

Process only public content or material you are authorized to analyze. Respect website terms, rate limits, privacy obligations, intellectual-property rights, and applicable law. Avoid sending personal or confidential information in HTML or input records unless your workflow is authorized to process it.

# Actor input Schema

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

Optional explicit public URLs. Private, loopback, and non-HTTP targets are rejected.

## `sitemapUrls` (type: `array`):

Optional public XML sitemap URLs constrained by allowedDomains.

## `htmlInputs` (type: `array`):

Deterministic HTML objects with sourceId, sourceUrl, html/currentHtml, and optional query.

## `allowedDomains` (type: `array`):

Optional hostname allowlist for network fetches.

## `maxPages` (type: `integer`):

Overall hard cap on HTML targets processed.

## `maxDepth` (type: `integer`):

Reserved at zero: this runtime does not follow discovered links.

## `includeEvidence` (type: `boolean`):

Include visible evidence snippets in dataset rows.

## `includeRawSnapshots` (type: `boolean`):

Store capped supplied/fetched HTML in key-value storage.

## `requestDelayMs` (type: `integer`):

Delay between permitted fetches.

## `timeoutMs` (type: `integer`):

Per-request timeout in milliseconds.

## `userAgentMode` (type: `string`):

Use the standard actor agent or a compatibility browser-style agent.

## `queries` (type: `array`):

Queries associated with supplied snapshots.

## `serpHtmlInputs` (type: `array`):

Captured SERP HTML objects containing visible People Also Ask markup.

## `maxQueries` (type: `integer`):

Maximum distinct queries processed.

## `maxSnapshots` (type: `integer`):

Maximum supplied or fetched snapshots processed.

## `maxQuestionsPerQuery` (type: `integer`):

Maximum visible question records emitted per query.

## `maxBrowserPages` (type: `integer`):

Hard cap on explicitly supplied public snapshot URLs fetched.

## `expandQuestionsWhenPossible` (type: `boolean`):

Report when an expanded answer is absent; this runtime does not simulate browser clicks.

## `dedupeQuestions` (type: `boolean`):

Emit one row per normalized question.

## `questionClusterMode` (type: `string`):

Apply deterministic intent clusters or disable clustering.

## `maxChargeUsd` (type: `number`):

Maximum accepted PPE spend before the actor stops without emitting unpaid output.

## `includeReport` (type: `boolean`):

Write Markdown, CSV, JSON evidence, and run metadata to key-value storage.

## Actor input object example

```json
{
  "startUrls": [],
  "sitemapUrls": [],
  "htmlInputs": [],
  "allowedDomains": [],
  "maxPages": 1,
  "maxDepth": 0,
  "includeEvidence": true,
  "includeRawSnapshots": false,
  "requestDelayMs": 250,
  "timeoutMs": 15000,
  "userAgentMode": "standard",
  "queries": [
    "project management software"
  ],
  "serpHtmlInputs": [],
  "maxQueries": 1,
  "maxSnapshots": 1,
  "maxQuestionsPerQuery": 20,
  "maxBrowserPages": 1,
  "expandQuestionsWhenPossible": false,
  "dedupeQuestions": true,
  "questionClusterMode": "intent",
  "maxChargeUsd": 50,
  "includeReport": true
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `report` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/people-also-ask-question-extractor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("junipr/people-also-ask-question-extractor").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 '{}' |
apify call junipr/people-also-ask-question-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,junipr/people-also-ask-question-extractor"
        }
    }
}

```

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/XpG8mDghD4rcbL71C/builds/5rd4MAoII91wRSqyO/openapi.json
