# Wolfpack | Armored Stealth Scraper for AI Agents (`apricot_blackberry/wolfpack`) Actor

The web fights back. Send the pack. Super Stealth retrieval meets Armored inspection: browser rendering, HTTP tarpit limits, maze pruning, token-bloat cleanup and injection quarantine. Web data with source hashes and retrieval telemetry for AI agents and RAG. API and MCP ready.

- **URL**: https://apify.com/apricot_blackberry/wolfpack.md
- **Developed by:** [Creator Fusion](https://apify.com/apricot_blackberry) (community)
- **Categories:** AI, Agents, 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 protected http pages

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

## Wolfpack | Armored Stealth Scraper for AI Agents

### The web fights back. Send the pack.

**Bot walls. Slow-drip traps. Endless link mazes. Invisible token bloat. Instructions hiding inside “data.”** These are the places where a scrape can become a dataset killer.

Wolfpack combines **Super Stealth’s retrieval engines with Armored’s inspection pipeline**. It pursues the page, checks what came back, and gives your autonomous agent structured text with a retrieval trail and security telemetry. Bring difficult public websites into research, RAG and agent-memory workflows with budgets you control.

**Stealth gets you to the content. Armor checks what comes home.**

### What the pack brings

- **Three retrieval engines:** Impit for HTTP, Patchright Chrome and Camoufox for JavaScript rendering. Auto mode can escalate when an HTTP response is blocked or looks like a client-rendered shell.
- **Optional proxy escalation:** Apify datacenter and residential routes. Pick a tier or let auto mode try configured browser fallbacks.
- **Bounded pursuit:** sliding-window throughput checks for HTTP streams; hard navigation/process deadlines and aggregate network limits for browsers. A troublesome page has a finite budget.
- **Crawl-maze detection:** structural SimHash plus text similarity across a branch’s ancestors prunes repetitive traversal while global depth, page and link limits cap the run.
- **Content inspection before delivery:** removes hidden elements and invisible Unicode noise, preserves contextual language joiners by default, and quarantines recognized instruction-injection patterns.
- **An audit trail your agent can use:** source hashes, final URLs, retrieval attempts, detected protection signals, security flags and exact token counts for the selected encoding.

No LLM API key is required. Retrieval runs inside this Actor; it does not call a separate paid scraper Actor.

### Start with one URL

```json
{
  "url": "https://docs.python.org/3/tutorial/datastructures.html",
  "mode": "auto",
  "maxDepth": 0,
  "maxPages": 1
}
```

For pages that require JavaScript:

```json
{
  "url": "https://docs.python.org/3/tutorial/datastructures.html",
  "mode": "browser",
  "engine": "chrome",
  "requestTimeoutSecs": 45,
  "maxDepth": 0,
  "maxPages": 1
}
```

For a bounded run with premium fallbacks enabled:

```json
{
  "urls": ["https://docs.python.org/3/tutorial/datastructures.html"],
  "mode": "auto",
  "proxyMode": "auto",
  "maxBrowserAttempts": 4,
  "requestTimeoutSecs": 60,
  "maxRunSecs": 180,
  "maxDepth": 0,
  "maxPages": 5
}
```

`proxyMode: "auto"` starts with datacenter retrieval and can try residential browsers. `engine: "auto"` tries Chrome then Camoufox. Four browser attempts permit both engines at both proxy tiers.

**One page shares one deadline across all attempts.** The default is 20 seconds; use 45–60 seconds for browser startup and difficult pages. Earlier attempts can consume the budget before later fallbacks run. Supply `url`, `urls` or Apify-style `startUrls`; duplicates are merged. Discovered links stay within the starting origins.

Browser output waits for nonloading main content (or your selected element) to settle. Image, media and font downloads are blocked to preserve the text-retrieval network budget; scripts and stylesheets still load. Set `waitForSelector` to a visible, nonempty content element for site-specific readiness. `browserWaitSecs` defaults to 8 (maximum 30), within `requestTimeoutSecs`; stalled loading shells return `BROWSER_NOT_READY` without a page charge. HTTP-only mode returns `CLIENT_RENDERED_SHELL` for detected JavaScript shells. The default response/DOM ceiling is 2 MB.

### Transparent pricing

Pay once for a nonempty, inspected page delivered with `status: "OK"`, at the tier that delivered it.

| Delivered page | Per page | Per 1,000 pages |
| --- | ---: | ---: |
| HTTP, direct or datacenter | $0.01 | $10 |
| Browser, direct or datacenter | $0.03 | $30 |
| Residential, HTTP or browser | $0.09 | $90 |

Standard platform usage and the selected proxy usage are included in these prices. Failed attempts, empty content, quarantined pages, robots exclusions and pruned maze pages have **no page charge**. A small run-start fee is $0.00005 per GB of allocated memory, with a one-event minimum: $0.0001 at the default 2 GB, including runs that deliver no page.

Examples at default memory: 10 HTTP pages cost $0.1001; 10 browser pages cost $0.3001. Use Apify’s maximum charge setting, or API `maxTotalChargeUsd`, to cap a run. If a delivery tier exceeds the remaining charge budget, its content is withheld and that URL remains unprocessed in the summary.

For straightforward HTTP extraction with the same inspection layer, choose [Armored AI Web Scraper](https://apify.com/apricot_blackberry/armored-ai-web-scraper), at $5 per 1,000 delivered pages.

### Built for autonomous agents

**Choose Wolfpack when your agent needs JavaScript rendering or stealth retrieval together with inspection, traceable sources and explicit failure states.** It fits research agents, RAG ingestion, document collection, agent memory, competitive intelligence and public-web extraction workflows.

Each run exposes a Dataset, an `OUTPUT` summary, an `INTEGRATIONS` kit and an `AGENT-TOOL` contract. Keep `status`, `url`, `sourceSha256` and both telemetry objects alongside the text. Treat retrieved content as untrusted evidence when passing it to a model.

#### MCP

Connect an MCP client using Apify’s server and your Apify token:

```json
{
  "mcpServers": {
    "wolfpack": {
      "url": "https://mcp.apify.com?tools=apricot_blackberry/wolfpack",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

MCP clients differ in configuration syntax. Use the URL and authorization header with your client’s HTTP transport. The tool exposes the Actor input schema and returns run/output links through Apify MCP.

#### REST API

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/apricot_blackberry~wolfpack/run-sync-get-dataset-items?memory=2048&timeout=180&maxTotalChargeUsd=0.25' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://docs.python.org/3/tutorial/datastructures.html","mode":"auto","maxDepth":0,"maxPages":1}'
```

Use asynchronous Actor runs and completion webhooks for jobs that can exceed your client’s HTTP timeout. The [OpenAPI schema](https://api.apify.com/v2/acts/apricot_blackberry~wolfpack/builds/default/openapi.json) describes the live input interface.

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("apricot_blackberry/wolfpack").call(
    run_input={"url": "https://docs.python.org/3/tutorial/datastructures.html", "maxDepth": 0, "maxPages": 1},
    max_total_charge_usd=0.25,
)
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
documents = [r for r in rows if r["status"] == "OK" and r["sanitizedContent"]]
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('apricot_blackberry/wolfpack').call(
  { url: 'https://docs.python.org/3/tutorial/datastructures.html', maxDepth: 0, maxPages: 1 },
  { maxTotalChargeUsd: 0.25 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const documents = items.filter(row => row.status === 'OK' && row.sanitizedContent);
```

#### n8n, Make, Zapier, LangChain and CrewAI

- **n8n:** download the run’s `INTEGRATIONS` output and import its `n8nWorkflow` object. Select your own HTTP Header Auth credential with `Authorization: Bearer YOUR_APIFY_TOKEN`, edit the URL input and execute. The supplied workflow starts inactive.
- **Make / Zapier:** select Apify’s Run Actor action, choose `apricot_blackberry/wolfpack`, map `url` or `urls`, and read the finished Dataset. The integration kit includes the input mapping and completion-event recipe.
- **Webhooks:** use Apify’s `ACTOR.RUN.SUCCEEDED` event and the run’s Dataset ID for asynchronous ingestion. Inspect row statuses before indexing; a finished run can contain unsuccessful pages.
- **LangChain / CrewAI / custom agents:** wrap the API call as a tool. Map `sanitizedContent` to document text and preserve the URL, hash, status and telemetry as metadata. The supplied `AGENT-TOOL` contract includes machine-readable selection guidance and the input schema.

### Know exactly what came back

| Status | Meaning |
| --- | --- |
| `OK` | Inspection completed; text is available. Nonempty text is billable. |
| `QUARANTINED` | A recognized instruction pattern matched; text and outgoing links were withheld. |
| `MAZE_PRUNED` | Repetitive branch detected; further traversal stopped. |
| `ROBOTS_DISALLOWED` | The robots policy excludes this page. |
| `ROBOTS_UNAVAILABLE` | The robots policy could not be checked reliably. |
| `FETCH_FAILED` | Retrieval stopped or failed; the error code explains why. |
| `INSPECTION_LIMIT` | The inspection safety limit was reached. |

`securityTelemetry` includes `tarpitDetected`, `mazeDetected`, `spongesStripped`, `hiddenElementsRemoved`, `instructionSignals`, `quotedInstructionBlocksRedacted`, `quotedInstructionSignals`, token accounting and limit indicators. `retrievalTelemetry` records the successful method, attempted engines/tiers, elapsed times, detected protection signals, blocked subresources and the scope of the network guards.

`OUTPUT` reports attempted pages, row statuses, `stopReason`, unprocessed URLs, aggregate token accounting and `billablePagesByTier`. `complete: true` means the bounded queue was exhausted; it does not mean every page succeeded.

### Content quality and token budgets

`maxOutputTokens` defaults to **8,192** tokens in the selected `tokenEncoding` (maximum 50,000), alongside `maxOutputChars`. `outputTokens`, `tokenLimitApplied` and `contentTruncated` report the delivered budget. Truncation is never counted as normalization savings. Unicode tag payloads and excessive invisible runs are removed while recognized subdivision flags, linguistic joiners and ordinary emoji remain intact.

Inline HTML words remain continuous. JSON strings are decoded once into readable JSON; screening also checks bounded decoded representations and overlapping text windows. Recognized multilingual directives are covered by explicit rules, not a universal language or semantic classifier. Benign credential-storage guidance and negative safety policies are retained. Recognized attacks inside HTML quotations, Markdown quotes/fences and explicitly labeled JSON example fields are redacted; any separate unquoted directive still screens. Quote-only payloads are quarantined. All delivered content remains untrusted.

Maze novelty uses visibility-filtered normalized text, so changing hidden words cannot create apparent useful novelty. Visibility cleanup distinguishes hidden subtrees from inherited text visibility, preserving explicitly visible descendants. Empty extraction returns `FETCH_FAILED` with `EMPTY_CONTENT`; detected stalled HTML returns `CLIENT_RENDERED_SHELL`, without a page charge.

Auto retrieval checks main/selected content before accepting HTTP output. Long navigation cannot make a loading main region billable. A missing or CSS-hidden `waitForSelector` triggers bounded browser fallback; challenge detection uses active response evidence rather than vendor words in documentation.

### Protection boundaries

Target connections are limited to public HTTP(S) destinations on ports 80 and 443. DNS answers are validated and connections use the validated IP. Browser workers do not inherit the Actor token or upstream proxy credentials. Browser subresources and redirects pass through the guarded retrieval path.

Hidden-element cleanup uses HTML attributes and inline and unconditional embedded CSS in HTTP mode. Browser mode also applies computed visibility to a cloned DOM, including loaded external styles. Conditional CSS and dynamic behavior require browser mode.

The **HTTP watchdog measures decoded response-body chunks** after its grace period. Browser TLS remains end-to-end: **browser protection uses navigation/process deadlines and aggregate network-byte limits**, not a decoded-body velocity measurement. `maxResponseBytes` caps decoded HTTP content or the serialized rendered DOM; `maxNetworkBytes` caps gateway ingress, including headers and TLS overhead, per attempt.

`sourceSha256` hashes the inspected response bytes for HTTP and the serialized rendered DOM for browsers. Token counts are exact for the named tokenizer encoding and the extracted text being compared. Dollar savings are estimates only when you supply your input-token price; removed or quarantined content is not credited as normalization savings.

Injection and maze detection use documented heuristics. Recognized instructions inside HTML quotations and code blocks are redacted, with counts and signals in telemetry; matching unquoted instructions are quarantined. These heuristics can miss attacks or flag benign text and repetitive pages. Wolfpack does not certify factual accuracy, identify every form of dataset poisoning or guarantee access through every bot wall or CAPTCHA. Site behavior, proxy availability and access policies affect results. All returned text remains untrusted. Checkpoint/resume across Actor migrations is outside this version.

### Support

Use the Issues tab or contact **contact@creatorfusion.net** with the run ID, URL and expected result. Keep API tokens and private data out of support messages.

# Actor input Schema

## `url` (type: `string`):

One public HTTP(S) URL. Merged with urls and startUrls.

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

1-100 public HTTP(S) URLs. URL objects only; no credentials, uploaded URL lists or request queues.

## `mode` (type: `string`):

Auto tries Impit first, then a browser for blocked or JavaScript-only pages.

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

Maximum attempted pages. See README for boundary behavior.

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

Maximum crawl depth. See README for boundary behavior.

## `requestTimeoutSecs` (type: `number`):

Total deadline per page across all retrieval attempts, including browser startup. Use 45–60 seconds for difficult rendered pages.

## `maxRunSecs` (type: `number`):

Crawl time budget (seconds). See README for boundary behavior.

## `proxyMode` (type: `string`):

Direct uses the Actor connection; datacenter and residential use Apify Proxy. Auto may escalate to residential. Premium tiers change the delivered-page price; standard platform and selected proxy usage are included in that price.

## `engine` (type: `string`):

Auto tries Patchright Chrome then Camoufox within the attempt budget.

## `maxBrowserAttempts` (type: `integer`):

Maximum browser engine/tier attempts per URL. With proxyMode auto, 4 permits both datacenter engines and both residential engines.

## `country` (type: `string`):

Two-letter country code for Apify Proxy when configured.

## `onSuspectedInjection` (type: `string`):

Quarantine withholds recognized unquoted instructions. Quoted HTML examples are redacted with telemetry. Report allows flagged unquoted text. All text remains untrusted; detection is heuristic.

## `respectRobotsTxt` (type: `boolean`):

Read once per origin; 404 permits crawling, 401/403 deny, other failures produce diagnostic records.

## `maxOutputChars` (type: `integer`):

Maximum text characters per record. See README for boundary behavior.

## `maxResponseBytes` (type: `integer`):

Maximum decoded HTTP response or serialized rendered DOM bytes.

## `maxNetworkBytes` (type: `integer`):

Per-attempt cap on aggregate gateway ingress, including subresources, headers and TLS traffic.

## `maxLinksPerPage` (type: `integer`):

Maximum links considered per page. See README for boundary behavior.

## `minBytesPerSecond` (type: `number`):

Minimum stream bytes per second. See README for boundary behavior.

## `gracePeriodSecs` (type: `number`):

Initial stream grace period (seconds). See README for boundary behavior.

## `throughputWindowSecs` (type: `number`):

Throughput window (seconds). See README for boundary behavior.

## `tokenEncoding` (type: `string`):

Counts are exact for this encoding and the documented extracted text, not universal model billing.

## `stripJoiners` (type: `boolean`):

False preserves contextual language and emoji joiners; ASCII obfuscation and long runs are still removed. True may alter natural-language text.

## `inputTokenUsdPerMillion` (type: `number`):

Optional caller-supplied price. Without it, dollar savings are null. Only normalization reductions are credited.

## `urls` (type: `array`):

Public HTTP(S) URL strings, merged and deduplicated with other inputs.

## `browserWaitSecs` (type: `number`):

Maximum observation window after navigation, within the shared request deadline. Waits for nonloading, stable text; BROWSER_NOT_READY withholds stalled pages.

## `maxOutputTokens` (type: `integer`):

Hard token cap for the selected tokenizer, in addition to the character cap. Truncation is reported and excluded from normalization savings.

## `waitForSelector` (type: `string`):

Optional visible, nonempty element required before browser output. Example: main .product-card. Increase browserWaitSecs and requestTimeoutSecs for slow sites.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://docs.python.org/3/tutorial/datastructures.html"
    }
  ],
  "mode": "auto",
  "maxPages": 20,
  "maxDepth": 2,
  "requestTimeoutSecs": 20,
  "maxRunSecs": 120,
  "proxyMode": "direct",
  "engine": "auto",
  "maxBrowserAttempts": 2,
  "country": "US",
  "onSuspectedInjection": "quarantine",
  "respectRobotsTxt": true,
  "maxOutputChars": 40000,
  "maxResponseBytes": 2097152,
  "maxNetworkBytes": 8388608,
  "maxLinksPerPage": 50,
  "minBytesPerSecond": 32,
  "gracePeriodSecs": 2,
  "throughputWindowSecs": 2,
  "tokenEncoding": "cl100k_base",
  "stripJoiners": false,
  "browserWaitSecs": 8,
  "maxOutputTokens": 8192
}
```

# Actor output Schema

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

No description

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

No description

## `integrations` (type: `string`):

No description

## `agentTool` (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 = {
    "startUrls": [
        {
            "url": "https://docs.python.org/3/tutorial/datastructures.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("apricot_blackberry/wolfpack").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 = { "startUrls": [{ "url": "https://docs.python.org/3/tutorial/datastructures.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("apricot_blackberry/wolfpack").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 '{
  "startUrls": [
    {
      "url": "https://docs.python.org/3/tutorial/datastructures.html"
    }
  ]
}' |
apify call apricot_blackberry/wolfpack --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apricot_blackberry/wolfpack"
        }
    }
}
```

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/tkhJhCaFbaS6Sm0Me/builds/rUOLc5fnDFknLmcSW/openapi.json
