# SpyFu Domain Intelligence Scraper (`clearpath/spyfu-scraper`) Actor

Scrape SpyFu domain data: competitors, organic and paid keywords, rank history, ad history and backlinks with monthly time series. Structured JSON export.

- **URL**: https://apify.com/clearpath/spyfu-scraper.md
- **Developed by:** [ClearPath](https://apify.com/clearpath) (community)
- **Categories:** SEO tools, Automation
- **Features:** Limited permissions
- **Stats:** 91 total users, 33 monthly users, 92.6% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.99 / 1,000 domains

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

## SpyFu Intelligence | Domain Competitive Intelligence from SpyFu (2026)

[![Keyword rankings. Search volume. SEO clicks. Ranking difficulty.](https://api.apify.com/v2/key-value-stores/pJ7iaZsTFhR3k9tjV/records/spyfu-scraper-readme-hero-v1.png)](https://console.apify.com/actors/7Fs85gfq1XtijG7IC/input)

From <strong>Clearpath</strong>, creators of <a href="https://apify.com/clearpath/email-finder-api">Email Finder</a> and <a href="https://apify.com/clearpath/shopify-store-leads">Shopify Store Leads</a>, with <strong>170,000+ combined runs</strong>. Business research and enrichment tools used across the Apify Store.

### Why choose this actor?

<strong>Compare demand, competition and traffic.</strong> Each domain report contains <strong>13 data sections</strong>; the hero shows just five fields from one keyword record. Get <code>searchVolume</code>, <code>rankingDifficulty</code>, <code>rank</code> and <code>seoClicks</code> alongside the keyword and its ranking URL. Assess which terms deserve a closer look, with the metrics in the same record.

<strong>See how competitors change over time.</strong> Monthly organic clicks, estimated ad budgets and ranking history help you track growth and shifts in search strategy. Established domains can include history back to 2006.

<strong>Research the right market.</strong> Choose from 32 country datasets. Each report also lists the domain’s keyword counts by country and flags its primary market, alongside competitors, ad history and backlink samples.

<a href="https://console.apify.com/actors/7Fs85gfq1XtijG7IC/input"><img src="https://api.apify.com/v2/key-value-stores/pJ7iaZsTFhR3k9tjV/records/spyfu-scraper-readme-cta-v1.svg" width="234" height="48" alt="Research your domain"/></a>

### Quick start

Start with a domain and a country. Replace <code>apify.com</code> with a competitor or your own website.

```json
{
  "queries": [
    "apify.com"
  ],
  "countryCode": "US"
}
```

<a href="https://console.apify.com/actors/7Fs85gfq1XtijG7IC/input">Open actor input</a> to add your domains. Export JSON to preserve the nested keyword records and monthly histories.

Keyword and backlink lists are source-limited samples; domain totals are reported separately. Some ad text is unavailable. Coverage varies by domain and country.

<table>
<tr>
<td style="background:#2B72BB;color:#FFFFFF;padding:10px 14px;font-size:13px;font-weight:700;border-radius:4px 4px 0 0">Clearpath · Business Research &amp; Leads</td>
</tr>
<tr>
<td style="padding:6px;border:1px solid #C6DCF3;border-top:none;border-radius:0 0 4px 4px;background:#EDF5FF">
<span style="display:inline-block;vertical-align:top;margin:3px;padding:8px 8px;border:1px solid #C6DCF3;border-radius:4px;background:#D7E9FC"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-7Fs85gfq1XtijG7IC-y9u1RUdU14-spyfu-logo.png" width="20" height="20" alt="" style="vertical-align:middle"/>&nbsp;&nbsp;<a href="https://apify.com/clearpath/spyfu-scraper" style="color:#183B63;text-decoration:none;font-weight:700;font-size:13px">SpyFu</a></span><br><span style="color:#345576;font-size:12px;white-space:nowrap">You are here</span></span><span style="display:inline-block;vertical-align:top;margin:3px;padding:8px 8px;border:1px solid #C6DCF3;border-radius:4px;background:#EDF5FF"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-fVz6tfmTCAkBxvBbF-0Uk5X3JrAZ-dataforseo-scraper-logo.png" width="20" height="20" alt="" style="vertical-align:middle"/>&nbsp;&nbsp;<a href="https://apify.com/clearpath/dataforseo" style="color:#183B63;text-decoration:none;font-weight:700;font-size:13px">DataForSEO</a></span><br><span style="color:#345576;font-size:12px;white-space:nowrap">Keyword volume &amp; backlinks</span></span><span style="display:inline-block;vertical-align:top;margin:3px;padding:8px 8px;border:1px solid #C6DCF3;border-radius:4px;background:#EDF5FF"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-R9SL2PPdhdhLQwdck-tbaq4J8sxX-shopy-by-shopify-scraper-logo.jpg" width="20" height="20" alt="" style="vertical-align:middle"/>&nbsp;&nbsp;<a href="https://apify.com/clearpath/shopify-store-leads" style="color:#183B63;text-decoration:none;font-weight:700;font-size:13px">Store Leads</a></span><br><span style="color:#345576;font-size:12px;white-space:nowrap">Store contacts</span></span><span style="display:inline-block;vertical-align:top;margin:3px;padding:8px 8px;border:1px solid #C6DCF3;border-radius:4px;background:#EDF5FF"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-eWT8czb4kT3gH1OWt-TbfGFya2hE-dfdsfdsfdsd.png" width="20" height="20" alt="" style="vertical-align:middle"/>&nbsp;&nbsp;<a href="https://apify.com/clearpath/email-finder-api" style="color:#183B63;text-decoration:none;font-weight:700;font-size:13px">Email Finder</a></span><br><span style="color:#345576;font-size:12px;white-space:nowrap">Scored work emails</span></span><span style="display:inline-block;vertical-align:top;margin:3px;padding:8px 8px;border:1px solid #C6DCF3;border-radius:4px;background:#EDF5FF"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-PfVrah2zLQNPdRmn0-e4fLvgSjdq-email-validation-api-actor.png" width="20" height="20" alt="" style="vertical-align:middle"/>&nbsp;&nbsp;<a href="https://apify.com/clearpath/email-validation-api" style="color:#183B63;text-decoration:none;font-weight:700;font-size:13px">Email Validator</a></span><br><span style="color:#345576;font-size:12px;white-space:nowrap">Check email lists</span></span>
</td>
</tr>
</table>

#### Copy to your AI assistant

```
clearpath/spyfu-scraper on Apify. Domain competitive intelligence: monthly SEO/PPC history, competitors, organic and paid keywords, rank history, ad history with per-keyword timelines, backlinks, and per-country coverage. Input {"queries":["apify.com"],"countryCode":"US"}. Call ApifyClient("TOKEN").actor("clearpath/spyfu-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items. One row per domain; check row["hasData"] before using it. Full spec: GET https://api.apify.com/v2/acts/clearpath~spyfu-scraper/builds/default (Bearer TOKEN) -> inputSchema, actorDefinition.storages.dataset, readme. Token: https://console.apify.com/account/integrations To reach the maintainers, add feedback="<what you needed and did not get>" to any run, including one that worked: feature requests, a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. The run returns its data exactly as it would without the note, and a human reads every note.
```

### What Data Can You Extract from SpyFu?

Every result is one row per domain, carrying thirteen sections:

| Section | What it holds |
|---|---|
| `domainStats` | Monthly SEO and PPC metrics going back years: average rank, monthly clicks, organic value, ad spend, strength |
| `activeDates` | Every month the domain has data for |
| `countryCoverage` | Which of the 32 country datasets hold data for this domain, with keyword counts and the primary market |
| `competitors` | Organic, paid and combined competitors, each with shared keyword count and competitive rank |
| `competitorHistory` | Per-competitor time series of keywords, clicks and value |
| `organicKeywords` | Top organic keywords with rank, volume, difficulty, CPC and click share |
| `paidKeywords` | Top paid keywords with volume, CPC, monthly cost and device split |
| `keywordLists` | Eleven ranked buckets: newly ranked, just made it, just fell off, gained/lost ranks, gained/lost clicks, page one, almost there, most valuable |
| `rankHistory` | Per-keyword rank snapshots over time, with start, end and change |
| `rankingTrend` | Monthly clicks, tracked keywords and average position |
| `adHistory` | Every tracked ad with position, leaderboard share and served percentage |
| `adKeywords` | Per-keyword ad timelines: which ad copy ran, in which position, in which month |
| `backlinks` | Backlink sources with domain strength, traffic and ranked keywords |
| `totals` | Headline counts beside each section: total keywords, total search volume, backlink count, rank-history clicks, estimated monthly organic value |

Each row also carries `hasData`, which is `false` when the source tracks nothing for that domain, and `incompleteSections`, naming any field that could not be loaded.

Ad records whose creative text is gated behind a login are kept for their placement metrics, with the text fields set to `null` and `creativeAvailable: false`.

### How to Scrape SpyFu Domain Data

Add one or more domains. Everything else is optional.

```json
{
  "queries": ["apify.com"]
}
```

Full URLs are accepted and reduced to the domain, so `https://www.apify.com/store` and `apify.com` are the same input. Add a country to pull a different market's dataset:

```json
{
  "queries": ["apify.com", "scrapingbee.com"],
  "countryCode": "UK"
}
```

#### Input Parameters

| Parameter | Type | Default | Meaning |
|---|---|---|---|
| `queries` | array | *required* | Domains to scrape, one row of output each. Full URLs are normalized. Entries that are not a usable domain are skipped and reported in the run log. |
| `countryCode` | string | `US` | Which country's dataset to read, from a 32-entry dropdown. |

The United Kingdom is `UK` in this dataset, not the ISO `GB`. Both are accepted and `GB` is treated as `UK`, so older saved tasks keep working. If you are unsure which market holds the data for a domain, run it once and read `countryCoverage` in the result: it lists the keyword count for all 32 countries and flags the primary one.

### Output Example

One row per domain. The blocks below are real excerpts from a live run on `apify.com`, shortened to one or two entries per array; the counts that row actually returned are listed after them.

**Row header and totals**

Every row opens with these, then the thirteen section arrays. `totals` is not subject to the row-sample cap described below.

```json
{
  "query": "apify.com",
  "normalizedQuery": "apify.com",
  "countryCode": "US",
  "scrapedAt": "2026-09-21T08:24:51.326198+00:00",
  "hasData": true,
  "totals": {
    "domainStats": {
      "domain": "apify.com",
      "totalResults": 111
    },
    "organicKeywords": {
      "total": 99687,
      "unfilteredTotal": 99845,
      "adultKeywordTotal": 0,
      "totalVolume": 0,
      "totalSeoClicks": 0,
      "totalSeoClicksChange": 0,
      "isValid": true
    },
    "paidKeywords": {
      "totalResults": 6003,
      "totalUnfilteredResults": 6003,
      "adultKeywordTotal": 0,
      "totalVolume": 1209443,
      "monthlyClicksTotal": 0,
      "monthlyBudget": 0,
      "adultFilter": true
    },
    "rankHistory": {
      "totalKeywords": 68678,
      "totalVolume": 11645448,
      "totalClicks": 23600,
      "totalClicksChange": 404,
      "totalRankChange": 3216286,
      "rankAverage": 26.73420020339968,
      "rankAverageChange": 17.29389669969722,
      "isValid": true
    },
    "adHistory": {
      "keywordCount": 6383
    },
    "backlinks": {
      "totalResults": 202
    },
    "seoOverview": {
      "total": 99845,
      "totalEstimatedOrganicClicks": 101196,
      "totalEstimatedOrganicClicksChange": -91025,
      "estimatedMonthlyOrganicValue": 590529.9104683995
    }
  },
  "incompleteSections": []
}
```

**`domainStats`**

One record per month of coverage, 107 for this domain, oldest first.

```json
[
  {
    "searchDate": "201710",
    "averageOrganicRank": 20.7,
    "monthlyPaidClicks": 0,
    "averageAdRank": 0,
    "totalOrganicResults": 279,
    "monthlyBudget": 0,
    "monthlyOrganicValue": 454.84131445904956,
    "totalAdsPurchased": 0,
    "monthlyOrganicClicks": 850.0616973757677,
    "strength": 0,
    "totalInverseRank": 1120,
    "hasData": true,
    "year": 2017,
    "month": 10,
    "domain": "apify.com",
    "totalResults": 111
  }
]
```

**`organicKeywords`**

Full keyword record. The `topLevel` to `fifthLevel` grouping fields are returned as null for every keyword.

```json
[
  {
    "topLevel": null,
    "secondLevel": null,
    "thirdLevel": null,
    "fourthLevel": null,
    "fifthLevel": null,
    "keyword": "true people search",
    "termId": "42413492",
    "domainId": "-1597208197357761749",
    "urlId": "-2054134300595655663",
    "topRankedUrl": "https://apify.com/scrapyspider/truepeoplesearch-contact-finder",
    "rank": 3,
    "rankChange": null,
    "searchVolume": 104000,
    "rankingDifficulty": 9,
    "broadCostPerClick": null,
    "phraseCostPerClick": null,
    "exactCostPerClick": null,
    "seoClicks": 5900,
    "seoClicksChange": null,
    "totalMonthlyClicks": 96200,
    "percentMobileSearches": 0.599452152352474,
    "percentDesktopSearches": 0.400547847647526,
    "percentNotClicked": 0.0750096166175151,
    "percentPaidClicks": 0.00644579983321002,
    "percentOrganicClicks": 0.99355420009748,
    "broadMonthlyCost": null,
    "phraseMonthlyCost": null,
    "exactMonthlyCost": null,
    "paidCompetitors": 3,
    "rankingHomepages": 8,
    "yourRank": null,
    "yourRankChange": null,
    "yourUrl": ""
  }
]
```

**`adKeywords`**

Which ad copy ran on a keyword and when. 50 keywords for this domain, each with its own dated `ads` timeline.

```json
[
  {
    "ads": [
      {
        "adId": 308936811,
        "searchDate": "20260601",
        "searchDateId": 20260601,
        "position": 3,
        "title": "Apify",
        "body": "Unlimited API web scraping — Find hundreds of ready-made Actors for your web scraping or automation project. Extremely scalable and hassle-free full-stack platform for all your web automation needs. Extract and download data.",
        "domainName": "apify.com",
        "fullUrl": "https://apify.com/",
        "term": "api",
        "termId": 110994,
        "adCount": 3,
        "isLeaderboardAd": false,
        "isThrottled": false,
        "creativeAvailable": true,
        "year": 2026,
        "month": 6
      }
    ],
    "termId": 110994,
    "term": "api",
    "clicksPerMonth": 91800,
    "costPerClick": 4.1,
    "adCount": 3,
    "potentialViews": 12,
    "termAdCount": 3,
    "coverage": 0.25,
    "isThrottled": false,
    "creativeAvailable": true
  }
]
```

**`adKeywords`, gated record**

Where the source withholds the text behind a login the record is still returned for its placement metrics, with the text fields null and `creativeAvailable` false.

```json
[
  {
    "termId": 32876173,
    "term": null,
    "clicksPerMonth": 0,
    "costPerClick": 0,
    "adCount": 2,
    "potentialViews": 0,
    "termAdCount": 1,
    "coverage": 0.08333333333333333,
    "isThrottled": true,
    "creativeAvailable": false
  }
]
```

**`countryCoverage`**

Where this domain actually has data, so you can tell whether another country would return more. Sorted with the primary market first.

```json
[
  {
    "countryCode": "US",
    "hasAdHistory": true,
    "hasRankHistory": true,
    "keywords": 107600,
    "isPrimary": true
  },
  {
    "countryCode": "UK",
    "hasAdHistory": true,
    "hasRankHistory": true,
    "keywords": 30660,
    "isPrimary": false
  }
]
```

#### Records per section

From the same run, 442 nested records in total:

| Section | Records for `apify.com` |
|---|---|
| `domainStats` | 107 |
| `activeDates` | 107 |
| `countryCoverage` | 32 |
| `competitors` | 15 |
| `competitorHistory` | 10 |
| `organicKeywords` | 5 |
| `paidKeywords` | 5 |
| `keywordLists` | 11 |
| `rankHistory` | 5 |
| `rankingTrend` | 13 |
| `adHistory` | 77 |
| `adKeywords` | 50 |
| `backlinks` | 5 |

#### Exporting the results

Each row nests thirteen arrays, several of them holding their own arrays. Use the JSON or JSONL export to keep that structure intact. The CSV and Excel exports flatten nested data into one column per leaf, which for a domain with 243 months of history and 226 ads produces thousands of columns and is rarely what you want. To work with one section as a flat table, export JSON and select that key, or use the dataset API's `fields` parameter.

### Pricing

You are charged per domain processed. **$7.99 per 1,000 domains** at the base rate, with volume discounts by plan.

**Domain charges**

| Plan | Price per 1,000 domains |
|---|---|
| Free / Bronze | $7.99 |
| Silver | $7.49 |
| Gold / Platinum / Diamond | $6.99 |

A 100-domain run on the Bronze rate costs $0.80 in domain charges.

Domains the source does not track are returned with `hasData: false` and are not charged, and neither is a row that came back mostly empty.

Free tier: 5 lifetime runs, 5 domains per run.

### FAQ

**How much data does each domain return?**
One dataset row per domain, holding thirteen sections. Across a five-domain sample the rows carried 339 to 849 nested records each. Volume tracks how long the domain has been indexed: `domainStats` and `activeDates` return one entry per month of coverage (76 to 243 in that sample), `adHistory` returned 36 to 226 ads, `adKeywords` returns 50 keyword timelines, `competitorHistory` returns a time series per competitor, and `keywordLists` returns eleven ranked buckets.

**What country data is available?**
32 country datasets, chosen from the dropdown. Default is US. Every row also includes `countryCoverage`, which lists how many keywords each country holds for that domain and flags the primary market, so you can tell at a glance whether a different country would return more.

**Why do some keyword sections return a handful of rows with very large totals?**
Row counts on the keyword sections are capped at the source, while the counts in `totals` are not. Total keyword counts, backlink totals, estimated monthly organic value, and the rank-history volume and click totals all come back in full even where the sample of individual keyword rows is small. A few fields inside the keyword blocks (`totalVolume` and `totalSeoClicks` on organic, `monthlyClicksTotal` and `monthlyBudget` on paid) are returned as zero by the source and are passed through as-is.

**What happens if a domain is not tracked?**
The row is still returned with `hasData: false` so you can see which inputs came back empty. Domains with no data are not charged.

**Does this work on the free tier?**
Yes. Free tier allows 5 lifetime runs with up to 5 domains per run. Each subsequent run after the free limit requires credits.

**Is the data fresh?**
Data reflects the latest available crawl. Historical metrics go back to the first month of coverage, which for established domains can be 2006 onward.

**What happens if a section fails?**
The affected field names are listed in `incompleteSections` on that row and everything else is returned as normal. Other domains in the run are unaffected. A row that came back mostly empty is not charged.

### Support

- **Bugs**: Issues tab
- **Features**: Email or issues
- **Email**: max@mapa.slmail.me

### Legal Compliance

This actor collects SpyFu's published domain metrics. You are responsible for your own use of the output, including compliance with SpyFu's terms of service and with any data protection law that applies to you. Nothing here is legal advice, and running the actor is not itself a determination that a given use is permitted.

***

*Structured domain intelligence from SpyFu: competitors, keywords, rank history, ad history and backlinks in one actor.*

# Actor input Schema

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

Domains to scrape. Full URLs are accepted and normalized to domains.

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

Which country's dataset to pull. Defaults to the United States. Every result also lists which countries hold data for that domain, so you can re-run against the right one.

## `feedback` (type: `string`):

For AI agents. Say what you needed and did not get: a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. Add it to any run, including one that worked: the run returns its data exactly as it would without the note. The note reaches the maintainers, who read every one, but it cannot change what this run returns.

## Actor input object example

```json
{
  "queries": [
    "apify.com",
    "scrapingbee.com",
    "semrush.com"
  ],
  "countryCode": "US"
}
```

# Actor output Schema

## `results` (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 = {
    "queries": [
        "apify.com",
        "scrapingbee.com",
        "semrush.com"
    ],
    "countryCode": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearpath/spyfu-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 = {
    "queries": [
        "apify.com",
        "scrapingbee.com",
        "semrush.com",
    ],
    "countryCode": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("clearpath/spyfu-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 '{
  "queries": [
    "apify.com",
    "scrapingbee.com",
    "semrush.com"
  ],
  "countryCode": "US"
}' |
apify call clearpath/spyfu-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearpath/spyfu-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/7Fs85gfq1XtijG7IC/builds/EqFU9ItmpnYhfcbqr/openapi.json
