# SERP Feature Snapshot Extractor (`junipr/serp-feature-snapshot-extractor`) Actor

Detect and extract visible SERP features such as featured snippets, image packs, video blocks, local packs, shopping blocks, knowledge panels, top stories, and result modules.

- **URL**: https://apify.com/junipr/serp-feature-snapshot-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?

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

## SERP Feature Snapshot Extractor

Detect and extract visible SERP features such as featured snippets, image packs, video blocks, local packs, shopping blocks, knowledge panels, top...

### Who it is for

SERP Feature Snapshot Extractor helps seo teams, content strategists, serp feature analysts, agencies detect and extract visible SERP features such as featured snippets, image packs, video blocks, local packs, shopping blocks, knowledge panels, top stories, and result modules. It produces schema-valid dataset rows, evidence-backed KVS reports, safe diagnostics, and capped pay-per-event pricing for predictable Apify Store runs.

Inventory visible featured snippets, image packs, video modules, local packs, shopping blocks, knowledge panels, and top-stories modules. Each row preserves the visible module text, owner domain when linked, position, item count, and source snapshot key.

### 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 `serpHtmlInputs` or `htmlInputs` with captured search-page HTML.
- Use `featureTypes` to limit output to normalized module types such as `featured_snippet` or `local_pack`.
- Use `startUrls` only for public URLs that return the search-page HTML you are authorized to process.
- Set `includeModuleScreenshots` to receive a clear snapshot-reference note; this runtime records HTML evidence and does not create image files.

### Example input

```json
{
  "queries": [
    "best crm"
  ],
  "serpHtmlInputs": [
    {
      "sourceUrl": "https://example.com/serp",
      "query": "best crm",
      "html": "<section class=\"featured-snippet\" data-position=\"1\"><h2>What is a CRM?</h2><p>A CRM organizes customer relationships.</p><a href=\"https://vendor.example/guide\">Source</a></section>"
    }
  ],
  "featureTypes": [
    "featured_snippet"
  ],
  "maxFeaturesPerSnapshot": 25,
  "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.

- `featureType` and `featurePosition`
- visible feature title, text, evidence excerpt, and item count
- first visible feature URL and owner domain when present
- query, source status, and stable snapshot key

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 |
| `serp-feature-record-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.

## `searchEngine` (type: `string`):

Source engine label attached to rows.

## `countryCode` (type: `string`):

ISO country context for the supplied snapshot.

## `languageCode` (type: `string`):

Language context for the supplied snapshot.

## `deviceProfile` (type: `string`):

Device context for the supplied snapshot.

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

Captured SERP HTML objects with optional query, sourceUrl, and searchEngine.

## `featureTypes` (type: `array`):

Optional normalized feature types such as featured_snippet or local_pack.

## `includeModuleScreenshots` (type: `boolean`):

Add an explicit note that snapshot keys—not generated images—identify modules.

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

Maximum distinct queries processed.

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

Maximum supplied or fetched snapshots processed.

## `maxFeaturesPerSnapshot` (type: `integer`):

Maximum visible feature records emitted per snapshot.

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

Hard cap on explicitly supplied public snapshot URLs fetched.

## `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": [
    "best project management software"
  ],
  "searchEngine": "google",
  "countryCode": "US",
  "languageCode": "en",
  "deviceProfile": "desktop",
  "serpHtmlInputs": [],
  "featureTypes": [],
  "includeModuleScreenshots": false,
  "maxQueries": 1,
  "maxSnapshots": 1,
  "maxFeaturesPerSnapshot": 25,
  "maxBrowserPages": 1,
  "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/serp-feature-snapshot-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/serp-feature-snapshot-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/serp-feature-snapshot-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,junipr/serp-feature-snapshot-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/Ja1Mawmb6K7cmgtzi/builds/0KF7yEBlzrYvvBu3M/openapi.json
