# Wrenfield Data: full reference for agents > SEO, AI-search and lead-data tools on Apify, pay per result. Short index: https://wrenfielddata.com/llms.txt. Agent setup: https://wrenfielddata.com/agents/. One OpenAPI file: https://wrenfielddata.com/openapi.json. # Wrenfield Data tools (agent-readable index) Each tool is an Apify Actor with a REST API, an OpenAPI 3 spec and an MCP tool. Human version: https://wrenfielddata.com/tools/ ## Keyword data - [Keyword Search Volume](https://wrenfielddata.com/tools/keyword-search-volume.md): Google Keyword Planner volume, CPC, competition and 12-month trends, no Ads account. From $4 / 1,000 keywords. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~keyword-search-volume/builds/default/openapi.json - [Keyword Research Tool](https://wrenfielddata.com/tools/keyword-research-tool.md): Keyword ideas with volume, KD, intent and SERP features in one row. From $3 / 1,000 keywords. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~keyword-research-tool/builds/default/openapi.json - [Competitor Keywords](https://wrenfielddata.com/tools/competitor-keywords.md): Every keyword a domain ranks for, with position, volume and traffic. From $2 / 1,000 keywords. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~competitor-keywords/builds/default/openapi.json - [Keyword Gap Report](https://wrenfielddata.com/tools/keyword-gap-report.md): Keywords up to 3 competitors rank for and you don't, top 20 re-checked on live Google. From $9 / report. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~keyword-gap-report/builds/default/openapi.json - [Keyword Difficulty Checker](https://wrenfielddata.com/tools/keyword-difficulty-checker.md): KD 0-100 and search intent for thousands of keywords at once. From $5 / 1,000 keywords. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~keyword-difficulty-checker/builds/default/openapi.json - [Google Autocomplete Expander](https://wrenfielddata.com/tools/google-autocomplete-keyword-expander.md): Long-tail and question keywords from Google and YouTube suggestions. From $1 / 1,000 ideas. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-autocomplete-keyword-expander/builds/default/openapi.json - [People Also Ask Scraper](https://wrenfielddata.com/tools/people-also-ask-scraper.md): PAA question trees, related searches and AI Overview text. From $5.50 / 1,000 keywords + $0.60 / 1,000 questions. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~people-also-ask-scraper/builds/default/openapi.json - [Google Trends Scraper](https://wrenfielddata.com/tools/google-trends-scraper.md): Interest over time, by region, related queries and Trending Now. From $3 / 1,000 terms. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-trends-scraper/builds/default/openapi.json - [Amazon Keyword Research](https://wrenfielddata.com/tools/amazon-keyword-research.md): Reverse ASIN, Amazon keyword ideas and Amazon search volume. From $1.50 / 1,000 keywords. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~amazon-keyword-research/builds/default/openapi.json ## AI search visibility - [AI Search Visibility Tracker](https://wrenfielddata.com/tools/ai-search-visibility-tracker.md): Brand mentions, share of voice and citations across 6 AI engines. From $0.04 / prompt check. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~ai-search-visibility-tracker/builds/default/openapi.json - [AI Answer Scraper](https://wrenfielddata.com/tools/ai-answer-scraper.md): Full answers and citations from ChatGPT, Perplexity, Gemini and AI Mode. From $0.015 / answer. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~ai-answer-scraper/builds/default/openapi.json - [Google AI Overview Scraper](https://wrenfielddata.com/tools/google-ai-overview-scraper.md): Google AI Overviews with every cited source, plus whether your domain is cited. From $0.0025 / query. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-ai-overview-scraper/builds/default/openapi.json - [Agency AI Visibility Reports](https://wrenfielddata.com/tools/agency-ai-visibility-reports.md): White-label weekly AI visibility packets for every client, from one CSV. From $12 / client packet ($7 at 50+). OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~agency-ai-visibility-reports/builds/default/openapi.json ## Rank tracking & site SEO - [Google Maps Grid Rank Tracker](https://wrenfielddata.com/tools/google-maps-grid-rank-tracker.md): Local rank heatmaps, ARP and share of local voice. From $0.008 / grid point. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-maps-grid-rank-tracker/builds/default/openapi.json - [SEO Toolkit All-in-One](https://wrenfielddata.com/tools/seo-toolkit.md): Domain overview, ranked keywords, backlinks and SERPs in one API. From ~$3 / 1,000 rows. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~seo-toolkit/builds/default/openapi.json - [Bulk PageSpeed Checker](https://wrenfielddata.com/tools/bulk-pagespeed-checker.md): Lighthouse scores and Core Web Vitals pass/fail for many URLs. From $5 / 1,000 tests. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~bulk-pagespeed-checker/builds/default/openapi.json - [SEO Agency Report](https://wrenfielddata.com/tools/seo-agency-report.md): White-label SEO and AI-visibility audit as HTML, PDF and JSON, per client. From $2.49 / report. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~seo-agency-report/builds/default/openapi.json ## Domain & website intelligence - [Domain Authority & Traffic](https://wrenfielddata.com/tools/domain-authority-traffic-checker.md): Domain rank, backlinks, referring domains and organic traffic. From $5 / 1,000 domains. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~domain-authority-traffic-checker/builds/default/openapi.json - [Tech Stack Detector](https://wrenfielddata.com/tools/website-tech-stack-detector.md): CMS, ecommerce, analytics, CRM, CDN and hosting for any site. From $2.50 / 1,000 sites. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~website-tech-stack-detector/builds/default/openapi.json - [Google Ads Transparency](https://wrenfielddata.com/tools/google-ads-transparency-scraper.md): Competitor ad creatives, text, landing pages and dates. From $1.50 / 1,000 ads. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-ads-transparency-scraper/builds/default/openapi.json ## Lead & company data - [Company Name to Domain](https://wrenfielddata.com/tools/company-name-to-domain.md): Official website domains for company names, with confidence. From $1.50 / 1,000 companies. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~company-name-to-domain/builds/default/openapi.json - [Website Contact Scraper](https://wrenfielddata.com/tools/website-contact-scraper.md): Emails, phones and social profiles from any list of websites. From $4 / 1,000 sites. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~website-contact-scraper/builds/default/openapi.json - [SEC Form D Scraper](https://wrenfielddata.com/tools/sec-form-d-scraper.md): Startups that just raised money, with executives and amounts. From $3 / 1,000 filings. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~sec-form-d-scraper/builds/default/openapi.json - [Businesses Without Websites](https://wrenfielddata.com/tools/businesses-without-websites.md): Google Maps leads with no website or a broken one. From $7 / 1,000 leads. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~businesses-without-websites/builds/default/openapi.json ## E-commerce & reviews - [Google Shopping Price Comparison](https://wrenfielddata.com/tools/google-shopping-price-comparison.md): Seller prices by keyword or UPC/EAN barcode, 45 countries. From $2 / 1,000 products. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-shopping-price-comparison/builds/default/openapi.json - [Walmart Scraper](https://wrenfielddata.com/tools/walmart-product-scraper.md): Prices, stock, sellers, UPC and reviews, with local ZIP pricing. From $3.50 / 1,000 products. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~walmart-product-scraper/builds/default/openapi.json - [Home Depot & Lowe's Scraper](https://wrenfielddata.com/tools/home-depot-lowes-scraper.md): Price, store stock, aisle and reviews for any ZIP code. From $4 / 1,000 products. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~home-depot-lowes-scraper/builds/default/openapi.json - [Shopify Store Scraper](https://wrenfielddata.com/tools/shopify-store-scraper.md): Any Shopify catalog, plus price-drop and restock monitoring. From $1 / 1,000 products. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~shopify-store-scraper/builds/default/openapi.json - [Tripadvisor Reviews](https://wrenfielddata.com/tools/tripadvisor-reviews-scraper.md): Reviews for hotels, restaurants and attractions. From $1 / 1,000 reviews. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~tripadvisor-reviews-scraper/builds/default/openapi.json ## Jobs & content - [ATS Jobs API](https://wrenfielddata.com/tools/ats-jobs-api.md): Greenhouse, Lever, Ashby, Workday, Workable and SmartRecruiters jobs. From $1.50 / 1,000 jobs. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~ats-jobs-api/builds/default/openapi.json - [Google Jobs Scraper](https://wrenfielddata.com/tools/google-jobs-scraper.md): Job listings with salary, description and every apply link. From $2 / 1,000 jobs. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~google-jobs-scraper/builds/default/openapi.json - [YouTube Transcript Scraper](https://wrenfielddata.com/tools/youtube-transcript-scraper.md): Transcripts as text, SRT, VTT or RAG chunks, any language. From $3 / 1,000 videos. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~youtube-transcript-scraper/builds/default/openapi.json - [Telegram Channel Scraper](https://wrenfielddata.com/tools/telegram-channel-scraper.md): Public channel posts, views and reactions, no login. From $1 / 1,000 posts. OpenAPI: https://api.apify.com/v2/acts/wrenfield-data~telegram-channel-scraper/builds/default/openapi.json --- # Agency AI Visibility Reports - White-Label Client Packets > Upload your client list once and get a finished, white-label weekly report per client: brand mentions, share of voice and citations across ChatGPT, Perplexity, Gemini and Google AI Mode, Google rank changes, quoted evidence and a prioritized action queue. Charged per completed client packet. - Category: AI search visibility - Price: $12 per client packet, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/agency-ai-visibility-reports - Human page: https://wrenfielddata.com/tools/agency-ai-visibility-reports/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~agency-ai-visibility-reports/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/agency-ai-visibility-reports (appears as `wrenfield-data--agency-ai-visibility-reports`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~agency-ai-visibility-reports/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"clientsCsv": "client,domain,brand,competitors,questions,keywords\nHelp Scout,helpscout.com,Help Scout,Zendesk | zendesk.com; Freshdesk | freshworks.com; Intercom | intercom.com,What is the best help desk software for a small business?; What is the best customer support tool for a SaaS startup?; What is the most affordable help desk software?,help desk software; shared inbox software\nPipedrive,pipedrive.com,Pipedrive,HubSpot | hubspot.com; Salesforce | salesforce.com; Zoho CRM | Zoho | zoho.com,What is the best CRM for a small sales team?; Which CRM is easiest to set up for a startup?; What is the best CRM for B2B sales pipelines?,sales pipeline software; crm for small business", "agencyName": "Northwind Digital", "engines": ["chatgpt", "perplexity", "gemini", "google_ai_mode"]}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `clientsCsv` | string | | | One row per client. Columns: client, domain, brand (optional; add spelling variants with \|), competitors (separate with ;, e.g. Zendesk \| zendesk.com; Intercom \| intercom.com), questions (up to 20, separated with ;) or category (we write 6 neutral buyer questions for you), keywords (optional, up to 10 Google keywords, ;-separated), location and language (optional). Export it from Google Sheets as CSV and paste it here. | | `agencyName` | string | | | Shown on every packet and the portfolio page (white label: Wrenfield Data is not mentioned). | | `agencyLogoUrl` | string | | | Optional. Public PNG or JPG URL; shown top left of each packet. | | `accentColor` | string | | `"#1F4E79"` | Optional. Hex color for headings and charts, e.g. #1F4E79. | | `reportTitle` | string | | | Optional. Default: AI Search Visibility Report. | | `engines` | array | | `["chatgpt", "perplexity", "gemini", "google_ai_mode"]` | Engines each question is asked on. Default: the four consumer AI search surfaces. | | `country` | string | | `"United States"` | Used for rows without a location. Country name or 2-letter code. | | `language` | string | | `"English"` | Used for rows without a language. | | `quoteOnly` | boolean | | `false` | Validate the book and show the number of packets, checks and the maximum price, without running checks or charging. | | `bookId` | string | | | Name of this client book. Runs with the same ID compare each client with the previous week. Default: built from the agency name. | | `forceRefresh` | boolean | | `false` | By default a re-run in the same week reuses the stored packets for free. Turn on to ask every question again (charged again). | | `includePdf` | boolean | | `true` | Also save a PDF of each packet. | | `clients` | array | | | Alternative to the CSV for API and agent use: an array of objects with the same fields, e.g. [{"client":"Acme","domain":"acme.com","competitors":"Rival \| rival.com","category":"project management software"}]. | ## Example input ```json { "clientsCsv": "client,domain,brand,competitors,questions,keywords\nHelp Scout,helpscout.com,Help Scout,Zendesk | zendesk.com; Freshdesk | freshworks.com; Intercom | intercom.com,What is the best help desk software for a small business?; What is the best customer support tool for a SaaS startup?; What is the most affordable help desk software?,help desk software; shared inbox software\nPipedrive,pipedrive.com,Pipedrive,HubSpot | hubspot.com; Salesforce | salesforce.com; Zoho CRM | Zoho | zoho.com,What is the best CRM for a small sales team?; Which CRM is easiest to set up for a startup?; What is the best CRM for B2B sales pipelines?,sales pipeline software; crm for small business", "agencyName": "Northwind Digital", "engines": [ "chatgpt", "perplexity", "gemini", "google_ai_mode" ] } ``` ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # AI Answer Scraper - ChatGPT, Perplexity, Gemini & AI Mode > Answers and cited sources from ChatGPT, Perplexity, Gemini, Google AI Mode, Google AI Overviews and Claude for your prompts. Same input as Apify's AI scrapers (queries, countryCode). Licensed data, no logins, no browser. $0.015 per answer. Built for GEO / AI search tracking and AI agents. - Category: AI search visibility - Price: $15 per 1,000 × ai answer, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/ai-answer-scraper - Human page: https://wrenfielddata.com/tools/ai-answer-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~ai-answer-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/ai-answer-scraper (appears as `wrenfield-data--ai-answer-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~ai-answer-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"prompts": ["What is the best CRM for a small business?"], "engines": ["chatgpt", "perplexity"], "country": "United States", "language": "English"}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `prompts` | array | | | Questions to ask, one per line (up to 500 characters each, up to 500 prompts). Each prompt is sent to every selected engine. Coming from Apify's ChatGPT / Perplexity / Gemini / AI Mode scrapers? You can send your existing queries input unchanged instead. | | `engines` | array | | `["chatgpt", "perplexity"]` | Engines to ask. One answer row per prompt and engine. Default: ChatGPT + Perplexity. | | `country` | string | | | Country the answers are localized to (web search location): name, 2-letter code or location code. Default: United States. | | `language` | string | | `"English"` | Language name or code (English, de). | | `chatgptWebSearch` | boolean | | `true` | Make ChatGPT search the web, so the answer has cited sources (what most users see for buying questions). | | `includeAnswerText` | boolean | | `true` | Turn off to get only citations, cited domains and brands (smaller output for agents). | | `maxAnswerChars` | integer | | `20000` | Answer text is cut to this length. | | `queries` | string | | | Same as queries in Apify's AI scrapers: one query per line. Added to Prompts. When used, each row also gets Apify-style fields (query, text, sources, citationUrls). | | `countryCode` | string | | | Lowercase 2-letter country code as in Apify's AI scrapers (e.g. us, gb). Used when Country is empty. | | `perplexitySearch` | object | | | Accepted for compatibility with apify/perplexity-search-scraper. Images, related questions and search recency are not supported and are ignored (noted in the run summary). | | `apifyCompatibleFields` | boolean | | | Add query, text, sources, citationUrls, relatedQuestions and images to every row, matching Apify's AI scrapers. Default: on when you use queries, off otherwise. | ## Example input ```json { "prompts": [ "What is the best CRM for a small business?" ], "engines": [ "chatgpt", "perplexity" ], "country": "United States", "language": "English" } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `prompt` | string | Prompt that was asked | | `engine` | string | Engine key | | `engine_name` | string | Engine name, e.g. ChatGPT | | `model` | string | Model that answered, when reported (e.g. sonar, gpt-..., google-ai-mode) | | `status` | string | ok = answer returned; no_answer = the engine showed no AI answer (e.g. no AI Overview for the query); error = the engine did not respond (not charged); incomplete = the engine returned a cut-off answer twice (not charged) | | `answer_markdown` | string | Answer as markdown (images removed) | | `answer_text` | string | Answer as plain text | | `answer_word_count` | integer | Words in the answer | | `citations` | array | Sources the answer cites: url, domain, title | | `citation_count` | integer | Number of cited sources | | `cited_domains` | array | Unique cited domains in order of first citation | | `brands` | array | Brands and products the answer recommends, in the order they first appear (all engines). Each: name, rank, mentions, cited (the answer cites a domain of that brand), cited_domain, confidence (high/low), source (answer, provider or answer+provider). | | `brands_mentioned` | array | Names of high-confidence brands, in answer order (ready for share-of-voice counts) | | `first_brand` | string | First high-confidence brand the answer names (the "top pick") | | `brand_entities` | array | Brands / products the engine highlighted (ChatGPT, Gemini) | | `fan_out_queries` | array | Web searches the engine ran to answer (ChatGPT, Perplexity when reported) | | `organic_results` | array | Google AI Overviews only: top organic results on the same page (rank, domain, url) | | `country` | string | Country used | | `language` | string | Language used | | `response_time_secs` | number | Seconds the engine took to answer | | `note` | string | Explanation when there is no answer | | `scraped_at` | string | When the answer was retrieved (ISO 8601, UTC) | | `query` | string | Apify-compatible alias of prompt (only with Apify-style input or apifyCompatibleFields) | | `text` | string | Apify-compatible alias of answer_markdown | | `sources` | array | Apify-compatible list of cited sources: id, title, url, section | | `citationUrls` | array | Apify-compatible list of cited URLs | | `relatedQuestions` | array | Apify-compatible field; always empty | | `images` | array | Apify-compatible field; always empty | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # AI Search Visibility Tracker: ChatGPT, Perplexity > Track brand mentions, share of voice and cited URLs in ChatGPT, Perplexity, Gemini, Google AI Overviews, AI Mode and Claude. Per prompt x engine: full answer, mention rank, sentiment, citations, your domain cited or not. Monitoring mode flags gained/lost mentions. GEO/AEO rank tracker. - Category: AI search visibility - Price: $40 per 1,000 × prompt check, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/ai-search-visibility-tracker - Human page: https://wrenfielddata.com/tools/ai-search-visibility-tracker/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~ai-search-visibility-tracker/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/ai-search-visibility-tracker (appears as `wrenfield-data--ai-search-visibility-tracker`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~ai-search-visibility-tracker/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"brands": ["HubSpot"], "domains": ["hubspot.com"], "competitors": ["Salesforce | salesforce.com", "Pipedrive | pipedrive.com"], "prompts": ["What is the best CRM for a small business?"], "promptsPerTopic": 3, "promptGeneration": "templates", "engines": ["chatgpt", "google_ai_mode"], "country": "United States", "language": "English", "monitoringMode": false, "monitoringStoreName": "ai-visibility-monitor", "maxChecks": 200, "chatgptWebSearch": true, "includeAnswerText": true, "caseSensitive": false, "maxConcurrency": 5}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `brands` | array | yes | `["HubSpot"]` | Your brand name, one per line. Add spelling variants after a \|, e.g. HubSpot \| HubSpot CRM. A token that looks like a domain (hubspot.com) is used as your domain. Matching is case-insensitive and whole-word. | | `domains` | array | | | Your website domain(s), e.g. hubspot.com. Used to check whether AI answers cite your site (subdomains count). Writing the domain in the answer text also counts as a mention. | | `competitors` | array | | | Competitor brands to compare with, one per line: Name \| variant \| domain.com. Used for share of voice, rank and citation comparisons. | | `prompts` | array | | | Questions your buyers ask AI assistants, one per line, e.g. What is the best CRM for a small business?. Max 500 characters each. Every prompt is checked on every selected engine (1 prompt x 3 engines = 3 checks). Leave empty if you use seed topics. | | `seedTopics` | array | | | Optional: product categories such as CRM software or running shoes for flat feet. The Actor generates buyer-intent questions ("What is the best ...", "alternatives to ", ...) for each topic and checks them too. | | `promptsPerTopic` | integer | | `3` | How many questions to generate per seed topic. | | `promptGeneration` | string | | `"templates"` | Templates: proven buyer-intent question patterns (stable from run to run, best for monitoring). AI-written: an AI model writes natural, varied buyer questions for each topic (at no extra charge; up to 20 topics). | | `engines` | array | | `["chatgpt", "perplexity", "google_ai_overview"]` | Engines to check every prompt on. Each prompt x engine is one check. ChatGPT, Gemini, Google AI Overviews and Google AI Mode are the real consumer answers (localized); Perplexity and Claude come from their official models. | | `country` | string | | `"United States"` | Where the questions are asked from: country name (Germany), 2-letter code (DE) or location code (2276). 190+ countries. | | `language` | string | | `"English"` | Language name (German) or code (de). Write your prompts in this language. | | `monitoringMode` | boolean | | `false` | Save results to a named key-value store and compare each prompt x engine with the previous run: flags gained/lost mentions, citations and rank changes, and adds share-of-voice changes to the summary. Schedule the Actor (e.g. weekly) to track AI visibility over time. | | `trackingId` | string | | | Name of this tracking project, e.g. hubspot-us. Runs with the same ID are compared with each other. Default: derived from your brand, country and language. | | `monitoringStoreName` | string | | `"ai-visibility-monitor"` | Named key-value store (in your Apify account) that keeps the previous results. | | `maxChecks` | integer | | `200` | Upper limit of prompt x engine checks per run (cost control). The run also stops cleanly at your Maximum cost per run. | | `chatgptWebSearch` | boolean | | `true` | Ask ChatGPT to search the web (like ChatGPT Search) so answers cite sources. Turn off to see what ChatGPT says from memory. | | `includeAnswerText` | boolean | | `true` | Save the complete AI answer (markdown) in each row. | | `caseSensitive` | boolean | | `false` | Turn on for brand names that are also common words (e.g. Notion, Monday) to count only capitalized mentions. | | `maxConcurrency` | integer | | `5` | How many checks run at the same time. | ## Example input ```json { "brands": [ "HubSpot" ], "domains": [ "hubspot.com" ], "competitors": [ "Salesforce | salesforce.com", "Pipedrive | pipedrive.com" ], "prompts": [ "What is the best CRM for a small business?" ], "promptsPerTopic": 3, "promptGeneration": "templates", "engines": [ "chatgpt", "google_ai_mode" ], "country": "United States", "language": "English", "monitoringMode": false, "monitoringStoreName": "ai-visibility-monitor", "maxChecks": 200, "chatgptWebSearch": true, "includeAnswerText": true, "caseSensitive": false, "maxConcurrency": 5 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | check = one prompt answered by one AI engine; summary = share-of-voice row for one engine (or "all") and one brand | | `prompt` | string | The question sent to the AI engine | | `prompt_source` | string | input, template (generated from a seed topic) or ai (generated by AI from a seed topic) | | `seed_topic` | string | Seed topic the prompt was generated from | | `engine` | string | chatgpt, perplexity, gemini, google_ai_overview, google_ai_mode, claude (summary rows: also "all") | | `engine_name` | string | Engine display name | | `model` | string | Model / surface that produced the answer | | `country` | string | Country used for the check | | `language` | string | Language code | | `status` | string | ok = answer received; no_answer = the engine showed no AI answer (e.g. no AI Overview for this query); error = check failed (not charged); incomplete = the engine returned a cut-off answer twice (not charged) | | `note` | string | Explanation for no_answer / error / incomplete | | `brand` | string | Your brand(s) | | `brand_mentioned` | boolean | Your brand is mentioned in the answer | | `brand_position` | integer | Rank of your brand among all tracked brands by first mention (1 = mentioned first) | | `brand_mention_count` | integer | How many times your brand is mentioned | | `brand_sentiment` | string | positive, neutral, negative or mixed (wording around your brand) | | `brand_snippet` | string | Sentence where your brand is first mentioned | | `your_domain_cited` | boolean | One of your domains is cited as a source (null if you gave no domain) | | `your_cited_urls` | array | Your URLs cited as sources | | `your_organic_rank` | integer | Google AI Overview engine only: rank of your domain in the top-10 organic results | | `competitors_mentioned` | array | Tracked competitors mentioned in the answer | | `first_mentioned_brand` | string | Tracked brand mentioned first | | `brands_mentioned_count` | integer | Number of tracked brands mentioned | | `brand_results` | array | Per tracked brand: mentioned, mention_count, position, sentiment, snippet, cited, cited_urls, position_among_all_brands, organic_rank | | `other_brands_mentioned` | array | Other (untracked) brands the engine recognized in the answer (ChatGPT) | | `cited_domains` | array | Unique domains cited as sources | | `citations` | array/integer | Check rows: cited sources. Summary rows: checks citing the brand domain | | `citations_count` | integer | Number of unique cited URLs | | `fan_out_queries` | array | Web searches the engine ran to answer the prompt | | `answer_text` | string | Full answer (markdown) | | `answer_length` | integer | Answer length in characters | | `change_status` | string | Monitoring: first_check, gained_mention, lost_mention, gained_citation, lost_citation, position_changed, competitors_changed, unchanged | | `mention_change` | string | Monitoring: gained, lost or unchanged | | `citation_change` | string | Monitoring: gained, lost or unchanged | | `position_change` | integer | Monitoring: positions moved up (+) or down (-) since the previous run | | `brands_gained` | array | Monitoring: tracked brands newly mentioned | | `brands_lost` | array | Monitoring: tracked brands no longer mentioned | | `previous_checked_at` | string | Monitoring: time of the previous check | | `is_your_brand` | boolean | Summary: the row is about your brand | | `checks` | integer | Summary: completed checks | | `answers` | integer | Summary: checks with an AI answer | | `mentions` | integer | Summary: checks mentioning the brand | | `mention_rate` | number | Summary: mentions / checks (0-1) | | `share_of_voice` | number | Summary: brand mentions / all tracked-brand mentions (0-1) | | `avg_position` | number | Summary: average rank among tracked brands when mentioned | | `top_position_rate` | number | Summary: share of checks where the brand is mentioned first | | `citation_rate` | number | Summary: checks citing the brand domain / checks (null if no domain given) | | `mention_rate_change` | number | Summary + monitoring: change vs previous run | | `share_of_voice_change` | number | Summary + monitoring: change vs previous run | | `citation_rate_change` | number | Summary + monitoring: change vs previous run | | `checked_at` | string | When the row was produced (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Amazon Keyword Research & Reverse ASIN - Helium 10 Alternative > Reverse ASIN lookup (every keyword a product ranks for, with Amazon search volume and rank), Amazon keyword ideas from a seed, and bulk Amazon search volume. Licensed data, no Amazon login or scraping. $1.50 per 1,000 keywords + $0.03 per lookup. - Category: Keyword data - Price: $1.50 per 1,000 × keyword result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/amazon-keyword-research - Human page: https://wrenfielddata.com/tools/amazon-keyword-research/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~amazon-keyword-research/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/amazon-keyword-research (appears as `wrenfield-data--amazon-keyword-research`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~amazon-keyword-research/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"mode": "reverse_asin", "asins": ["B09B8V1LZ3"], "maxKeywords": 100}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `mode` | string | yes | `"reverse_asin"` | What to look up. | | `asins` | array | | | Reverse ASIN mode: ASINs or Amazon product URLs (up to 50). | | `keywords` | array | | | Keyword ideas mode: seed keywords (up to 20). Search volume mode: your keyword list (up to 10,000). | | `marketplace` | string | | `"amazon.com"` | Amazon marketplace of the data. | | `maxKeywords` | integer | | `100` | Max keyword rows per ASIN or seed keyword. The default of 100 finishes in a few seconds. | | `minSearchVolume` | integer | | `0` | Only keywords with at least this many monthly Amazon searches. | | `maxRank` | integer | | | Only keywords where the product ranks in this position or better. | | `mustContainSeed` | boolean | | `false` | Keep only ideas that contain the seed phrase (long-tail variations). | | `depth` | integer | | `2` | How many levels of related keywords to follow (1-4). | ## Example input ```json { "mode": "reverse_asin", "asins": [ "B09B8V1LZ3" ], "maxKeywords": 100 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `mode` | string | reverse_asin, keyword_ideas or search_volume | | `keyword` | string | Amazon search keyword | | `search_volume` | integer | Estimated monthly Amazon searches | | `asin` | string | reverse_asin: the product | | `seed_keyword` | string | keyword_ideas: seed the idea came from | | `rank` | integer | reverse_asin: organic rank of the product for the keyword | | `rank_absolute` | integer | reverse_asin: rank counting all result types | | `is_amazon_choice` | boolean | reverse_asin: shown with the Amazon's Choice badge | | `is_best_seller` | boolean | reverse_asin: shown with the Best Seller badge | | `product_title` | string | reverse_asin: product title in the results | | `price` | number | reverse_asin: price shown | | `currency` | string | Currency | | `rating` | number | reverse_asin: star rating | | `reviews_count` | integer | reverse_asin: ratings count | | `bought_past_month` | integer | reverse_asin: "bought in past month" figure shown | | `product_url` | string | reverse_asin: product page | | `search_results_count` | integer | reverse_asin: total results for the keyword | | `related_keywords` | array | keyword_ideas: keywords related to this one | | `depth` | integer | keyword_ideas: 0 = the seed, 1-4 = related-keyword hops | | `marketplace` | string | Amazon marketplace | | `data_updated_at` | string | When the data was last updated (ISO 8601, UTC) | | `scraped_at` | string | When the row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Greenhouse Jobs Scraper: Lever, Ashby, Workday API > ATS Jobs API: Greenhouse, Lever, Ashby, Workday, Workable & SmartRecruiters jobs scraper. Enter company domains or careers URLs; ATS is auto-detected. One normalized schema with salary, remote flag & dates, filters and new-job monitoring. - Category: Jobs & content - Price: $1.50 per 1,000 × job posting result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/ats-jobs-api - Human page: https://wrenfielddata.com/tools/ats-jobs-api/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~ats-jobs-api/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/ats-jobs-api (appears as `wrenfield-data--ats-jobs-api`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~ats-jobs-api/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"companies": ["stripe.com", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/notion", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"], "maxJobsPerCompany": 10, "searchInDescription": false, "remoteOnly": false, "monitoringMode": false, "monitoringIncludeChanged": true, "monitoringStoreName": "ats-jobs-monitor", "includeDescription": true, "fetchGreenhouseSalary": false, "maxConcurrency": 5}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `companies` | array | yes | `["stripe.com", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/notion", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"]` | One company per line. Accepted formats: • Company domain: stripe.com (careers page is scanned and ATS boards are probed) • Careers page URL: https://www.figma.com/careers/ • ATS board URL: https://boards.greenhouse.io/stripe, https://jobs.lever.co/spotify, https://jobs.ashbyhq.com/notion, https://apply.workable.com/huggingface, https://jobs.smartrecruiters.com/BoschGroup, https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite • Board token: notion (all token-based ATSs are tried) • Prefixed token to skip detection: greenhouse:stripe, lever:spotify, ashby:notion, workable:huggingface, smartrecruiters:BoschGroup Workday sites must be given as a URL (or found on the company's careers page). | | `maxJobsPerCompany` | integer | | | Maximum number of job postings to save per company (after filters). Leave empty or 0 for no limit. Large Workday and SmartRecruiters employers can have thousands of open roles. | | `maxItems` | integer | | | Stop after saving this many jobs across all companies. Leave empty or 0 for no limit. The run also stops automatically when your 'Maximum cost per run' is reached. | | `keywords` | array | | | Keep only jobs whose title contains at least one of these words or phrases (case-insensitive, whole words). Example: engineer, data scientist, product manager. | | `excludeKeywords` | array | | | Drop jobs whose title contains any of these words. Example: intern, senior. | | `searchInDescription` | boolean | | `false` | When enabled, keywords are matched against the title and the full job description. | | `locations` | array | | | Keep only jobs where any location (or the country) contains one of these words or phrases, case-insensitive, whole words (US won't match Austria). Remote jobs also match Remote. Example: New York, London, Germany, Remote. | | `remoteOnly` | boolean | | `false` | Keep only jobs marked as remote by the ATS (or with 'Remote' in the location). | | `postedWithinDays` | integer | | | Keep only jobs first published within this many days. Jobs whose ATS does not expose a posting date are kept. | | `departments` | array | | | Keep only jobs whose department or team contains one of these strings. Example: Engineering, Sales. | | `employmentTypes` | array | | | Keep only these normalized employment types: Full-time, Part-time, Contract, Internship, Temporary. Jobs whose ATS doesn't publish an employment type (common on Greenhouse) are kept. | | `monitoringMode` | boolean | | `false` | Remember every job saved per company in a named key-value store and on later runs save only postings that are new (or changed, see below). Perfect for scheduled runs that feed alerts, Slack, CRMs or job boards. The first run saves everything and creates the baseline. Jobs skipped because of the max-jobs limits are not remembered, so they show up on a later run. | | `monitoringIncludeChanged` | boolean | | `true` | In monitoring mode, also save jobs whose title, location, department, employment type or salary changed since they were last seen (marked with changeType = 'changed'). | | `monitoringStoreName` | string | | `"ats-jobs-monitor"` | Name of the key-value store holding the 'already seen' state. Use a different name for each independent monitor (e.g. one per schedule or client). | | `includeDescription` | boolean | | `true` | Save the full description as plain text and HTML. Turn off for faster, smaller runs (Workday and SmartRecruiters need one extra request per job for descriptions). | | `fetchGreenhouseSalary` | boolean | | `false` | Greenhouse only exposes structured pay ranges per job. Enable to make one extra request per Greenhouse job to get exact min/max salary. When disabled, salary is still extracted from the description text when present. | | `maxConcurrency` | integer | | `5` | How many companies are scraped at the same time. | ## Example input ```json { "companies": [ "stripe.com", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/notion", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" ], "maxJobsPerCompany": 10, "searchInDescription": false, "remoteOnly": false, "monitoringMode": false, "monitoringIncludeChanged": true, "monitoringStoreName": "ats-jobs-monitor", "includeDescription": true, "fetchGreenhouseSalary": false, "maxConcurrency": 5 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `company` | string | Company name | | `title` | string | Job title | | `department` | string | | | `team` | string | | | `location` | string | Primary location | | `locations` | array | All locations of the posting | | `country` | string | | | `remote` | boolean | | | `workplaceType` | string | Remote, Hybrid or On-site | | `employmentType` | string | Full-time, Part-time, Contract, Internship, Temporary | | `postedAt` | string | First published (ISO 8601, UTC) | | `updatedAt` | string | | | `salaryMin` | number | | | `salaryMax` | number | | | `salaryCurrency` | string | | | `salaryInterval` | string | YEAR, MONTH or HOUR | | `salaryText` | string | | | `salarySource` | string | structured (from ATS) or description (parsed from text) | | `descriptionText` | string | | | `descriptionHtml` | string | | | `jobUrl` | string | | | `applyUrl` | string | | | `ats` | string | greenhouse, lever, ashby, workable, smartrecruiters or workday | | `atsBoardToken` | string | | | `atsBoardUrl` | string | | | `jobId` | string | | | `requisitionId` | string | | | `sourceInput` | string | | | `scrapedAt` | string | | | `changeType` | string | Monitoring mode only: new or changed | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Bulk PageSpeed & Core Web Vitals Checker > Run Google PageSpeed Insights on hundreds of URLs: performance, SEO, accessibility scores, lab metrics, real-user Core Web Vitals (LCP, INP, CLS from CrUX) with pass/fail, and the top fixes per page. Mobile and desktop. $5 per 1,000 tests, no Google key needed. - Category: Rank tracking & site SEO - Price: $5 per 1,000 × pagespeed test, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/bulk-pagespeed-checker - Human page: https://wrenfielddata.com/tools/bulk-pagespeed-checker/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~bulk-pagespeed-checker/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/bulk-pagespeed-checker (appears as `wrenfield-data--bulk-pagespeed-checker`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~bulk-pagespeed-checker/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"urls": ["https://apify.com", "https://example.com"], "devices": ["mobile"]}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `urls` | array | yes | `["https://apify.com", "https://example.com"]` | Pages to test, one per line (up to 5,000). https:// is added when missing. | | `devices` | array | | `["mobile"]` | Each URL is tested once per device. | | `categories` | array | | `["performance", "seo"]` | Scores to include. Performance is always included. | | `maxOpportunities` | integer | | `5` | How many improvement opportunities (with estimated savings) to list per test. | | `googleApiKey` | string | | | Optional free PageSpeed Insights API key from Google Cloud, for very large jobs. Not needed: the Actor has its own. | | `useBackupService` | boolean | | `true` | If Google PageSpeed Insights is over its quota, test pages on a backup Lighthouse service instead (lab data only, no real-user Core Web Vitals; lighthouse-test event). | ## Example input ```json { "urls": [ "https://apify.com", "https://example.com" ], "devices": [ "mobile" ] } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `url` | string | URL tested | | `device` | string | mobile or desktop | | `status` | string | ok or error | | `error` | string | Why the test failed | | `engine` | string | pagespeed_insights (Google, lab + real-user data) or lighthouse_backup (lab data only) | | `final_url` | string | URL after redirects | | `redirected` | boolean | The URL redirected | | `performance_score` | integer | Lighthouse performance score 0-100 | | `accessibility_score` | integer | Accessibility score 0-100 (if requested) | | `best_practices_score` | integer | Best practices score 0-100 (if requested) | | `seo_score` | integer | SEO score 0-100 (if requested) | | `cwv_assessment` | string | Core Web Vitals assessment from real users (CrUX): passed, failed or no_data | | `field_data_scope` | string | url = real-user data for this page; origin = whole-site data (page has too little traffic) | | `origin_cwv_assessment` | string | Core Web Vitals assessment for the whole site | | `field_lcp_p75` | number | Real-user LCP at the 75th percentile (ms) | | `field_inp_p75` | number | Real-user INP at the 75th percentile (ms) | | `field_cls_p75` | number | Real-user CLS at the 75th percentile (unitless) | | `field_fcp_p75` | number | Real-user FCP at the 75th percentile (ms) | | `field_ttfb_p75` | number | Real-user TTFB at the 75th percentile (ms) | | `field_lcp_rating` | string | Real-user LCP rating: fast, average or slow | | `field_inp_rating` | string | Real-user INP rating: fast, average or slow | | `field_cls_rating` | string | Real-user CLS rating: fast, average or slow | | `field_fcp_rating` | string | Real-user FCP rating: fast, average or slow | | `field_ttfb_rating` | string | Real-user TTFB rating: fast, average or slow | | `lab_fcp_ms` | integer | Lab First Contentful Paint (ms) | | `lab_lcp_ms` | integer | Lab Largest Contentful Paint (ms) | | `lab_tbt_ms` | integer | Lab Total Blocking Time (ms) | | `lab_cls` | number | Lab Cumulative Layout Shift | | `lab_speed_index_ms` | integer | Lab Speed Index (ms) | | `lab_tti_ms` | integer | Lab Time to Interactive (ms) | | `lab_server_response_ms` | integer | Server response time (ms) | | `page_weight_bytes` | integer | Total page weight (bytes) | | `requests_count` | integer | Network requests | | `opportunities` | array | Top fixes with estimated savings | | `failed_audits` | array | Common audits the page fails (compression, render-blocking, images, meta description, ...) | | `lighthouse_version` | string | Lighthouse version | | `checked_at` | string | When the test ran (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Businesses Without Websites - Google Maps Leads > Find local businesses on Google Maps that have no website, only a Facebook/Instagram page, or a broken, outdated or non-mobile site. Phone, address, rating, reviews and a 0-100 lead score per business. For web designers and agencies. $7 per 1,000 leads, no login, no proxies. - Category: Lead & company data - Price: $7 per 1,000 × lead, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/businesses-without-websites - Human page: https://wrenfielddata.com/tools/businesses-without-websites/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~businesses-without-websites/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/businesses-without-websites (appears as `wrenfield-data--businesses-without-websites`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~businesses-without-websites/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"searchTerms": ["roofer"], "locations": ["Boise, ID"], "leadType": "no_real_website"}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `searchTerms` | array | yes | `["roofer"]` | What to search on Google Maps, e.g. plumber, hair salon, dentist. Up to 50. | | `locations` | array | | | Cities, areas or ZIP codes, e.g. Austin, TX, Leeds, 90210. Each business type is searched in each location (up to 100). Leave empty to search the whole country. | | `country` | string | | `"United States"` | Country: name (United States), 2-letter code (DE) or location code (2840). | | `leadType` | string | | `"no_real_website"` | Which businesses become leads. | | `auditWebsites` | boolean | | `false` | Check each business website (one page load): unreachable, no HTTPS / SSL error, not mobile-friendly, outdated copyright year, very slow, parked page, site builder. Adds the website-audit event. Always on for "weak_website". | | `maxPlacesPerSearch` | integer | | `100` | How many Google Maps results to scan per business type and location (in steps of 100, up to 700). Google shows about 100-120 for most searches. | | `maxLeads` | integer | | `1000` | Stop after this many leads in total. | | `minReviews` | integer | | `0` | Only businesses with at least this many Google reviews (real, active businesses). | | `minRating` | string | | | Only businesses rated at least this (e.g. 4). | | `requirePhone` | boolean | | `false` | Skip businesses without a phone number. | | `language` | string | | | Language of the results (name or code). Default: English. | ## Example input ```json { "searchTerms": [ "roofer" ], "locations": [ "Boise, ID" ], "leadType": "no_real_website" } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `business_name` | string | Business name on Google Maps | | `category` | string | Main Google category | | `additional_categories` | array | Other categories | | `phone` | string | Phone number | | `address` | string | Full address | | `street` | string | Street address | | `city` | string | City | | `postal_code` | string | ZIP / postal code | | `region` | string | State / region | | `country_code` | string | 2-letter country code | | `latitude` | number | Latitude | | `longitude` | number | Longitude | | `rating` | number | Google rating 1-5 | | `reviews_count` | integer | Number of Google reviews | | `is_claimed` | boolean | Owner has claimed the Google Business Profile | | `business_status` | string | Opening status when checked (open, close, closed_forever, temporarily_closed) | | `price_level` | string | Price level, e.g. $$ | | `total_photos` | integer | Photos on the listing | | `website` | string | Website on the listing (null = none) | | `website_type` | string | none = no website; social = only a social media page; directory = only a directory/booking page; own = a real website | | `has_real_website` | boolean | true when the listing links to its own website | | `lead_score` | integer | Lead score 0-100: no/weak website, contactable, active and reviewed businesses score higher | | `lead_reason` | string | Why this business is a lead | | `website_audited` | boolean | The website was checked (auditWebsites) | | `website_audit_status` | string | ok, blocked (bot protection or access denied: the site works for people, so no issues are reported) or unreachable | | `website_issues` | array | Problems found: unreachable, broken (404/5xx), ssl_error, no_https, not_mobile_friendly, no_title, outdated, parked_or_empty, slow (over 20 s) | | `website_reachable` | boolean | Website loaded | | `website_status_code` | integer | HTTP status of the homepage | | `website_final_url` | string | URL after redirects | | `website_https` | boolean | Served over HTTPS | | `website_ssl_error` | boolean | SSL certificate problem | | `website_mobile_friendly` | boolean | Has a mobile viewport tag | | `website_load_secs` | number | Seconds to load the homepage HTML | | `website_copyright_year` | integer | Latest copyright year on the page | | `website_platform` | string | Site builder / CMS detected (wix, squarespace, wordpress, godaddy, ...) | | `website_title` | string | Homepage title | | `google_maps_url` | string | Google Maps link to the listing | | `place_id` | string | Google place ID | | `cid` | string | Google CID | | `search_term` | string | Business type searched | | `search_location` | string | Location searched | | `rank_in_search` | integer | Position in the Google Maps results | | `scraped_at` | string | When the row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Company Name to Domain - Bulk Website Finder > Find the official website domain for any list of company names. Bulk name-to-domain lookup with a confidence score, verified live homepage, LinkedIn URL, logo, favicon and alternatives. Clearbit Name-to-Domain alternative. Pay only for resolved companies. - Category: Lead & company data - Price: $1.50 per 1,000 × company resolved, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/company-name-to-domain - Human page: https://wrenfielddata.com/tools/company-name-to-domain/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~company-name-to-domain/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/company-name-to-domain (appears as `wrenfield-data--company-name-to-domain`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~company-name-to-domain/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"companies": ["Stripe", "Spotify", "Shopify", "Siemens", "Patagonia", "Delta | airline", "Mercury | banking for startups"], "minConfidence": 60, "searchFallback": "auto", "searchEngine": "bing", "useClearbit": true, "useWikidata": true, "includeUnresolved": true, "maxAlternatives": 3, "maxConcurrency": 20, "proxyConfiguration": {"useApifyProxy": true}}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `companies` | array | | | One company per line. Optionally add a hint after a \| to tell similar names apart: a city, country or industry, e.g. Delta \| airline, Franklin Barbecue \| Austin, TX, Rossmann \| Germany. Legal suffixes like Inc, LLC or GmbH are handled automatically. | | `records` | array | | | Optional. Company objects, e.g. [{"name": "Bolt", "country": "Estonia", "industry": "ride-hailing", "id": "crm-123"}]. Recognized keys: name/company, country, city/location, industry/category, hint. The whole record is returned in inputRecord so you can join results back to your CRM. | | `csvData` | string | | | Optional. Paste CSV (comma, semicolon or tab separated). With a header row, the column named name/company is used and country, city, industry columns become hints. Without a header, the first column is the company name and the other columns are used as hints. | | `country` | string | | | Optional country applied to every company without its own country (name or 2-letter code, e.g. Germany or DE). Prefers that country's domains (e.g. .de) and companies registered there. | | `minConfidence` | integer | | `60` | A domain is returned (and charged) only when its confidence score is at least this value. Default 60 was ~98-100% precise on our test sets. Raise it to 80 for even fewer false positives; lower it to get more best guesses. | | `searchFallback` | string | | `"auto"` | Auto (recommended): search the web only when the free sources are not confident enough. Always: search for every company (slower). Never: only Clearbit autocomplete, Wikidata and domain guesses. | | `searchEngine` | string | | `"bing"` | Bing / DuckDuckGo via Apify Proxy. Google via Apify's Google SERP proxy gives the best results for small local businesses (only works on the Apify platform). | | `useClearbit` | boolean | | `true` | Use the free public Clearbit company autocomplete as one of the candidate sources. | | `useWikidata` | boolean | | `true` | Use the official website (P856) recorded on Wikidata as one of the candidate sources. | | `includeUnresolved` | boolean | | `true` | Also output a row (free of charge) for companies where no domain reached the minimum confidence, with the best guess and alternatives, so your output has one row per input. | | `maxAlternatives` | integer | | `3` | How many runner-up candidate domains to include (with their own confidence). | | `maxConcurrency` | integer | | `20` | How many companies are resolved in parallel. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Proxy used for the web search fallback (Bing / DuckDuckGo). Homepages, Clearbit and Wikidata are fetched directly. | ## Example input ```json { "companies": [ "Stripe", "Spotify", "Shopify", "Siemens", "Patagonia", "Delta | airline", "Mercury | banking for startups" ], "minConfidence": 60, "searchFallback": "auto", "searchEngine": "bing", "useClearbit": true, "useWikidata": true, "includeUnresolved": true, "maxAlternatives": 3, "maxConcurrency": 20, "proxyConfiguration": { "useApifyProxy": true } } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `input` | string | The input line / name as given | | `companyName` | string | Company name that was looked up | | `status` | string | found (charged), low_confidence, not_found or error (free) | | `domain` | string | Best official website domain (registrable domain, e.g. stripe.com) | | `confidence` | integer | Confidence score 0-100 | | `website` | string | Homepage URL after redirects | | `companyNameFound` | string | Company name as found on the website / sources | | `title` | string | Homepage | | `description` | string | Homepage meta description | | `linkedinUrl` | string | LinkedIn company page linked from the homepage | | `logoUrl` | string | Logo URL found on the homepage | | `faviconUrl` | string | Favicon URL | | `finalUrl` | string | Final URL after redirects | | `redirectedFrom` | string | Original candidate domain if it redirected to the returned domain | | `isLive` | boolean | Homepage answered over HTTP(S) | | `httpStatus` | integer | Homepage HTTP status | | `sources` | array | Signals that pointed to this domain: clearbit, wikidata, search, guess | | `wikidataId` | string | Wikidata entity ID if matched | | `alternatives` | array | Runner-up candidates: {domain, confidence, sources, title, isLive, isParked} | | `bestGuess` | object | Top candidate when below the confidence threshold | | `hint` | object | Hints used (country, city, industry, text) | | `inputRecord` | object | Your original record (records / CSV input) | | `error` | string | | | `checkedAt` | string | UTC timestamp | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Competitor Keywords - Ranked Keywords of Any Domain > See every Google keyword a competitor ranks for: position, URL, search volume, CPC, keyword difficulty, intent and estimated traffic for any domain or page, in 90+ countries. Bulk domains, sortable, filterable. No SEO suite subscription needed. - Category: Keyword data - Price: $2 per 1,000 × ranked keyword, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/competitor-keywords - Human page: https://wrenfielddata.com/tools/competitor-keywords/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~competitor-keywords/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/competitor-keywords (appears as `wrenfield-data--competitor-keywords`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~competitor-keywords/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"domains": ["backlinko.com"], "location": "United States", "language": "English", "maxKeywordsPerDomain": 20}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `domains` | array | yes | `["backlinko.com"]` | Competitor domains (e.g. example.com) or full page URLs (e.g. https://example.com/blog/post), one per line. https:// and www. are removed automatically for domains. | | `location` | string | | `"United States"` | Country of the Google results: name (United States), 2-letter code (GB) or location code (2840). | | `language` | string | | | Language name or code (English, de). Leave empty for the main language of the country. | | `maxKeywordsPerDomain` | integer | | `100` | How many ranked keywords to return for each domain (up to 50,000). You pay per keyword returned. | | `sortBy` | string | | `"search_volume"` | Which keywords come first (and are kept when you limit the number of keywords). | | `minSearchVolume` | integer | | `0` | Only return keywords with at least this many monthly searches. 0 = all. | | `maxPosition` | integer | | `100` | Only return keywords where the domain ranks at this position or better (e.g. 10 = first page only). 100 = all. | | `resultTypes` | string | | `"organic"` | Which Google result types count as a ranking. | | `includeSubdomains` | boolean | | `true` | Count rankings of subdomains (e.g. blog.example.com) for a domain. | ## Example input ```json { "domains": [ "backlinko.com" ], "location": "United States", "language": "English", "maxKeywordsPerDomain": 20 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `domain` | string | Domain or page URL the keywords were looked up for | | `keyword` | string | Keyword the domain ranks for in Google | | `position` | integer | Google rank among results of the same type (1 = top) | | `position_absolute` | integer | Absolute position on the results page, counting all SERP elements | | `result_type` | string | Type of the ranking result: organic, paid, featured_snippet, local_pack or ai_overview_reference | | `url` | string | URL of the ranking page | | `title` | string | Title of the ranking result | | `search_volume` | integer | Average monthly Google searches for the keyword | | `cpc` | number | Average Google Ads cost per click (USD) | | `competition` | string | Google Ads competition level: LOW, MEDIUM or HIGH | | `keyword_difficulty` | integer | SEO keyword difficulty, 0-100 (higher = harder to rank) | | `search_intent` | string | Main search intent: informational, navigational, commercial or transactional | | `estimated_traffic` | number | Estimated monthly organic visits this ranking brings the domain | | `estimated_traffic_cost_usd` | number | What that traffic would cost per month in Google Ads (USD) | | `previous_position` | integer | Previous absolute position, when known | | `position_change` | string | Change since the previous check: new, up, down or same | | `serp_features` | array | SERP feature types present on the results page (e.g. people_also_ask, ai_overview) | | `is_featured_snippet` | boolean | True when the ranking result is a featured snippet | | `search_volume_trend` | object | Search volume change in % (monthly, quarterly, yearly) | | `location` | string | Country the data is for, e.g. "United States" | | `language` | string | Language name, e.g. "English" | | `serp_checked_at` | string | When the Google results page was last checked (ISO 8601, UTC) | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Domain Authority Checker: Backlinks, Website Traffic > Bulk domain authority, backlinks and organic traffic for thousands of domains. Licensed DataForSEO data (not Ahrefs/Semrush/Similarweb scraping). Flat rows + optional deep report. - Category: Domain & website intelligence - Price: $5 per 1,000 × domain result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/domain-authority-traffic-checker - Human page: https://wrenfielddata.com/tools/domain-authority-traffic-checker/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~domain-authority-traffic-checker/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/domain-authority-traffic-checker (appears as `wrenfield-data--domain-authority-traffic-checker`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~domain-authority-traffic-checker/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"domains": ["stripe.com", "shopify.com"], "mode": "bulk", "metrics": ["traffic"], "location": "United States", "language": "English", "rankScale": "one_thousand", "topBacklinks": 20, "topReferringDomains": 20, "topKeywords": 20, "topCompetitors": 10}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `domains` | array | yes | `["stripe.com", "shopify.com"]` | One domain or URL per line (e.g. stripe.com, https://www.shopify.com/). Domains are normalized (scheme and www. stripped). Page URLs are kept when they include a path. Up to 100,000; processed in batches of 1,000. Duplicates are removed. | | `mode` | string | | `"bulk"` | Bulk: one flat metrics row per domain (thousands supported). Deep report: one domain with top backlinks, referring domains, organic keywords and competitors (charged as a report). | | `metrics` | array | | `["traffic", "authority", "backlinks", "spamScore"]` | Which metrics to fetch. traffic uses DataForSEO Labs only (works without the Backlinks API). Authority, backlinks, spam and new/lost need the Backlinks API (pay-as-you-go, no monthly commitment as of Jul 2026). trafficValue is a per-domain Labs call and costs more at scale. | | `location` | string | | `"United States"` | Country for organic/paid traffic estimates. Name or code: United States, US, 2840. | | `language` | string | | `"English"` | Language name or code (English, en). | | `rankScale` | string | | `"one_thousand"` | Authority score scale from the Backlinks API: 0–1000 (default, closer to classic PageRank-style metrics) or 0–100. | | `topBacklinks` | integer | | `20` | How many top backlinks to include in a deep report. 0 to skip. | | `topReferringDomains` | integer | | `20` | How many top referring domains to include in a deep report. 0 to skip. | | `topKeywords` | integer | | `20` | How many top organic keywords to include in a deep report. 0 to skip. | | `topCompetitors` | integer | | `10` | How many SEO competitor domains to include in a deep report. 0 to skip. | ## Example input ```json { "domains": [ "stripe.com", "shopify.com" ], "mode": "bulk", "metrics": [ "traffic" ], "location": "United States", "language": "English", "rankScale": "one_thousand", "topBacklinks": 20, "topReferringDomains": 20, "topKeywords": 20, "topCompetitors": 10 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `domain` | string | Normalized domain (or page host for reports) | | `input` | string | Original input domain or URL | | `mode` | string | bulk or report | | `found` | boolean | true if at least one requested metric was returned (only these rows are charged) | | `domain_rank` | integer | Domain rank / authority score (DataForSEO Rank, not Ahrefs DR) | | `rank_scale` | string | 0-1000 or 0-100 | | `backlinks` | integer | Live backlinks count | | `referring_domains` | integer | | | `referring_domains_nofollow` | integer | | | `referring_main_domains` | integer | | | `referring_ips` | integer | Referring IPs (deep report / summary) | | `referring_subnets` | integer | Referring subnets (deep report / summary) | | `dofollow_backlinks` | integer | Approx. dofollow referring pages (report mode) | | `nofollow_backlinks` | integer | Nofollow referring pages (report mode) | | `spam_score` | integer | Spam score 0-100 | | `new_backlinks` | integer | | | `lost_backlinks` | integer | | | `new_referring_domains` | integer | | | `lost_referring_domains` | integer | | | `organic_traffic` | number | Estimated monthly organic traffic (ETV) | | `organic_keywords` | integer | Organic keyword / SERP count | | `paid_traffic` | number | | | `paid_keywords` | integer | | | `traffic_value_usd` | number | Estimated monthly traffic value in USD | | `top_countries` | array | Top referring countries [{country, backlinks}] (report) | | `first_seen` | string | When the first backlink was seen (report) | | `location` | string | | | `location_code` | integer | | | `language` | string | | | `language_code` | string | | | `metrics_available` | array | Which metric groups were filled | | `note` | string | | | `error` | string | | | `scraped_at` | string | | | `top_backlinks` | array | | | `top_referring_domains` | array | | | `top_organic_keywords` | array | | | `competitors` | array | | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Ads Transparency Scraper - Competitor Ads > Scrape Google Ads Transparency Center creatives by advertiser name, AR ID, domain or URL: ad text (headline/description), images, YouTube videos, regions, impression ranges, platforms and first/last shown dates. Monitoring mode detects new and stopped ads. Fast HTTP, no browser. - Category: Domain & website intelligence - Price: $1.50 per 1,000 × ad result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-ads-transparency-scraper - Human page: https://wrenfielddata.com/tools/google-ads-transparency-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-ads-transparency-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-ads-transparency-scraper (appears as `wrenfield-data--google-ads-transparency-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-ads-transparency-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"targets": ["Nike"], "maxAdsPerTarget": 5, "region": "anywhere", "includeDetails": true, "extractAdText": true, "ocrTextAds": true, "ocrLanguage": "auto", "advertiserSummary": true, "maxAdvertisersPerName": 1, "monitorMode": false, "monitorStoreName": "google-ads-transparency-monitor", "activeWithinDays": 7, "emitBaselineOnFirstRun": true, "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "maxConcurrency": 8, "dataForSeoFallback": false}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `targets` | array | yes | `["Nike"]` | One per line. Accepts: an advertiser name (Nike), an advertiser ID (AR16735076323512287233), a website domain (grammarly.com - returns every advertiser running ads for that site), or any Ads Transparency Center URL (advertiser page, single creative page, or a domain search; filters in the URL such as region, platform, format and dates are respected). | | `maxAdsPerTarget` | integer | | `50` | How many ad creatives to return for each target, newest (most recently shown) first. Big brands have thousands of ads. | | `region` | string | | `"anywhere"` | Only ads shown in this country. Anywhere = all regions. | | `lastDays` | integer | | | Only ads shown at least once in the last N days (e.g. 30). Overrides the date range below. | | `dateFrom` | string | | | Only ads shown on or after this date (YYYY-MM-DD). Data starts in 2018. | | `dateTo` | string | | | Only ads shown on or before this date (YYYY-MM-DD). Default: today. | | `formats` | array | | | Leave empty for all formats. | | `platforms` | array | | | Leave empty for all platforms (this also includes Display-network ads, which have no separate filter in the Transparency Center). | | `includeDetails` | boolean | | `true` | Open each ad's detail record: every region it ran in with first/last shown dates, impression ranges and per-platform breakdown (impressions and platforms are published for EU/EEA regions), topic and targeting categories. Turn off for a faster list-only scrape. | | `extractAdText` | boolean | | `true` | Read headline, description, call to action, display/landing URL, YouTube video ID and image URLs from the ad previews. | | `ocrTextAds` | boolean | | `true` | Google archives most Search text ads only as a rendered image. With this on, the Actor reads the headline, description, display URL and sitelinks from that image with OCR (marked textSource: "ocr"). | | `ocrLanguage` | string | | `"auto"` | Language model used to read text ads archived as images. Automatic picks the language of the selected region, of the countries the ad ran in, or of the domain (e.g. zalando.de -> German), and English otherwise. Latin-script models read English text too. | | `advertiserSummary` | boolean | | `true` | One extra row per advertiser (type: "summary") with active ad count, total ads estimate, format and platform mix and top regions. Summary rows are free. | | `maxAdvertisersPerName` | integer | | `1` | A name can match several advertiser accounts (e.g. regional subsidiaries). How many of the best matches to scrape. | | `monitorMode` | boolean | | `false` | Compares each target with the previous run (state kept in a named key-value store) and outputs only ads that are NEW since the last run or have STOPPED running (changeType field). Schedule the Actor daily or weekly for competitor-ad alerts. | | `monitorStoreName` | string | | `"google-ads-transparency-monitor"` | Named key-value store that keeps the last-seen ads per target. Use different names to keep independent watch lists. | | `activeWithinDays` | integer | | `7` | An ad whose last-shown date is older than this is treated as inactive (isActive: false) and, in monitoring mode, reported as STOPPED. | | `emitBaselineOnFirstRun` | boolean | | `true` | On the first run for a target there is nothing to compare with, so every current ad is reported as NEW. Turn off to silently store the baseline and only report changes from the second run on. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Apify Proxy is used by default (datacenter first, automatic residential fallback if Google throttles). | | `residentialFallback` | boolean | | `true` | If datacenter IPs are throttled, retry through Apify residential proxy automatically. | | `maxConcurrency` | integer | | `8` | Parallel requests to the Transparency Center. | | `dataForSeoFallback` | boolean | | `false` | Only for self-hosted copies with DATAFORSEO_LOGIN / DATAFORSEO_PASSWORD environment variables: if the Transparency Center request fails, fetch the ad list from DataForSEO instead (list data only). | ## Example input ```json { "targets": [ "Nike" ], "maxAdsPerTarget": 5, "region": "anywhere", "includeDetails": true, "extractAdText": true, "ocrTextAds": true, "ocrLanguage": "auto", "advertiserSummary": true, "maxAdvertisersPerName": 1, "monitorMode": false, "monitorStoreName": "google-ads-transparency-monitor", "activeWithinDays": 7, "emitBaselineOnFirstRun": true, "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": true, "maxConcurrency": 8, "dataForSeoFallback": false } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: ad, summary or error (summary and error rows are free) | | `changeType` | string | Monitoring mode: NEW (first seen), STOPPED (no longer running or removed) or RESUMED (stopped before, running again) | | `previewImageUrl` | string | Rendered preview image of the ad (text ads are archived as images) | | `advertiserName` | string | Advertiser name as shown in the Transparency Center | | `advertiserId` | string | Advertiser ID (AR...) | | `advertiserVerified` | boolean | Advertiser identity verified by Google | | `advertiserCountry` | string | Advertiser country (ISO code) | | `advertiserLegalName` | string | Advertiser legal name | | `creativeId` | string | Ad creative ID (CR...) | | `format` | string | TEXT, IMAGE or VIDEO | | `headline` | string | Ad headline | | `description` | string | Ad description / body text | | `longHeadline` | string | Long headline (responsive display / video ads) | | `callToAction` | string | Call-to-action text | | `displayUrl` | string | Display URL shown in the ad | | `businessName` | string | Business / brand name shown in the ad | | `sitelinks` | array | Sitelink texts (text ads, OCR) | | `productTitle` | string | Product title (Shopping ads) | | `merchant` | string | Merchant (Shopping ads) | | `textSource` | string | Where the ad text came from: preview (structured) or ocr (read from the ad image) | | `ocrConfidence` | number | Average OCR confidence 0-100 | | `ocrLanguage` | string | OCR language model used (tesseract code, e.g. eng, deu, jpn) | | `landingUrl` | string | Final/destination URL when the preview exposes it | | `landingDomain` | string | Domain the ad points to | | `imageUrls` | array | Image asset URLs | | `videoId` | string | YouTube video ID (video ads) | | `videoUrl` | string | YouTube video URL | | `videoTitle` | string | YouTube video title (video ads) | | `videoThumbnailUrl` | string | YouTube thumbnail | | `youtubeChannel` | string | YouTube channel name | | `videoDuration` | string | Video duration | | `firstShown` | string | First time the ad was shown (UTC) | | `lastShown` | string | Last time the ad was shown (UTC) | | `daysShown` | integer | Number of days the ad was shown | | `isActive` | boolean | Shown within the last activeWithinDays days | | `regionCodes` | array | Countries where the ad was shown | | `regions` | array | Per region: first/last shown, impression range and per-platform impressions (impressions published for EU/EEA) | | `impressionsMin` | integer | Total impressions, lower bound (EU/EEA) | | `impressionsMax` | integer | Total impressions, upper bound (EU/EEA) | | `platforms` | array | Platforms the ad ran on (GOOGLE_SEARCH, YOUTUBE, GOOGLE_SHOPPING, GOOGLE_MAPS, GOOGLE_PLAY) | | `topic` | string | Ad topic / vertical | | `targeting` | object | Targeting criteria used (EU/EEA disclosure): demographics, locations, contextual signals, customer lists, topics of interest | | `variationsCount` | integer | Number of ad variations | | `adUrl` | string | Ad page in the Google Ads Transparency Center | | `detailsError` | string | Why details could not be loaded (row still returned) | | `adsInThisRun` | integer | Summary: ads returned for this advertiser | | `activeAdCount` | integer | Summary: ads shown within activeWithinDays | | `newThisRun` | integer | Summary (monitoring): new ads this run | | `stoppedThisRun` | integer | Summary (monitoring): stopped ads this run | | `totalAdsMin` | integer | Summary: total ads Google reports for the target and filters (lower bound; the same for every advertiser of a domain target) | | `totalAdsMax` | integer | Summary: total ads Google reports for the target and filters (upper bound) | | `formatsMix` | object | Summary: ads per format | | `platformsMix` | object | Summary: ads per platform | | `topRegions` | object | Summary: ads per region | | `adsWithText` | integer | Summary: ads with extracted text | | `matchedBy` | string | Summary: how a name input was matched (exact-name, domain-suggestion, ...) | | `advertiserUrl` | string | Summary: advertiser page in the Transparency Center | | `input` | string | Error rows: the input that failed | | `error` | string | Error rows: reason | | `target` | object | Input target and filters this row came from | | `scrapedAt` | string | Scrape time (UTC) | | `newestAdFirstShown` | string | Summary: most recent first-shown date among the ads | | `latestShown` | string | Summary: most recent last-shown date | | `allAdsFetched` | boolean | Summary: true when all ads of the target were fetched (not capped by maxAdsPerTarget) | | `firstMonitoringRun` | boolean | Summary (monitoring): true on the first (baseline) run | | `monitoringRun` | integer | Summary (monitoring): run number for this target | | `note` | string | Summary: note, e.g. why no ads were found | | `source` | string | Data source: Transparency Center (default) or dataforseo (optional fallback) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google AI Overview Scraper - Answers, Sources & Brand Tracking > Scrape Google AI Overviews for any query: full answer text and Markdown, every cited source, and whether your domain or brand is cited. Plus organic top 10, People Also Ask and related searches in the same row. Any country, language, city or device. $2.50 per 1,000 queries. - Category: AI search visibility - Price: $2.50 per 1,000 × query checked, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-ai-overview-scraper - Human page: https://wrenfielddata.com/tools/google-ai-overview-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-ai-overview-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-ai-overview-scraper (appears as `wrenfield-data--google-ai-overview-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-ai-overview-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"queries": ["best crm for small business", "is coffee good for you", "how to lower cholesterol naturally"], "targetDomains": ["hubspot.com"], "brands": ["HubSpot", "Salesforce", "Zoho"], "location": "United States", "language": "English"}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `queries` | array | yes | `["best crm for small business", "is coffee good for you", "how to lower cholesterol naturally"]` | Google searches to check, one per line. Each query is one Google results page. Questions and comparisons ("best crm for small business", "hubspot vs salesforce") trigger AI Overviews most often. | | `targetDomains` | array | | | Optional. Domains to look for among the AI Overview's cited sources, e.g. hubspot.com. Subdomains count. Each row then shows whether each domain is cited, at which source positions, and its organic position. | | `brands` | array | | | Optional. Brand names to look for in the AI Overview text (case-insensitive, whole words). Each row lists which brands are mentioned and which are not. | | `location` | string | | `"United States"` | Country name (United States), 2-letter code (GB), location code (2840), or a full Google location name for cities and regions (e.g. London,England,United Kingdom). | | `language` | string | | | Language name or code (English, de). Leave empty for the main language of the country. | | `device` | string | | `"desktop"` | Desktop or mobile Google results. | | `mode` | string | | `"standard"` | Standard ($2.50 / 1,000 queries): results usually arrive in 10-30 seconds for the whole batch, sometimes a few minutes at peak times. Fast ($6 / 1,000 queries): every query is fetched live and in parallel, usually 5-25 seconds each, with no queue. Same data in both. | | `includeOrganicResults` | boolean | | `true` | Add the top 10 organic results (position, title, URL, domain, description) to each row. Free. | | `includePeopleAlsoAsk` | boolean | | `true` | Add the People Also Ask questions shown on the page. Free. | | `includeRelatedSearches` | boolean | | `true` | Add the related searches from the bottom of the page. Free. | | `onlyWithAiOverview` | boolean | | `false` | Skip rows for queries where Google showed no AI Overview. They are still checked and charged; the run summary counts them. | ## Example input ```json { "queries": [ "best crm for small business", "is coffee good for you", "how to lower cholesterol naturally" ], "targetDomains": [ "hubspot.com" ], "brands": [ "HubSpot", "Salesforce", "Zoho" ], "location": "United States", "language": "English" } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `query` | string | Google search checked | | `has_ai_overview` | boolean | Whether Google showed an AI Overview (null if the query failed) | | `status` | string | ai_overview, no_ai_overview or failed (failed queries are not charged) | | `ai_overview_text` | string | AI Overview as plain text | | `ai_overview_markdown` | string | AI Overview as Markdown (headings, lists, bold) | | `ai_overview_word_count` | integer | Words in the AI Overview | | `ai_overview_sections` | array | Sections of the AI Overview with title, text and the positions of the sources each section cites | | `ai_overview_is_async` | boolean | True when Google loaded the AI Overview after the page (captured anyway) | | `references` | array | Every cited source: position, title, source name, domain, URL, snippet | | `reference_count` | integer | Number of unique cited sources | | `referenced_domains` | array | Unique cited domains, in citation order | | `target_domains` | array | Per domain from your input: cited (true/false), source positions, organic position | | `target_cited` | boolean | True if any of your domains is cited | | `target_first_reference_position` | integer | Best (lowest) source position of your domains | | `brands_mentioned` | array | Brands from your input that appear in the AI Overview text | | `brands_not_mentioned` | array | Brands from your input that do not appear | | `organic_results` | array | Organic top 10: position, title, URL, domain, description | | `people_also_ask` | array | People Also Ask questions on the page | | `related_searches` | array | Related searches on the page | | `serp_features` | array | Result types on the page (ai_overview, organic, video, local_pack...) | | `google_url` | string | The Google search URL that was checked | | `error` | string | Why the query failed (failed rows only) | | `location` | string | Location searched from | | `language` | string | Search language | | `device` | string | desktop or mobile | | `checked_at` | string | When the page was checked (UTC, ISO 8601) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Autocomplete Keyword Expander - Long-Tail Ideas > Turn seed keywords into hundreds of long-tail keyword ideas from Google and YouTube autocomplete: A-Z, questions, prepositions and buyer modifiers, any country and language. Optional search volume, CPC and keyword difficulty. $1 per 1,000 keywords. - Category: Keyword data - Price: $1 per 1,000 × keyword suggestion, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-autocomplete-keyword-expander - Human page: https://wrenfielddata.com/tools/google-autocomplete-keyword-expander/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-autocomplete-keyword-expander/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-autocomplete-keyword-expander (appears as `wrenfield-data--google-autocomplete-keyword-expander`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-autocomplete-keyword-expander/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"seedKeywords": ["running shoes"], "country": "US", "language": "English", "expansions": ["alphabet", "questions", "prepositions"], "maxKeywords": 100}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `seedKeywords` | array | yes | `["running shoes"]` | Topics to expand, one per line (e.g. running shoes). Each seed is combined with the modifiers below and sent to autocomplete. | | `country` | string | | `"US"` | Country of the suggestions: name (United States) or 2-letter code (GB, DE). | | `language` | string | | `"English"` | Language name or code (English, de). | | `expansions` | array | | `["alphabet", "questions", "prepositions"]` | How to expand each seed. alphabet: seed + a…z. numbers: seed + 0…9. questions: how / what / why / … + seed. prepositions: seed + for / with / vs / near / … commercial: best / cheap / review / price / alternative / near me … | | `maxKeywords` | integer | | `500` | Maximum number of unique keyword suggestions per run (shared across seeds). You pay per keyword returned. | | `deepExpand` | boolean | | `false` | Also run autocomplete on the first suggestions to find even longer long-tail phrases. | | `mustContainSeed` | boolean | | `false` | Drop suggestions that don't contain the seed keyword as written. | | `source` | string | | `"google"` | Google web search or YouTube search suggestions. | | `addSearchVolume` | boolean | | `false` | Enrich every suggestion with monthly search volume, CPC, competition, keyword difficulty and search intent (Google Search only, country level). Extra charge per enriched keyword, see Pricing. | ## Example input ```json { "seedKeywords": [ "running shoes" ], "country": "US", "language": "English", "expansions": [ "alphabet", "questions", "prepositions" ], "maxKeywords": 100 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `keyword` | string | Autocomplete suggestion (normalized, lower-case) | | `seed_keyword` | string | Seed keyword the suggestion came from | | `expanded_from` | string | With deep expansion: the first-level suggestion that was expanded again | | `query` | string | Exact query sent to autocomplete (seed + modifier) | | `modifier` | string | Letter, digit, question word or preposition added to the seed | | `position` | integer | Position of the suggestion in the autocomplete list (1 = top) | | `relevance` | integer | Google suggest relevance score, when provided | | `depth` | integer | 0 = from the seed, 1 = from deep expansion | | `word_count` | integer | Number of words in the suggestion | | `is_question` | boolean | True when the suggestion is a question (how, what, why ...) | | `source` | string | google_autocomplete or youtube_autocomplete | | `country` | string | Country ISO code used, e.g. US | | `language` | string | Language code used, e.g. en | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | | `search_volume` | integer | Average monthly Google searches (only with addSearchVolume) | | `cpc` | number | Average Google Ads cost per click in USD (only with addSearchVolume) | | `competition` | string | Google Ads competition level (only with addSearchVolume) | | `keyword_difficulty` | integer | SEO keyword difficulty 0-100 (only with addSearchVolume) | | `search_intent` | string | Main search intent (only with addSearchVolume) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Jobs Scraper - Job Listings & Salaries > Scrape Google Jobs (the jobs panel in Google Search) by keyword and location: title, company, location, salary (parsed), posted date, employment type, full description, highlights, and every apply link with board names. Deduplicated, 70+ countries. - Category: Jobs & content - Price: $2 per 1,000 × job result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-jobs-scraper - Human page: https://wrenfielddata.com/tools/google-jobs-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-jobs-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-jobs-scraper (appears as `wrenfield-data--google-jobs-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-jobs-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"queries": ["data analyst"], "locations": ["Austin, TX"], "country": "US", "language": "en", "maxResultsPerQuery": 10, "datePosted": "anytime", "remoteOnly": false, "includeDetails": true, "includeAllApplyLinks": true, "dedupe": true}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `queries` | array | yes | `["data analyst"]` | What you would type into Google Jobs, one per line, e.g. data analyst, registered nurse, python developer. Each query is searched in every location. | | `locations` | array | | | Cities, states or regions, one per line, e.g. Austin, TX, London, Bengaluru, Bavaria. Matched to Google's own locations inside the selected country (add the state for ambiguous US cities: Portland, ME). Leave empty to search the whole country. Enter Remote for remote jobs. | | `country` | string | | `"US"` | Country to search in (Google Jobs is available in these countries). | | `language` | string | | | 2-letter language code of the Google interface and results, e.g. en, de, fr. Leave empty for the country's main language (English for US, UK and India). | | `maxResultsPerQuery` | integer | | `50` | Maximum number of jobs to return for each query × location combination. Google Jobs shows up to about 200 jobs per search. | | `maxResults` | integer | | | Optional cap on the total number of jobs in this run (all queries and locations together). Leave empty for no cap. | | `datePosted` | string | | `"anytime"` | Only return jobs posted within this period. | | `employmentTypes` | array | | | Only return these employment types. Leave empty for all. | | `remoteOnly` | boolean | | `false` | Only return remote / work-from-home jobs. | | `radiusKm` | integer | | | Optional radius around each city in kilometers (1-300). Leave empty for Google's default. | | `includeDetails` | boolean | | `true` | Include the job description and Google's job highlights (qualifications, responsibilities, benefits). Turn off for smaller, list-only results. | | `includeAllApplyLinks` | boolean | | `true` | Return every 'Apply on ...' option (LinkedIn, Indeed, the company site, ...) with board names and URLs. When off, only the main apply link is returned. | | `dedupe` | boolean | | `true` | Return each job only once, even if it appears in several queries or locations. | ## Example input ```json { "queries": [ "data analyst" ], "locations": [ "Austin, TX" ], "country": "US", "language": "en", "maxResultsPerQuery": 10, "datePosted": "anytime", "remoteOnly": false, "includeDetails": true, "includeAllApplyLinks": true, "dedupe": true } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `title` | string | Job title | | `company` | string | Company / employer name | | `location` | string | Location as shown by Google ('Anywhere' = remote) | | `jobLocation` | string | Location from the job details if different | | `otherLocationsCount` | integer | Number of additional locations | | `remote` | boolean | Remote / work from home | | `via` | string | Job board Google got the posting from (LinkedIn, Indeed, company site...) | | `postedAt` | string | Posted date (ISO 8601, UTC, approximate) | | `postedAgo` | string | Posted, as shown by Google ('3 days ago') | | `employmentType` | string | Full-time, Part-time, Contractor or Internship | | `employmentTypes` | array | All employment types | | `employmentTypeText` | string | Employment type as shown | | `salaryMin` | number | Minimum salary | | `salaryMax` | number | Maximum salary | | `salaryCurrency` | string | ISO currency | | `salaryInterval` | string | YEAR, MONTH, WEEK, DAY or HOUR | | `salaryText` | string | Salary as shown | | `salarySource` | string | google (salary chip) or description (parsed from text) | | `benefits` | array | Benefit chips (health insurance, paid time off...) | | `noDegreeMentioned` | boolean | Google's 'No degree mentioned' flag | | `applyUrl` | string | Main apply link | | `applyOptions` | array | All apply links: title (board), url, domain | | `shareLink` | string | Google Jobs share link | | `companyLogo` | string | Company logo URL | | `companyUrl` | string | Company website | | `jobId` | string | Google Jobs job ID | | `description` | string | Full job description (plain text) | | `descriptionIsPreview` | boolean | True if Google only shows a preview (e.g. EU countries) | | `highlights` | object | Qualifications, responsibilities and benefits identified by Google | | `highlightSections` | array | Highlight sections as shown | | `query` | string | Your search query | | `searchLocation` | string | Google location used for the search | | `locationInput` | string | Your location input | | `country` | string | Country code | | `language` | string | Language code | | `position` | integer | Rank in the search results | | `source` | string | Data source | | `scrapedAt` | string | Scraped at (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Maps Geo-Grid Rank Tracker - Local Falcon Alternative > See where a business ranks on Google Maps across an N x N grid around it: rank per pin, average rank, share of local voice, top competitors per pin, a heatmap image and changes since the last run. $0.008 per grid point, a 7x7 scan costs $0.40. - Category: Rank tracking & site SEO - Price: $8 per 1,000 × grid point, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-maps-grid-rank-tracker - Human page: https://wrenfielddata.com/tools/google-maps-grid-rank-tracker/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-maps-grid-rank-tracker/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-maps-grid-rank-tracker (appears as `wrenfield-data--google-maps-grid-rank-tracker`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-maps-grid-rank-tracker/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"keywords": ["roofer"], "businessName": "Boise Roofing and Gutters", "businessLocation": "Boise, ID", "gridSize": 5, "radiusKm": 3}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `keywords` | array | yes | `["roofer"]` | What customers search on Google Maps, e.g. plumber, emergency plumber. Up to 20. | | `businessName` | string | | | The business to track, exactly as on Google Maps. | | `businessLocation` | string | | | Helps find the right business, e.g. Boise, ID. | | `placeId` | string | | | Most precise way to identify the business (e.g. ChIJ...). | | `cid` | string | | | Alternative business ID (the number in maps?cid=...). | | `businessDomain` | string | | | Used to match the business when no ID is given. | | `centerCoordinates` | string | | | Latitude, longitude for the grid centre, e.g. 43.6150, -116.2023. Default: the business location. | | `gridSize` | integer | | `5` | Points per side (odd number): 3 = 9 points, 5 = 25, 7 = 49, 9 = 81, up to 15 = 225. | | `radiusKm` | number | | `3` | Distance from the centre to the outer points. 1-3 km for dense cities, 5-15 km for suburbs and service areas. | | `depth` | integer | | `20` | How deep to look in each Google Maps result list (10-100). Ranks beyond this show as "20+". | | `zoom` | integer | | `13` | Google Maps zoom level used at each point (13 = city level, 15 = neighbourhood). | | `trackChanges` | boolean | | `true` | Remember results in a named key-value store ("maps-grid-rank-history") so each run shows rank changes. | | `country` | string | | `"United States"` | Country used to find the business by name. | | `language` | string | | | Language of the results. Default: English. | ## Example input ```json { "keywords": [ "roofer" ], "businessName": "Boise Roofing and Gutters", "businessLocation": "Boise, ID", "gridSize": 5, "radiusKm": 3 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `row_type` | string | pin = rank at one grid point; summary = one row per keyword with averages, competitors and the heatmap | | `keyword` | string | Keyword checked | | `business_name` | string | Tracked business | | `pin` | integer | pin rows: point number (row by row from the north-west corner) | | `row` | integer | pin rows: grid row (1 = north) | | `col` | integer | pin rows: grid column (1 = west) | | `latitude` | number | pin rows: latitude of the point | | `longitude` | number | pin rows: longitude of the point | | `distance_km` | number | pin rows: distance from the grid centre | | `rank` | integer | pin rows: Google Maps rank of the business at this point (null = not in the results checked) | | `found` | boolean | pin rows: the business appears in the results | | `in_top3` | boolean | pin rows: rank 1-3 (the local pack) | | `rank_label` | string | pin rows: rank as text, e.g. "4" or "20+" | | `previous_rank` | integer | pin rows: rank in the previous run | | `rank_change` | integer | pin rows: positions gained since the previous run (positive = better) | | `top_results` | array | pin rows: top 3 businesses at this point | | `results_checked` | integer | pin rows: results returned at this point | | `business_place_id` | string | summary: place ID of the tracked business | | `business_cid` | string | summary: CID of the tracked business | | `grid_size` | integer | summary: points per side | | `radius_km` | number | summary: grid radius | | `zoom` | integer | summary: map zoom | | `center_latitude` | number | summary: grid centre latitude | | `center_longitude` | number | summary: grid centre longitude | | `pins_checked` | integer | summary: points checked | | `pins_found` | integer | summary: points where the business appears | | `pins_top3` | integer | summary: points where it ranks 1-3 | | `pins_top10` | integer | summary: points where it ranks 1-10 | | `average_rank` | number | summary: average rank where found (ARP) | | `average_total_rank` | number | summary: average rank over all points, not found = depth + 1 (ATRP) | | `share_of_local_voice` | number | summary: % of points where the business is in the top 3 (SoLV) | | `best_rank` | integer | summary: best rank on the grid | | `previous_average_total_rank` | number | summary: ATRP in the previous run | | `previous_share_of_local_voice` | number | summary: SoLV in the previous run | | `average_total_rank_change` | number | summary: ATRP improvement since the previous run (positive = better) | | `share_of_local_voice_change` | number | summary: SoLV change in percentage points | | `previous_checked_at` | string | summary: when the previous run checked this keyword | | `top_competitors` | array | summary: competitors that rank best across the grid (pins in top 3, average rank) | | `heatmap_url` | string | summary: link to the heatmap PNG in the run key-value store | | `scraped_at` | string | When the row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Shopping Scraper - Price Comparison & UPC > Compare Google Shopping prices by keyword, barcode (UPC/EAN/GTIN), product ID or URL. Every seller offer with price, shipping, total, condition and stock, plus min/max/typical price. Price monitoring flags price drops and new or removed sellers. 45 countries. - Category: E-commerce & reviews - Price: $2 per 1,000 × product result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-shopping-price-comparison - Human page: https://wrenfielddata.com/tools/google-shopping-price-comparison/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-shopping-price-comparison/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-shopping-price-comparison (appears as `wrenfield-data--google-shopping-price-comparison`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-shopping-price-comparison/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"queries": ["coffee maker"], "gtins": ["025500304076"], "country": "US", "sort": "relevance", "condition": "any", "maxProducts": 2, "maxProductsPerQuery": 40, "fetchOffers": true, "maxOffersPerProduct": 10, "includeDetails": false, "resolveOfferUrls": true, "onlyChanges": false, "minPriceChangePct": 0}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `queries` | array | | | Product searches, exactly as you would type them into Google Shopping (e.g. air fryer, iphone 15 128gb). One product row per result, up to Max products per query. You can also paste a Google Shopping search URL. | | `gtins` | array | | | Barcodes to look up, one per line: 12-digit UPC, 13-digit EAN, 14-digit GTIN or 8-digit EAN-8 (e.g. 025500304076). Each barcode is matched to its Google Shopping product and verified against independent web listings for that barcode. Barcodes that cannot be matched are listed as not_found and are free. | | `productIds` | array | | | Google Shopping product IDs (the productId from a previous run, e.g. 14870010698400265781) or Google Shopping product URLs (google.com/shopping/product/... or google.com/search?ibp=oshop&...prds=... links). Best for monitoring a fixed list of products. | | `country` | string | | `"US"` | Google Shopping country. Prices, sellers and currency are for this country. | | `language` | string | | | Language code such as en, de, fr, es, pt-BR. Leave empty for the country's main language. | | `location` | string | | | Get local results for a place inside the country, e.g. 10001, Chicago, Bavaria or London,England,United Kingdom. Leave empty for the whole country. | | `sort` | string | | `"relevance"` | Sort order for search queries (barcodes and product IDs are not affected). | | `minPrice` | integer | | | Only search results at or above this price (whole currency units). | | `maxPrice` | integer | | | Only search results at or below this price (whole currency units). | | `condition` | string | | `"any"` | Filters seller offers by condition. For search results it removes or keeps products whose title says refurbished / renewed / used / pre-owned (best effort). | | `maxProducts` | integer | | `100` | Maximum product rows for the whole run (barcodes and product IDs first, then search results). Duplicate products are skipped. | | `maxProductsPerQuery` | integer | | `40` | How many results to take from each search query (Google Shopping returns up to about 120). | | `fetchOffers` | boolean | | `true` | For every product, get the seller offers (Compare prices list): seller, price, shipping, total, condition, availability, seller rating and offer URL. Also fills min/max/typical price and number of sellers. Turn off for a cheaper product-only scrape. | | `maxOffersPerProduct` | integer | | `20` | Maximum seller offers per product (Google lists up to about 100). | | `includeDetails` | boolean | | `false` | Also get brand, description, all images, specifications and variants for each search result (adds the product-details event per product). Barcode and product ID lookups always include details. | | `resolveOfferUrls` | boolean | | `true` | Turn Google redirect links into the direct merchant product URL (e.g. the walmart.com or target.com page). Off = keep Google's redirect link. | | `monitoringStoreName` | string | | | Turn on price monitoring: give a name (e.g. my-price-watch). Each run is compared with the previous run that used the same name, country and language. Products get a priceMonitor object (price drop / increase, new and removed sellers) and offers get changeStatus. Removed sellers are added as free offer rows. Schedule the Actor to monitor prices daily. | | `onlyChanges` | boolean | | `false` | With price monitoring on, skip products whose price and sellers did not change (they are not charged) and unchanged offers. | | `minPriceChangePct` | integer | | `0` | Price changes below this percentage count as unchanged. | ## Example input ```json { "queries": [ "coffee maker" ], "gtins": [ "025500304076" ], "country": "US", "sort": "relevance", "condition": "any", "maxProducts": 2, "maxProductsPerQuery": 40, "fetchOffers": true, "maxOffersPerProduct": 10, "includeDetails": false, "resolveOfferUrls": true, "onlyChanges": false, "minPriceChangePct": 0 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | product, offer or not_found (not_found rows are free) | | `title` | string | Product title | | `productId` | string | Google Shopping product ID (catalog ID) | | `gid` | string | Google global product ID | | `gtin` | string | Barcode you searched (barcode lookups) | | `gtin14` | string | Barcode as 14-digit GTIN | | `brand` | string | Brand (with details) | | `image` | string | Main image URL | | `rating` | number | Product rating 1-5 | | `reviewsCount` | integer | Number of product reviews | | `price` | number | Headline price shown on Google Shopping | | `oldPrice` | number | Previous / strike-through price | | `minPrice` | number | Lowest seller price | | `maxPrice` | number | Highest seller price | | `typicalPrice` | number | Median seller price | | `minTotalPrice` | number | Lowest price incl. shipping | | `cheapestSeller` | string | Seller with the lowest total price | | `sellersCount` | integer | Number of sellers (offers returned, or Google's count) | | `currency` | string | Currency (ISO code) | | `headlineSeller` | string | Seller shown in search results | | `delivery` | string | Delivery info | | `tags` | array | Badges, e.g. LOW PRICE, 10% OFF | | `productUrl` | string | Brand / product URL | | `googleShoppingUrl` | string | Google Shopping product link | | `description` | string | Description | | `images` | array | All images | | `specifications` | object | Specifications | | `features` | array | Feature bullets | | `variants` | array | Variants (size, color, ...) | | `match` | object | Barcode match: method, confidence, rank, name from web listings | | `priceMonitor` | object | Price monitoring: status, previous price, change, new / removed sellers | | `source` | object | Input that produced this row | | `productTitle` | string | Product title (offer rows) | | `sellerName` | string | Seller | | `offerTitle` | string | Seller's own product title | | `shippingPrice` | number | Shipping cost | | `tax` | number | Tax | | `totalPrice` | number | Price + shipping | | `condition` | string | new, used or refurbished | | `availability` | string | in_stock, out_of_stock, ... | | `sellerRating` | number | Seller rating 1-5 | | `sellerReviewsCount` | integer | Seller reviews | | `annotation` | string | Deal note, e.g. 39% off | | `offerUrl` | string | Merchant offer URL | | `googleOfferUrl` | string | Google redirect link to the offer | | `merchantDomain` | string | Merchant domain | | `walmartItemId` | string | Walmart item ID (Walmart offers) | | `isAd` | boolean | Sponsored offer | | `position` | integer | Offer position | | `changeStatus` | string | new, price_drop, price_increase, unchanged or removed | | `previousPrice` | number | Price in the previous monitoring run | | `priceChange` | number | Price change | | `priceChangePct` | number | Price change (%) | | `country` | string | Country | | `language` | string | Language | | `location` | string | Location | | `input` | string | Input (not_found rows) | | `error` | string | Why nothing was found (not_found rows) | | `scrapedAt` | string | Scrape time (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Google Trends Scraper & API - Bulk, Trending Now > Reliable Google Trends API: interest over time, interest by region/city, related queries and topics (top + rising), and Trending Now by country. Compare up to 5 terms, batch hundreds, any geo, time range, category or YouTube/News/Shopping. Auto-retries with fresh sessions. - Category: Keyword data - Price: $3 per 1,000 × search term analysed, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/google-trends-scraper - Human page: https://wrenfielddata.com/tools/google-trends-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~google-trends-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/google-trends-scraper (appears as `wrenfield-data--google-trends-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~google-trends-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"searchTerms": ["coffee", "tea, matcha"], "geos": ["US"], "timeRange": "today 12-m", "category": 0, "property": "web", "includeInterestOverTime": true, "includeInterestByRegion": true, "regionResolution": "auto", "includeLowSearchVolumeRegions": false, "maxRegions": 250, "includeRelatedQueries": true, "includeRelatedTopics": false, "maxRelatedItems": 25, "trendingGeos": ["US"], "trendingHours": "24", "trendingActiveOnly": false, "maxTrendingPerGeo": 10, "includeTrendingNews": true, "outputFormat": "flat", "language": "en-US", "timezoneOffsetMinutes": 0, "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "maxConcurrency": 5, "maxRetries": 8}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `searchTerms` | array | | | One search term (or Google Trends topic ID like /m/02vqfm) per line. To compare up to 5 terms on the same 0-100 scale, put them on one line separated by commas, e.g. coffee, tea, matcha. Add as many lines as you like - each line is scraped separately for every geo. | | `geos` | array | | `["US"]` | Country code (US, GB, DE), region (US-CA, GB-SCT) or US metro (US-NY-501). Leave a line empty or write WORLDWIDE for worldwide. Every search term is scraped for every geo. | | `timeRange` | string | | | Preset period. Use Custom time range below for exact dates. | | `customTimeRange` | string | | | Optional, overrides the preset. YYYY-MM-DD YYYY-MM-DD (e.g. 2024-01-01 2024-12-31) or hourly YYYY-MM-DDTHH YYYY-MM-DDTHH within the last 7 days (UTC). | | `category` | ['integer', 'string'] | | `0` | Google Trends category ID to narrow ambiguous terms (0 = all categories). A number or a string id (e.g. "71", as in apify/google-trends-scraper) both work. Common: 3 Arts & Entertainment, 5 Computers & Electronics, 7 Finance, 18 Shopping, 20 Sports, 44 Beauty & Fitness, 45 Health, 47 Autos & Vehicles, 66 Pets & Animals, 67 Travel, 71 Food & Drink, 958 Jobs & Education (full list in the README). | | `property` | string | | `"web"` | Which Google search product the interest comes from. | | `includeInterestOverTime` | boolean | | `true` | Timeline of search interest (0-100). | | `includeInterestByRegion` | boolean | | `true` | Interest per country / subregion / metro / city. When comparing several terms, values are each term's share (%) of the compared searches in that region, as on the Google Trends website. | | `regionResolution` | string | | `"auto"` | Granularity of interest by region. Falls back to Google's default if the resolution isn't available for the geo. | | `includeLowSearchVolumeRegions` | boolean | | `false` | Also return regions with too little data (value 0). | | `maxRegions` | integer | | `250` | Keep only the top N regions by interest. | | `includeRelatedQueries` | boolean | | `true` | Top and rising related searches (rising includes Breakout terms). | | `includeRelatedTopics` | boolean | | `false` | Off by default. Top and rising related topics. Google returns empty related topics to regular automated sessions, so when enabled this option requests them through Google Trends' embeddable-widget endpoint, sending a Referer header from a pool of public websites. Enable it only if this method is acceptable for your use case. Adds 2 requests per term; if topics can't be retrieved, the term is still returned with its other data. | | `maxRelatedItems` | integer | | `25` | Maximum rows per top / rising list. | | `trendingGeos` | array | | | Get the current Trending Now / daily trending searches for these countries (e.g. US, GB, IN, or a region like US-CA). Works with or without search terms. | | `trendingHours` | string | | `"24"` | Trends that started within this window. | | `trendingCategories` | array | | | Optional filter. Empty = all categories. | | `trendingActiveOnly` | boolean | | `false` | Skip trends that have already ended. | | `maxTrendingPerGeo` | integer | | `25` | Google lists up to ~500 trends per day for big countries; ranked by relevance. | | `includeTrendingNews` | boolean | | `true` | Attach up to 3 news articles (title, URL, source, time, image) that Google links to each trending search. One extra request per 50 trends. | | `outputFormat` | string | | `"flat"` | Flat: every timeline point, region, related query and topic is its own row with a type column. Per term: one row per search term + geo with arrays inside. Price is the same - you pay per term, not per row. | | `advancedQueries` | array | | | Optional. Fine-grained list of queries, each with its own geo / time range / category / property, e.g. [{"terms": "nike, adidas", "geo": "DE", "timeRange": "today 5-y", "category": 0, "property": "youtube"}]. Missing fields use the values above. | | `language` | string | | `"en-US"` | Language of region and topic names, e.g. en-US, de, fr. | | `timezoneOffsetMinutes` | integer | | `0` | Google's tz parameter (minutes behind UTC, e.g. 300 = US Eastern standard time). Default 0 = UTC dates. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Defaults to Apify datacenter proxy (cheapest) with automatic residential fallback when Google blocks it. Choose the RESIDENTIAL group to always use residential IPs. | | `residentialFallback` | boolean | | `true` | When a request is rate-limited (HTTP 429) on datacenter IPs, retry it on a residential IP. Recommended - this is what keeps the success rate above 99%. | | `maxConcurrency` | integer | | `5` | Queries processed in parallel. | | `maxRetries` | integer | | `8` | Each attempt uses a fresh session (new IP + new cookie) with exponential backoff. | | `geo` | string | | | Country code as a single string (e.g. US). Empty = worldwide. Used when Geo list is empty. Same as geo in apify/google-trends-scraper. | | `isMultiple` | boolean | | `true` | Same as isMultiple in apify/google-trends-scraper. On (default): commas in a searchTerms line compare up to 5 terms (Google's limit). Off: each line is one search term, commas included. | | `maxItems` | integer | | `0` | Maximum number of term×geo queries to run. 0 = no limit. | | `startUrls` | array | | | Paste Google Trends explore URLs; each is turned into a query (q, geo, date, cat). Also accepts apify/google-trends-scraper's format: [{"url": "…"}] or [{"requestsFromUrl": "…"}]. | | `viewedFrom` | string | | | Same as viewedFrom in apify/google-trends-scraper: 2-letter country for the proxy (e.g. us). Optional. | | `spreadsheetId` | string | | | Same as spreadsheetId in apify/google-trends-scraper: a public Google Sheet (Anyone with the link). Terms are read from the first column; row 1 is the header. Added to Search terms. | | `maxRequestRetries` | integer | | | Same as maxRequestRetries in apify/google-trends-scraper. Used as Max retries when that is not set. | | `pageLoadTimeoutSecs` | integer | | | Accepted so apify/google-trends-scraper inputs work unchanged. Not needed here: we don't load full browser pages per term. | | `skipDebugScreen` | boolean | | | Accepted so apify/google-trends-scraper inputs work unchanged. We never save page snapshots. | | `dataforseoFallback` | boolean | | `true` | If the browser scrape fails after retries, fetch interest-over-time from DataForSEO's Google Trends API (~$0.011 per call on the Actor owner's account; you are not charged extra beyond the normal term-result event). Related queries/regions are not included in the fallback. | ## Example input ```json { "searchTerms": [ "coffee", "tea, matcha" ], "geos": [ "US" ], "timeRange": "today 12-m", "category": 0, "property": "web", "includeInterestOverTime": true, "includeInterestByRegion": true, "regionResolution": "auto", "includeLowSearchVolumeRegions": false, "maxRegions": 250, "includeRelatedQueries": true, "includeRelatedTopics": false, "maxRelatedItems": 25, "trendingGeos": [ "US" ], "trendingHours": "24", "trendingActiveOnly": false, "maxTrendingPerGeo": 10, "includeTrendingNews": true, "outputFormat": "flat", "language": "en-US", "timezoneOffsetMinutes": 0, "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": true, "maxConcurrency": 5, "maxRetries": 8 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: interest_over_time, interest_by_region, related_query, related_topic, trending_now, term (per-term format) or status (no data / error, free) | | `searchTerm` | string | Search term (or trending search) | | `comparedWith` | array | Other terms in the same comparison (values share one 0-100 scale) | | `geo` | string | Geo code (WORLDWIDE for worldwide) | | `timeRange` | string | Requested time range | | `period` | string | Resolved date range from Google | | `category` | integer | Category ID | | `property` | string | web, images, news, youtube or shopping | | `date` | string | Timeline point (YYYY-MM-DD, or ISO datetime for hourly data, UTC) | | `timestamp` | integer | Unix timestamp of the timeline point | | `formattedTime` | string | Google's label for the point | | `value` | integer | Interest 0-100 (region rows of comparisons: share %); related rows: relative value or % growth | | `formattedValue` | string | Google's formatted value (e.g. +250%, Breakout) | | `hasData` | boolean | False when Google has too little data | | `isPartial` | boolean | Last timeline point is still being collected | | `resolution` | string | Timeline (WEEK, DAY, HOUR...) or region resolution | | `rank` | integer | Position in its list | | `geoCode` | string | Region code (e.g. US-CA, DMA 807) | | `geoName` | string | Region name | | `valueType` | string | interest (single term) or share (comparison) | | `lat` | number | City latitude | | `lng` | number | City longitude | | `rankType` | string | top or rising | | `query` | string | Related query | | `topicId` | string | Knowledge Graph topic ID | | `topicTitle` | string | Topic name | | `topicType` | string | Topic type | | `isBreakout` | boolean | Rising more than 5000% | | `link` | string | Google Trends link for the related item | | `searchVolume` | integer | Trending now: approximate searches | | `searchVolumeFormatted` | string | e.g. 200K+ | | `increasePercentage` | integer | Trending now: growth % | | `startedAt` | string | Trend start (UTC) | | `endedAt` | string | Trend end (UTC), null while active | | `isActive` | boolean | Trend still active | | `categories` | array | Trending categories | | `trendBreakdown` | array | Queries grouped into this trend | | `newsArticles` | array | News headlines {title, url, source, picture} | | `status` | string | ok, partial, no_data or error | | `averageInterest` | number | Per-term format: mean interest | | `peakInterest` | integer | Per-term: max interest | | `peakDate` | string | Per-term: date of the peak | | `latestInterest` | integer | Per-term: last value | | `interestOverTime` | array | Per-term: timeline | | `interestByRegion` | array | Per-term: regions | | `relatedQueriesTop` | array | Per-term | | `relatedQueriesRising` | array | Per-term | | `relatedTopicsTop` | array | Per-term | | `relatedTopicsRising` | array | Per-term | | `error` | string | Error message (rows with errors are free) | | `exploreUrl` | string | Open the same query on trends.google.com | | `scrapedAt` | string | UTC timestamp | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Home Depot & Lowe's Scraper - Price & Store Stock > Scrape Home Depot and Lowe's products by keyword, category URL, product URL or item ID: price, was-price, UPC, model, SKU, local store price, in-store stock quantity, aisle/bay, pickup/delivery, specs, images, ratings and optional reviews. - Category: E-commerce & reviews - Price: $4 per 1,000 × product with details, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/home-depot-lowes-scraper - Human page: https://wrenfielddata.com/tools/home-depot-lowes-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~home-depot-lowes-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/home-depot-lowes-scraper (appears as `wrenfield-data--home-depot-lowes-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~home-depot-lowes-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"retailer": "both", "startUrls": [{"url": "https://www.homedepot.com/b/Tools-Hand-Tools-Hammers-Claw-Hammers/N-5yc1vZc98p"}], "productIds": ["hd:205594063", "lowes:1000379005"], "maxItems": 4, "maxItemsPerQuery": 24, "includeDetails": true, "includeReviews": false, "maxReviewsPerProduct": 20, "reviewsSort": "relevance", "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "useBrowserSessions": true, "maxConcurrency": 8, "maxRetries": 8}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `searchKeywords` | array | | | Keywords to search, one per line (e.g. cordless drill, claw hammer). Each keyword is searched on the retailer(s) chosen below and returns up to Max products per search/category products from each. | | `retailer` | string | | `"both"` | Where to search the keywords. URLs and prefixed item IDs always go to the retailer they belong to. | | `startUrls` | array | | | homedepot.com category pages (/b/...N-5yc1v...), search pages (/s/drill) or product pages (/p/...); lowes.com category pages (/pl/...), search pages (/search?searchTerm=...) or product pages (/pd/...). | | `productIds` | array | | | One per line: product URLs, or IDs with a prefix - hd:205594063 (Home Depot internet # / OMSID), lowes:1000379005 (Lowe's product ID from the URL) or lowes:921987 (Lowe's item #). Bare 9-digit numbers are treated as Home Depot IDs, other numbers as Lowe's. | | `maxItems` | integer | | `50` | Maximum number of product rows for the whole run (reviews are not counted). Duplicates across inputs are skipped. | | `maxItemsPerQuery` | integer | | `24` | How many products to take from each keyword (per retailer) or category URL. Both sites show 24 products per page; Home Depot allows paging to about 700 products per search. | | `includeDetails` | boolean | | `true` | Fetch each product's detail data: UPC, model, specifications, description, all images, categories, fulfillment and aisle/bay. Turn off for a faster listing-only scrape (title, price, rating, stock from the search grid). | | `zipCode` | string | | | Optional 5-digit US ZIP. The nearest Home Depot and Lowe's stores are used for local price, in-store stock quantity and aisle/bay. Leave empty for online (national) prices. | | `homeDepotStoreId` | string | | | Optional Home Depot store number (e.g. 121), overrides the ZIP lookup. Shown on homedepot.com store pages. | | `lowesStoreId` | string | | | Optional Lowe's store number (e.g. 1807), overrides the ZIP lookup. Recommended for Lowe's - faster and more reliable than a ZIP search. | | `includeReviews` | boolean | | `false` | Also output customer reviews for every product (one row per review, type = review). | | `maxReviewsPerProduct` | integer | | `20` | Reviews are fetched 10 per request. | | `reviewsSort` | string | | `"relevance"` | Lowe's supports only most relevant and newest; other options fall back to most relevant there. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Defaults to Apify Proxy: datacenter IPs where they work (Lowe's product data) and US residential IPs with real-browser sessions where they are required (Home Depot, Lowe's search pages). | | `residentialFallback` | boolean | | `true` | Use US residential IPs when datacenter IPs are blocked. Required for Home Depot. | | `useBrowserSessions` | boolean | | `true` | Open a real browser once per proxy session to pass the sites' bot protection, then reuse its cookies for fast API requests. Turning this off makes Home Depot and Lowe's search pages fail. | | `maxConcurrency` | integer | | `8` | Parallel requests. | | `maxRetries` | integer | | `8` | Blocked requests are retried with a new IP and session. | ## Example input ```json { "retailer": "both", "startUrls": [ { "url": "https://www.homedepot.com/b/Tools-Hand-Tools-Hammers-Claw-Hammers/N-5yc1vZc98p" } ], "productIds": [ "hd:205594063", "lowes:1000379005" ], "maxItems": 4, "maxItemsPerQuery": 24, "includeDetails": true, "includeReviews": false, "maxReviewsPerProduct": 20, "reviewsSort": "relevance", "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": true, "useBrowserSessions": true, "maxConcurrency": 8, "maxRetries": 8 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: product, review or error (error rows are free) | | `retailer` | string | homedepot or lowes | | `itemId` | string | Home Depot internet # / OMSID, or Lowe's product ID | | `modelNumber` | string | Manufacturer model number | | `sku` | string | Home Depot store SKU / Lowe's item # | | `upc` | string | UPC / barcode | | `title` | string | Product title | | `brand` | string | Brand | | `image` | string | Main image URL | | `price` | number | Current price (local store price when a store/ZIP is set) | | `wasPrice` | number | Previous / strike-through price | | `currency` | string | Currency | | `unitPrice` | number/string | Price per unit when shown | | `unitOfMeasure` | string | Unit of measure (Home Depot) | | `savingsAmount` | number | Savings vs was-price | | `savingsPercent` | number | Savings percent | | `promotion` | object | Active promotion (Home Depot) | | `specialBuy` | boolean | Special Buy / deal of the day (Home Depot) | | `clearancePrice` | number | In-store clearance price (Home Depot) | | `priceType` | string | STORE or NETWORK price (Lowe's) | | `rating` | number | Average rating 1-5 | | `reviewCount` | integer | Number of reviews | | `availability` | object | online / shipToHome / delivery / pickup / inStore flags, online quantity, delivery dates | | `storeStockQuantity` | integer | Units on hand at the selected store | | `storeLimitedStock` | boolean | Limited stock at the store (Home Depot) | | `aisle` | string | Aisle at the selected store | | `bay` | string | Bay at the selected store | | `store` | object | Selected store (id, name, address, city, state, zip) | | `categories` | array | Category breadcrumb | | `images` | array | All image URLs | | `specifications` | array | Specifications {group, name, value} | | `description` | string | Description | | `bullets` | array | Feature bullets | | `highlights` | array | Highlights (Home Depot) | | `socialProof` | string | Social proof message, e.g. "100+ bought last week" (Lowe's) | | `isSponsored` | boolean | Sponsored listing | | `url` | string | Product URL | | `detailsScraped` | boolean | false = listing-only row | | `source` | object | Which input produced the row (search, page, position) | | `productTitle` | string | Reviewed product title (review rows) | | `reviewId` | string | Review ID | | `reviewTitle` | string | Review title | | `text` | string | Review text | | `date` | string | Review date | | `author` | string | Reviewer nickname | | `recommended` | boolean | Would recommend | | `helpfulVotes` | integer | Helpful votes | | `verifiedPurchase` | boolean | Verified purchaser | | `incentivized` | boolean | Incentivized review | | `photos` | array | Review photo URLs | | `error` | string | Error message (error rows) | | `scrapedAt` | string | Scrape time (UTC) | | `isBundle` | boolean | Home Depot bundle ("sets") product | | `detailsError` | string | Why product-page details could not be loaded (listing-only row) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Bulk Keyword Difficulty Checker - KD & Search Intent > Check SEO keyword difficulty (KD 0-100) and search intent for thousands of keywords at once, in 90+ countries and languages. Find easy keywords to rank for. Up to 1,000 keywords per request, $5 per 1,000 keywords. - Category: Keyword data - Price: $5 per 1,000 × keyword difficulty, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/keyword-difficulty-checker - Human page: https://wrenfielddata.com/tools/keyword-difficulty-checker/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~keyword-difficulty-checker/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/keyword-difficulty-checker (appears as `wrenfield-data--keyword-difficulty-checker`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~keyword-difficulty-checker/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"keywords": ["keyword research", "seo tools", "how to start a blog", "best running shoes for flat feet", "running shoes"], "location": "United States", "language": "English", "includeSearchIntent": true}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `keywords` | array | yes | `["keyword research", "seo tools", "how to start a blog", "best running shoes for flat feet", "running shoes"]` | Keywords to check, one per line (thousands are fine; they're sent in batches of 1,000). Keywords are trimmed, lower-cased and de-duplicated. | | `location` | string | | `"United States"` | Country to measure difficulty in: name (United States), 2-letter code (DE) or location code (2840). | | `language` | string | | | Language name or code (English, es). Leave empty for the main language of the country. | | `includeSearchIntent` | boolean | | `true` | Also classify each keyword as informational, navigational, commercial or transactional (small extra charge per keyword, see Pricing). | ## Example input ```json { "keywords": [ "keyword research", "seo tools", "how to start a blog", "best running shoes for flat feet", "running shoes" ], "location": "United States", "language": "English", "includeSearchIntent": true } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `keyword` | string | Keyword (normalized, lower-case) | | `keyword_difficulty` | integer | SEO keyword difficulty, 0-100 (higher = harder to rank). null when the keyword is not in the database | | `difficulty_level` | string | Difficulty band: very easy, easy, possible, difficult, hard or very hard | | `search_intent` | string | Main search intent: informational, navigational, commercial or transactional | | `search_intent_probability` | number | Confidence of the main intent, 0-1 | | `secondary_intents` | array | Other likely intents | | `location` | string | Country the data is for, e.g. "United States" | | `language` | string | Language name, e.g. "English" | | `found` | boolean | True when a difficulty score was found (only these rows are charged) | | `note` | string | Explanation when no score was found | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Keyword Gap & Opportunity Report - Competitor Keyword Gap > Keywords up to 3 competitors rank for on Google and your client's domain doesn't: volume, difficulty, intent, competing URLs and why each was picked. Top 20 re-checked on the live Google top 10. CSV-ready dataset + HTML report. One flat price per report. - Category: Keyword data - Price: $9 per keyword gap report, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/keyword-gap-report - Human page: https://wrenfielddata.com/tools/keyword-gap-report/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~keyword-gap-report/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/keyword-gap-report (appears as `wrenfield-data--keyword-gap-report`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~keyword-gap-report/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"clientDomain": "helpscout.com", "competitors": ["zendesk.com", "freshworks.com", "intercom.com"], "location": "United States", "language": "English"}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `clientDomain` | string | yes | `"helpscout.com"` | The site you want new keywords for, e.g. helpscout.com. https://, www. and paths are removed. | | `competitors` | array | yes | `["zendesk.com", "freshworks.com", "intercom.com"]` | 1 to 3 competitors that rank where you want to rank, e.g. zendesk.com. Pick real search competitors (the sites that outrank you), not only business rivals. | | `location` | string | | `"United States"` | Country of the Google results: name (United States), 2-letter code (GB) or location code (2840). | | `language` | string | | | Language name or code (English, de). Empty = main language of the country. | | `excludeTerms` | array | | | Drop keywords that contain any of these words or phrases, e.g. jobs, free download, your own brand. Case-insensitive. | | `excludeCompetitorBrands` | boolean | | `true` | Drop keywords containing a competitor's name taken from its domain (for example zendesk from zendesk.com). Usually what you want: you can't win "zendesk pricing". | | `topicTerms` | array | | | Keep only keywords containing at least one of these words, e.g. help desk, support, ticket. Useful when competitors are broad sites. | | `minSearchVolume` | integer | | `30` | Skip keywords with fewer Google searches a month. 0 also keeps keywords whose volume is unavailable. | | `maxKeywordDifficulty` | integer | | `100` | Skip keywords harder than this (0-100). 100 = no limit. | | `maxCompetitorPosition` | integer | | `20` | Only count a competitor ranking at this position or better. 20 = first two pages (recommended); 10 = page one only. | | `includeNavigational` | boolean | | `false` | Keep brand and login searches ("x login", "x support phone"). Off by default: they are rarely winnable. | | `includeCompetitorSubdomains` | boolean | | `false` | Also count rankings on competitor subdomains. Off by default, because hosted subdomains (for example customer help centers on *.zendesk.com) are not the competitor's own content. | | `candidatesPerCompetitor` | integer | | `100` | How many gap keywords to pull per competitor (highest competitor traffic first), before merging duplicates. Max 100, so a report has up to 300. | | `liveSerpChecks` | integer | | `20` | How many of the best candidates to re-check on the live Google top 10 (confirms the gap is still open today). Max 20. 0 = database only. | | `preparedBy` | string | | | Your name or agency, shown on the HTML report. No Wrenfield branding appears in the report. | | `maxSpendUsd` | integer | | | Optional. The run stops before collecting anything, and charges nothing, if the report price is above this. Same effect as "Maximum cost per run" in Run options. | ## Example input ```json { "clientDomain": "helpscout.com", "competitors": [ "zendesk.com", "freshworks.com", "intercom.com" ], "location": "United States", "language": "English" } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `rank` | integer | Position in this report (live-confirmed gaps first, then by opportunity score) | | `keyword` | string | Keyword at least one competitor ranks for on Google and the client domain does not | | `opportunity_score` | number | 0-100: 25% demand, 20% ease (100 - KD), 20% topic fit, 15% competitor overlap, 10% intent, 10% best competitor position | | `search_volume` | integer | Average monthly Google searches (Google Ads data). null = unavailable | | `search_volume_status` | string | measured, zero (Google reports no searches) or unavailable (no value; not the same as zero) | | `search_volume_month` | string | Latest month covered by the volume data (YYYY-MM) | | `cpc_usd` | number | Average Google Ads cost per click, USD | | `competition_level` | string | Google Ads competition: LOW, MEDIUM, HIGH | | `topic_fit` | number | 0-1: share of the keyword's words found on the client's homepage (title, headings, links). null = site could not be read | | `topic_fit_status` | string | measured or unavailable | | `keyword_difficulty` | integer | Keyword difficulty 0-100. null = unavailable | | `keyword_difficulty_status` | string | measured or unavailable | | `search_intent` | string | Main intent: informational, commercial, transactional, navigational | | `search_intent_status` | string | measured or unavailable | | `competitors_ranking` | integer | How many of the competitors rank for the keyword (database) | | `competitor_positions` | string | Each ranking competitor with its Google position, e.g. 'zendesk.com #4; intercom.com #7' | | `best_competitor` | string | Competitor with the best position | | `best_competitor_position` | integer | That competitor's Google position (database) | | `best_competitor_url` | string | The competitor page that ranks | | `competing_urls` | string | All ranking competitor URLs, separated with ' \| ' | | `competitor_traffic_estimate` | integer | Modeled monthly visits competitors get from the keyword (provider estimate) | | `serp_features_labs` | string | SERP features seen in the database snapshot (AI Overview, People Also Ask, ...) | | `selection_reasons` | string | Why the keyword was picked, in plain language, separated with '; ' | | `live_checked` | boolean | Whether the keyword was re-checked on the live Google top 10 | | `live_verdict` | string | open gap, client already ranks, competitors not in top 10 now, check failed, or not checked | | `client_position_live` | integer | Client's live Google position if in the top 10, else null | | `competitor_positions_live` | string | Competitors in the live top 10 with positions | | `top10_domains_live` | string | Domains in the live top 10, in order | | `serp_features_live` | string | SERP features on the live page | | `ai_overview_live` | boolean | An AI Overview was shown on the live page | | `ai_overview_cites_client` | boolean | The live AI Overview cites the client domain (null if no AI Overview) | | `labs_serp_observed_at` | string | When the provider last observed the Google results behind the database rankings (observation time) | | `labs_retrieved_at` | string | When this run queried the database (retrieval time) | | `serp_checked_at` | string | When the live Google results were observed | | `serp_retrieved_at` | string | When this run requested the live check | | `client_domain` | string | Client domain | | `competitors` | string | Competitors used | | `location` | string | Country | | `language` | string | Language | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Keyword Research Tool - Ideas, Volume, KD, Intent & SERP > Keyword ideas from any seed with search volume, CPC, keyword difficulty (KD), search intent and SERP features in one row. Ahrefs Keywords Explorer & Semrush Keyword Magic alternative. 90+ countries, up to 10,000 keywords per run, $3 per 1,000 keywords. - Category: Keyword data - Price: $3 per 1,000 × keyword result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/keyword-research-tool - Human page: https://wrenfielddata.com/tools/keyword-research-tool/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~keyword-research-tool/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/keyword-research-tool (appears as `wrenfield-data--keyword-research-tool`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~keyword-research-tool/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"seedKeywords": ["running shoes"], "mode": "ideas", "location": "United States", "language": "English", "maxKeywords": 50}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `seedKeywords` | array | yes | `["running shoes"]` | One or more topics to research, e.g. running shoes. "Ideas" mode accepts up to 200 seeds at once; "suggestions" and "related" use up to 20. | | `mode` | string | | `"ideas"` | How keywords are found. ideas = topically related keywords, suggestions = phrase-match long tail containing your seed, related = Google related-searches graph. | | `location` | string | | `"United States"` | Country: name (United States), 2-letter code (DE) or location code (2840). | | `language` | string | | | Language name or code (English, es). Leave empty for the main language of the country. | | `maxKeywords` | integer | | `100` | Maximum keyword rows per run, including the seed keywords. The default of 100 finishes in a few seconds. | | `sortBy` | string | | `"relevance"` | Which keywords come first (and are kept when you hit Max keywords). | | `minSearchVolume` | integer | | | Only keywords with at least this many monthly searches. | | `maxKeywordDifficulty` | integer | | | Only keywords with KD at or below this value (0-100). Use 30 to find easy wins. | | `searchIntents` | array | | | Only keywords with these main intents. Leave empty for all. | | `includeSeedKeywords` | boolean | | `true` | Add a row with full metrics for each seed keyword (one extra data request). | | `includeMonthlySearches` | boolean | | `false` | Add the last 12 months of search volume to each row. | | `relatedDepth` | integer | | `2` | Only for "related" mode: how many levels of related searches to follow (more = more keywords). | ## Example input ```json { "seedKeywords": [ "running shoes" ], "mode": "ideas", "location": "United States", "language": "English", "maxKeywords": 50 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `keyword` | string | Keyword (lower-case) | | `type` | string | seed = one of your seed keywords; idea / suggestion / related = a keyword found from the seeds | | `seed_keyword` | string | Seed keyword the row came from (null in ideas mode with several seeds) | | `search_volume` | integer | Average monthly Google searches (last 12 months) | | `cpc` | number | Average Google Ads cost per click (USD) | | `competition` | string | Google Ads competition level: LOW, MEDIUM or HIGH | | `competition_index` | integer | Google Ads competition, 0-100 | | `low_top_of_page_bid` | number | Top-of-page bid, low range (USD) | | `high_top_of_page_bid` | number | Top-of-page bid, high range (USD) | | `keyword_difficulty` | integer | SEO keyword difficulty 0-100 (higher = harder to reach the top 10) | | `difficulty_level` | string | very easy (0-14), easy (15-29), possible (30-49), difficult (50-69), hard (70-84), very hard (85-100) | | `search_intent` | string | Main search intent: informational, navigational, commercial or transactional | | `secondary_intents` | array | Other likely intents | | `serp_features` | array | Google result types on the first page, e.g. ai_overview, people_also_ask, local_pack, popular_products, video | | `has_ai_overview` | boolean | Google shows an AI Overview for this keyword | | `has_featured_snippet` | boolean | Google shows a featured snippet | | `has_people_also_ask` | boolean | Google shows People Also Ask questions | | `has_local_pack` | boolean | Google shows a local map pack | | `has_shopping_results` | boolean | Google shows shopping / product results | | `has_video` | boolean | Google shows video results | | `has_images` | boolean | Google shows image results | | `has_ads` | boolean | Google showed ads when the results page was last checked | | `serp_results_count` | integer | Number of results Google reports for the keyword | | `word_count` | integer | Number of words in the keyword | | `avg_backlinks_top10` | integer | Average backlinks of the pages ranking in the top 10 | | `avg_referring_domains_top10` | integer | Average referring domains of the pages ranking in the top 10 | | `search_volume_trend` | object | Search volume change in %: monthly, quarterly and yearly | | `monthly_searches` | array | Last 12 months of search volume (only with includeMonthlySearches) | | `related_depth` | integer | Related mode only: how many related-search hops from the seed | | `location` | string | Country the data is for, e.g. "United States" | | `language` | string | Language name, e.g. "English" | | `data_updated_at` | string | When the keyword metrics were last updated (ISO 8601, UTC) | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Keyword Search Volume - Google Keyword Planner, No Ads Account > Bulk keyword search volume checker and search volume API with real Google Keyword Planner data: monthly searches, CPC, competition, 12-month trends and keyword ideas for any country, city or language. No Google Ads account. $4 per 1,000 keywords; keywords with no data are free. - Category: Keyword data - Price: $4 per 1,000 × keyword result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/keyword-search-volume - Human page: https://wrenfielddata.com/tools/keyword-search-volume/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~keyword-search-volume/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/keyword-search-volume (appears as `wrenfield-data--keyword-search-volume`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~keyword-search-volume/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"keywords": ["keyword research", "seo tools", "ai seo", "content marketing", "running shoes"], "location": "United States", "language": "English", "mode": "search_volume", "includeMonthlySearches": true}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `keywords` | array | yes | `["keyword research", "seo tools", "ai seo", "content marketing", "running shoes"]` | Keywords to look up, one per line (thousands are fine). Used as seed keywords when you ask for keyword ideas. Keywords are trimmed, lower-cased and de-duplicated; match-type symbols like [exact] or "phrase" and characters Google Ads does not accept are removed. Max 80 characters and 10 words per keyword. Large lists are split into batches of 1,000 automatically. Keywords without data are free. | | `mode` | string | | `"search_volume"` | Search volume: metrics for exactly the keywords you enter. Keyword ideas: new related keywords (with the same metrics) generated from your seed keywords, like Google Keyword Planner's 'Discover new keywords'. Both: metrics for your keywords plus ideas. | | `location` | string | | `"United States"` | Country (United States, US, 2840), state or region (California, Bavaria,Germany), city (London, Austin, TX, New York,New York,United States) or Worldwide. Plain names are matched to the Google Ads location list; if a name is ambiguous the run note says which place was used. State, city and worldwide lookups use live Google Ads data. | | `language` | string | | | Language name (English, Spanish) or code (en, es). Leave empty to use the main language of the location (e.g. German for Germany). | | `includeMonthlySearches` | boolean | | `true` | Add the month-by-month search volume (last 12 months by default, or the date range below) to every result. | | `dateFrom` | string | | | Optional start month of the monthly history, format YYYY-MM (e.g. 2024-01). Up to 4 years back. Leave empty for the last 12 months. | | `dateTo` | string | | | Optional end month of the monthly history, format YYYY-MM. Google publishes data for the previous month only, so later months are capped automatically. | | `ideasMethod` | string | | `"keyword_ideas"` | Only used for keyword ideas. With the Google Ads API data source, ideas come from Keyword Planner's 'Discover new keywords' (up to 20 seed keywords per request) and this setting is ignored. With the keyword database: Keyword Planner-style ideas = keywords about the same topic; Long-tail suggestions = phrases that contain your seed keyword; Related searches = Google's 'related searches' for your seed keyword. | | `maxIdeas` | integer | | `100` | Maximum number of keyword ideas to return in total per run. You only pay for ideas that are returned. | | `minSearchVolume` | integer | | `0` | Skip keyword ideas with a lower average monthly search volume (e.g. 100 to drop tiny long-tail phrases). 0 = keep all ideas that have data. | | `dataSource` | string | | `"google_ads"` | Google Ads API (default): queries Google Ads (Keyword Planner) live, up to 1,000 keywords per request, and returns a row for every keyword Google knows. Adds a small per-request fee (see Pricing). Keyword database: a database built from Google Ads data, refreshed monthly; no request fee, also returns keyword difficulty and search intent, country-level locations only. Auto: keyword database for country-level searches, Google Ads API for regions/cities or languages the database does not cover. | | `googleAdsMode` | string | | `"live"` | Only used when the Google Ads API is queried. Live (default): results in seconds. Queued: cheaper per-request fee, but results usually take a few minutes and can take longer at peak times; the run waits for them. If a queued run times out, run it again with the same input to collect the results without paying the request fee again. | | `queuedMaxWaitMinutes` | integer | | `120` | Queued mode only: how long the run waits for Google Ads results before stopping (it never waits past the run timeout). | ## Example input ```json { "keywords": [ "keyword research", "seo tools", "ai seo", "content marketing", "running shoes" ], "location": "United States", "language": "English", "mode": "search_volume", "includeMonthlySearches": true } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `keyword` | string | Keyword (normalized, lower-case) | | `type` | string | keyword = one of your input keywords; idea = a keyword idea generated from your seed keywords | | `seed_keyword` | string | Seed keyword(s) an idea was generated from | | `location` | string | Location name | | `location_code` | integer | Google Ads location code (e.g. 2840 = United States) | | `language` | string | | | `language_code` | string | | | `search_volume` | integer | Average monthly searches (last 12 months) | | `cpc` | number | Average cost per click in USD | | `competition` | string | Paid search competition level: LOW, MEDIUM or HIGH | | `competition_index` | integer | Paid search competition index, 0-100 | | `low_top_of_page_bid` | number | Top-of-page bid, low range (USD) | | `high_top_of_page_bid` | number | Top-of-page bid, high range (USD) | | `keyword_difficulty` | integer | SEO ranking difficulty 0-100 (keyword database only) | | `search_intent` | string | informational, navigational, commercial or transactional (keyword database only) | | `trend` | object | Search volume change in % of the latest month vs. previous month / 3 months / 12 months earlier | | `search_volume_avg_in_range` | integer | Average monthly searches within the requested date range (only when a date range is set) | | `monthly_searches` | array | Monthly search volume history, oldest to newest: {date, year, month, search_volume} | | `found` | boolean | true if search volume data was found (only these rows are charged) | | `spell` | string | Google's spelling correction, if the keyword looked misspelled | | `note` | string | Explanation when no data was found | | `source` | string | keyword_database, google_ads_live or google_ads_queued | | `data_updated_at` | string | When the keyword's metrics were last refreshed (keyword database) | | `scraped_at` | string | When this row was produced (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # People Also Ask Scraper - Google PAA & AI Overviews > Get Google People Also Ask questions (up to 4 levels deep), related searches and optional AI Overview text for any keyword, country, city and language. Content ideas, FAQ schema and AEO research in bulk. No proxies or browser needed. - Category: Keyword data - Price: $5.50 per 1,000 × keyword search, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/people-also-ask-scraper - Human page: https://wrenfielddata.com/tools/people-also-ask-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~people-also-ask-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/people-also-ask-scraper (appears as `wrenfield-data--people-also-ask-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~people-also-ask-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"keywords": ["how to start a blog"], "location": "United States", "language": "English", "clickDepth": 2}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `keywords` | array | yes | `["how to start a blog"]` | Google searches to check, one per line. Each keyword is one Google search. | | `location` | string | | `"United States"` | Country name (United States), 2-letter code (GB), location code (2840) or a full Google location name for cities and regions (e.g. London,England,United Kingdom). | | `language` | string | | | Language name or code (English, fr). Leave empty for the main language of the country. | | `clickDepth` | integer | | `2` | How many levels of People Also Ask to open. 1 = the questions shown on the page (usually 4). 2-4 = also the follow-up questions Google reveals when a question is clicked (usually 8-20 questions in total). | | `includeRelatedSearches` | boolean | | `true` | Also save the "related searches" at the bottom of the results page (free). | | `includeAiOverview` | boolean | | `false` | Also save Google's AI Overview text and its cited sources when Google shows one (extra charge per keyword, see Pricing). | | `device` | string | | `"desktop"` | Desktop or mobile Google results. | ## Example input ```json { "keywords": [ "how to start a blog" ], "location": "United States", "language": "English", "clickDepth": 2 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `keyword` | string | Keyword searched on Google | | `type` | string | Row type: question (People Also Ask), related_search or ai_overview | | `text` | string | The question, related search, or AI Overview text | | `position` | integer | Order on the results page (1 = first) | | `level` | integer | 1 = shown directly, 2 = revealed by clicking another question | | `parent_question` | string | Question that was clicked to reveal this one (level 2) | | `answer` | string | Answer snippet shown under the question, when available | | `answer_title` | string | Title of the page the answer comes from | | `answer_url` | string | URL of the page the answer comes from | | `answer_domain` | string | Domain of the page the answer comes from | | `ai_overview_references` | array | Sources cited by the AI Overview (ai_overview rows only) | | `location` | string | Country the data is for, e.g. "United States" | | `language` | string | Language name, e.g. "English" | | `device` | string | desktop or mobile | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Form D Scraper - SEC EDGAR Startup Funding Leads > Find startups and private companies that just raised money, from official SEC EDGAR Form D filings. Filter by date, state, industry, amount, exemption and keyword. Get issuer, address, phone, executives & directors, amount raised, investors, 506(b)/(c) and first-time-raise flag. - Category: Lead & company data - Price: $3 per 1,000 × filing result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/sec-form-d-scraper - Human page: https://wrenfielddata.com/tools/sec-form-d-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~sec-form-d-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/sec-form-d-scraper (appears as `wrenfield-data--sec-form-d-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~sec-form-d-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"dateFrom": "7 days", "excludePooledFunds": true, "filingType": "new", "includeIssuerHistory": true, "maxItems": 20}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `dateFrom` | string | | | Earliest SEC filing date (inclusive). An absolute date like 2026-09-01 or a relative one like 7 days. Defaults to 7 days before Filed to. Form D data is available from 2009-03-16. | | `dateTo` | string | | | Latest SEC filing date (inclusive). Leave empty for today. Results are returned newest first. | | `states` | array | | | Only filings whose issuer's principal place of business is in these US states (business address on the Form D). Leave empty for all states and countries. | | `industryGroups` | array | | | Form D industry groups (as selected by the issuer). Pick a whole sector (e.g. Technology (all)) or a specific group. Leave empty for all industries. | | `excludePooledFunds` | boolean | | `true` | About 60% of Form D filings are pooled investment funds (VC, PE, hedge and real-estate funds raising from LPs). Keep this on to get operating companies and startups only. Turn it off to include funds, e.g. to track new VC funds. | | `minOfferingAmount` | integer | | | Only offerings whose total offering amount is at least this. Offerings marked "Indefinite" pass this filter. | | `maxOfferingAmount` | integer | | | Only offerings whose total offering amount is at most this. Offerings marked "Indefinite" are excluded when this is set. | | `minAmountSold` | integer | | | Only offerings that have already raised at least this much (total amount sold). | | `keyword` | string | | | Full-text search across the Form D (issuer name, people, addresses...). Examples: Acme, software, "artificial intelligence" (quotes = exact phrase). | | `filingType` | string | | `"new"` | A new Form D is filed within 15 days after the first sale of a new offering. Amendments (D/A) update an existing offering, e.g. more money raised or the annual renewal. | | `exemptions` | array | | | Only filings claiming at least one of these exemptions. 506(b) is the classic private round; 506(c) allows general solicitation (accredited investors verified). | | `includeIssuerHistory` | boolean | | `true` | Looks up the issuer on SEC EDGAR to add EIN, SIC code, how many Form Ds it filed before, the date of its first Form D, and isFirstFormD (a first-time raise). One extra SEC request per company. | | `maxItems` | integer | | `100` | Stop after saving this many filings. You are only charged for filings saved to the dataset. | ## Example input ```json { "dateFrom": "7 days", "excludePooledFunds": true, "filingType": "new", "includeIssuerHistory": true, "maxItems": 20 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `issuerName` | string | Issuer (company) name | | `cik` | string | SEC Central Index Key | | `formType` | string | D (new) or D/A (amendment) | | `isAmendment` | boolean | | | `filingDate` | string | Date filed with the SEC (YYYY-MM-DD) | | `accessionNumber` | string | SEC accession number | | `previousAccessionNumber` | string | For amendments: the filing being amended | | `filingUrl` | string | EDGAR filing index page | | `formUrl` | string | Human-readable Form D on sec.gov | | `xmlUrl` | string | Raw primary_doc.xml | | `industrySector` | string | Form D sector (Technology, Health Care, Real Estate...) | | `industryGroup` | string | Form D industry group | | `investmentFundType` | string | For pooled funds: VC, PE, hedge, other | | `isPooledInvestmentFund` | boolean | | | `isLikelySpv` | boolean | Name suggests an SPV / series LLC | | `entityType` | string | Corporation, LLC, LP... | | `stateOfIncorporation` | string | Jurisdiction of incorporation | | `yearOfIncorporation` | number | Year of incorporation (only reported if within 5 years) | | `incorporatedWithinFiveYears` | boolean | | | `yearOfIncorporationText` | string | | | `street1` | string | | | `street2` | string | | | `city` | string | | | `state` | string | Business address state/country code | | `stateName` | string | | | `zipCode` | string | | | `fullAddress` | string | | | `phone` | string | Issuer phone | | `previousNames` | array | | | `totalOfferingAmount` | number | Total offering amount in USD (null if indefinite) | | `isOfferingAmountIndefinite` | boolean | | | `totalAmountSold` | number | Amount already sold, USD | | `totalRemaining` | number | Amount remaining, USD | | `percentSold` | number | | | `minimumInvestment` | number | Minimum investment accepted, USD | | `numberOfInvestors` | number | Investors who already invested | | `hasNonAccreditedInvestors` | boolean | | | `numberOfNonAccreditedInvestors` | number | | | `exemptions` | array | Exemptions claimed | | `exemptionsText` | string | | | `exemptionCodes` | array | Raw Form D exemption codes | | `is506b` | boolean | | | `is506c` | boolean | | | `dateOfFirstSale` | string | | | `firstSaleYetToOccur` | boolean | | | `offeringMoreThanOneYear` | boolean | | | `securitiesTypes` | array | | | `securitiesTypesText` | string | | | `isBusinessCombination` | boolean | | | `revenueRange` | string | | | `aggregateNetAssetValueRange` | string | | | `salesCommissions` | number | | | `findersFees` | number | | | `grossProceedsUsedForInsiders` | number | Proceeds paid to executives, directors, promoters | | `salesCompensationRecipients` | string | Broker-dealers / placement agents | | `relatedPersons` | array | Executives, directors and promoters with roles | | `relatedPersonsText` | string | | | `executives` | string | | | `directors` | string | | | `promoters` | string | | | `contact1Name` | string | | | `contact1Roles` | string | | | `contact2Name` | string | | | `contact2Roles` | string | | | `contact3Name` | string | | | `contact3Roles` | string | | | `signerName` | string | | | `signerTitle` | string | | | `signatureDate` | string | | | `coIssuers` | array | | | `ein` | string | IRS Employer ID (issuer history) | | `website` | string | | | `sic` | string | | | `sicDescription` | string | | | `formDFilingsBefore` | number | Earlier new Form Ds by this issuer | | `firstFormDDate` | string | | | `isFirstFormD` | boolean | First-ever Form D (first-time raise) | | `totalFormDFilings` | number | | | `scrapedAt` | string | | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # SEO Agency Report - White-Label SEO & AI Visibility Audit > One domain in, one client-ready SEO report out: rankings, top 100 keywords, quick wins, competitors, domain authority, backlinks, live SERPs, PageSpeed and ChatGPT / Google AI Mode visibility. White-label HTML + PDF and JSON. $2.49 per report. - Category: Rank tracking & site SEO - Price: $2.49 per seo report, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/seo-agency-report - Human page: https://wrenfielddata.com/tools/seo-agency-report/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~seo-agency-report/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/seo-agency-report (appears as `wrenfield-data--seo-agency-report`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~seo-agency-report/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"domain": "backlinko.com", "location": "United States", "agencyName": "Northwind Digital", "accentColor": "#0F766E"}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `domain` | string | yes | `"backlinko.com"` | The site to report on, e.g. example.com. A full URL also works; the report covers the whole domain including subdomains. | | `competitors` | array | | | Up to 5 competitor domains to benchmark. Leave empty to find the top 5 organic competitors automatically. | | `keywords` | array | | | Up to 20 keywords your client wants to rank for. Each gets search volume, keyword difficulty, intent and (for the first ones) a live Google check of your position, competitors and AI Overview citation. Leave empty to use the site's own top keywords. | | `location` | string | | `"United States"` | Search market: a country name ("United Kingdom"), 2-letter code ("GB") or location code (2826). | | `language` | string | | | Language name or code, e.g. "English" or "de". Defaults to the country's main language. | | `brandName` | string | | | How the brand is written in AI answers, e.g. "Acme Plumbing". Separate variants with commas. Defaults to the domain name. | | `aiPrompts` | array | | | Up to 5 questions to ask ChatGPT and Google AI Mode, e.g. "best emergency plumber in Austin". Leave empty to generate buyer questions from the site's keywords. | | `aiPromptCount` | integer | | `5` | How many prompts to check on each engine (0 to skip). Included in the report price. | | `includeAiVisibility` | boolean | | `true` | Check whether ChatGPT and Google AI Mode mention or cite the brand. | | `agencyName` | string | | | Shown in the report header and footer (white-label). | | `agencyLogoUrl` | string | | | Public PNG or JPG URL of your logo, shown top-left. | | `accentColor` | string | | | Hex colour for headings and charts, e.g. #0F766E. | | `clientName` | string | | | Shown as "prepared for …" under the title. | | `reportTitle` | string | | | Defaults to "SEO & AI Search Visibility Report". | | `includePdf` | boolean | | `true` | Also save the report as a PDF (the HTML report is always saved). | | `includePageSpeed` | boolean | | `true` | Test the homepage with Google PageSpeed Insights (mobile and desktop). | | `pageSpeedUrl` | string | | | Defaults to the homepage. | | `topKeywords` | integer | | `100` | How many of the site's top ranking keywords (by traffic) to include in the data. | | `serpKeywords` | integer | | `5` | How many keywords to check live on Google (target keywords first). | ## Example input ```json { "domain": "backlinko.com", "location": "United States", "agencyName": "Northwind Digital", "accentColor": "#0F766E" } ``` ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # SEO Toolkit All-in-One - Ahrefs & Semrush Alternative > Domain overview, ranked keywords, competitors, top pages, backlinks, referring domains, keyword metrics and live Google SERPs in one Actor. Licensed DataForSEO data, no scraping of Ahrefs or Semrush, no subscription. One "tool" parameter makes it a perfect MCP tool for AI agents. - Category: Rank tracking & site SEO - Price: $3 per 1,000 × result row, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/seo-toolkit - Human page: https://wrenfielddata.com/tools/seo-toolkit/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~seo-toolkit/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/seo-toolkit (appears as `wrenfield-data--seo-toolkit`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~seo-toolkit/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"tool": "domain_overview", "targets": ["backlinko.com"], "location": "United States", "maxResults": 20}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `tool` | string | yes | `"domain_overview"` | What to look up. Domain tools read targets; keyword_overview and serp read keywords. | | `targets` | array | | | Domains (example.com) or page URLs, for domain_overview, ranked_keywords, competitors, top_pages, backlinks and referring_domains. Up to 100. | | `keywords` | array | | | Keywords for keyword_overview (up to 2,000) and serp (up to 100). | | `location` | string | | `"United States"` | Country: name (United States), 2-letter code (DE) or location code (2840). | | `language` | string | | | Language name or code (English, es). Leave empty for the main language of the country. | | `maxResults` | integer | | `50` | Row limit for list tools (ranked keywords, competitors, top pages, backlinks, referring domains, SERP rows). The default of 50 keeps runs fast and cheap. | | `includeBacklinks` | boolean | | `true` | Adds domain rank, backlinks, referring domains and spam score to domain_overview (one extra backlinks request per domain). Turn off for traffic and keyword metrics only. | | `includeSubdomains` | boolean | | `true` | Count subdomains of the target (e.g. blog.example.com) too. | | `allBacklinksPerDomain` | boolean | | `false` | Off = one (strongest) backlink per referring domain, the most useful view. On = every backlink. | | `serpDepth` | integer | | `10` | serp tool only: how many Google results to check, in steps of 10 (each 10 results is one SERP request). | | `device` | string | | `"desktop"` | serp tool only. | ## Example input ```json { "tool": "domain_overview", "targets": [ "backlinko.com" ], "location": "United States", "maxResults": 20 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `tool` | string | Tool that produced the row | | `target` | string | Domain, URL or keyword the row is about | | `keyword` | string | Keyword (ranked_keywords, keyword_overview, serp) | | `position` | integer | Google position (ranked_keywords, serp) | | `position_absolute` | integer | Absolute position counting all result types (serp) | | `url` | string | Ranking URL (ranked_keywords, serp) or page URL (top_pages) | | `title` | string | Result title (serp) | | `description` | string | Result snippet (serp) | | `domain` | string | Result domain (serp) | | `result_type` | string | organic, paid or featured_snippet | | `is_featured_snippet` | boolean | Result is a featured snippet (serp) | | `has_ai_overview` | boolean | Google shows an AI Overview for the keyword | | `serp_features` | array | Result types on the Google results page | | `serp_results_count` | integer | Total results Google reports (serp) | | `search_volume` | integer | Average monthly Google searches | | `cpc` | number | Average Google Ads cost per click (USD) | | `competition` | string | Google Ads competition level | | `keyword_difficulty` | integer | SEO keyword difficulty 0-100 | | `difficulty_level` | string | very easy / easy / possible / difficult / hard / very hard | | `search_intent` | string | Main search intent | | `search_volume_trend` | object | Search volume change in % (monthly, quarterly, yearly) | | `estimated_traffic` | number | Estimated monthly visits from this ranking (ranked_keywords) | | `previous_position` | integer | Previous position (ranked_keywords) | | `position_change` | string | new, up, down or same (ranked_keywords) | | `organic_keywords` | integer | Keywords ranking in Google top 100 (domain_overview, top_pages) | | `organic_traffic` | integer | Estimated monthly organic visits (domain_overview, top_pages) | | `organic_traffic_value_usd` | number | What the organic traffic would cost in Google Ads per month (USD) | | `top3_keywords` | integer | Keywords in positions 1-3 | | `top10_keywords` | integer | Keywords in positions 1-10 | | `new_keywords` | integer | Newly ranking keywords since the last update (domain_overview) | | `lost_keywords` | integer | Keywords that stopped ranking (domain_overview) | | `keywords_up` | integer | Keywords that moved up (domain_overview) | | `keywords_down` | integer | Keywords that moved down (domain_overview) | | `paid_keywords` | integer | Keywords with Google Ads (domain_overview) | | `paid_traffic` | integer | Estimated monthly paid visits (domain_overview) | | `paid_traffic_cost_usd` | number | Estimated monthly Google Ads spend (USD, domain_overview) | | `domain_rank` | integer | Domain authority score 0-1000 from the backlink index (domain_overview, referring_domains) | | `backlinks` | integer | Live backlinks (domain_overview: total; referring_domains: from that domain) | | `referring_domains` | integer | Referring domains (domain_overview) | | `referring_main_domains` | integer | Referring root domains (domain_overview) | | `referring_ips` | integer | Referring IP addresses (domain_overview) | | `broken_backlinks` | integer | Backlinks pointing to broken pages (domain_overview) | | `spam_score` | integer | Backlink spam score 0-100 (higher = spammier) | | `first_seen` | string | When the domain or link was first seen (ISO 8601) | | `last_seen` | string | When the link was last seen (backlinks) | | `found` | boolean | domain_overview: false when no data exists for the domain | | `competitor_domain` | string | Competing domain (competitors) | | `common_keywords` | integer | Keywords both domains rank for (competitors) | | `avg_position` | number | Competitor average position on shared keywords (competitors) | | `shared_keywords_traffic` | integer | Competitor traffic from shared keywords (competitors) | | `competitor_organic_keywords` | integer | Competitor total organic keywords (competitors) | | `competitor_organic_traffic` | integer | Competitor total organic traffic (competitors) | | `competitor_traffic_value_usd` | number | Competitor organic traffic value in USD (competitors) | | `source_url` | string | Page the backlink is on (backlinks) | | `source_domain` | string | Domain the backlink is on (backlinks) | | `source_title` | string | Title of the linking page (backlinks) | | `target_url` | string | Linked page on the target (backlinks) | | `anchor` | string | Anchor text (backlinks) | | `dofollow` | boolean | Link passes authority (backlinks) | | `link_type` | string | anchor, image, redirect, canonical, ... (backlinks) | | `source_domain_rank` | integer | Rank 0-1000 of the linking domain (backlinks) | | `source_page_rank` | integer | Rank 0-1000 of the linking page (backlinks) | | `referring_domain` | string | Linking domain (referring_domains) | | `referring_pages` | integer | Pages on the referring domain that link (referring_domains) | | `location` | string | Country the data is for, e.g. "United States" | | `language` | string | Language name, e.g. "English" | | `scraped_at` | string | When this row was produced (ISO 8601, UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Shopify Scraper - Products & Price Monitor > Scrape any Shopify store's products (prices, compare-at and discount %, variants, SKUs, stock, images, tags, dates) from its public JSON feed. Monitor mode compares with the previous run and returns only new, removed, price-changed and stock-changed products. - Category: E-commerce & reviews - Price: $1 per 1,000 × product result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/shopify-store-scraper - Human page: https://wrenfielddata.com/tools/shopify-store-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~shopify-store-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/shopify-store-scraper (appears as `wrenfield-data--shopify-store-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~shopify-store-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"stores": ["allbirds.com", "kyliecosmetics.com"], "maxProductsPerStore": 20, "monitorMode": false, "outputProductsOnFirstRun": true, "monitorStoreName": "shopify-store-monitor", "includeInventory": false, "trackQuantityChanges": false, "includeDescription": true, "proxyConfiguration": {"useApifyProxy": true}, "requestDelaySecs": 1.0, "maxConcurrency": 5, "maxRetries": 6}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `stores` | array | yes | `["allbirds.com", "kyliecosmetics.com"]` | Store domains or URLs, one per line, e.g. allbirds.com, https://www.gymshark.com. You can also paste a collection URL (/collections/mens) or a product URL (/products/handle) to scrape just that collection or product. Domains that are not Shopify stores get a free error row. | | `collections` | array | | | Only scrape these collections in every store, e.g. mens-shoes (the part after /collections/ in the URL). Leave empty for the whole catalog. | | `keywords` | array | | | Keep only products whose title, handle, vendor, product type or tags contain at least one of these words (case-insensitive). | | `maxProductsPerStore` | integer | | `1000` | Maximum products per store (after the keyword filter). Shopify returns up to 250 products per request. In monitor mode, use a limit above the store's catalog size so removed products can be detected. | | `monitorMode` | boolean | | `false` | Compare each store with the previous run and output only new, removed, price-changed and stock-changed products, with previous and current values. Snapshots are kept in a named key-value store, one record per store. Schedule the Actor (e.g. daily) to get a change feed. | | `outputProductsOnFirstRun` | boolean | | `true` | On the first monitor run for a store there is nothing to compare with. When on, the full product list is output (billed as products); when off, the first run only saves the baseline. | | `monitorStoreName` | string | | `"shopify-store-monitor"` | Named key-value store in your account that keeps the snapshots. Use a different name to keep separate monitors. | | `monitorId` | string | | | Optional label that separates snapshots when you monitor the same store with different tasks. Collections and keyword filters already get their own snapshot. | | `includeInventory` | boolean | | `false` | Fetch each product's /products/.js to add variant barcodes and inventoryQuantity when the store exposes it. Checked once per store; skipped automatically if the store hides quantities. Adds one request per product. | | `trackQuantityChanges` | boolean | | `false` | Monitor mode with inventory on: also output a stock_changed row when a variant's inventory quantity changes (not only when it goes in or out of stock). Useful for sales-velocity tracking, but produces many more change rows. | | `includeDescription` | boolean | | `true` | Add the product description as plain text (HTML removed, max 5,000 characters). | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Requests go directly to the store first. The proxy is used only for a store that rate-limits the Actor (HTTP 429/430). Default: Apify datacenter proxy. | | `requestDelaySecs` | number | | `1.0` | Minimum pause between requests to the same store (with jitter). The default of 1 second matches the Crawl-delay most Shopify stores publish in robots.txt. The delay grows automatically if a store rate-limits. | | `maxConcurrency` | integer | | `5` | How many different stores are scraped at the same time. Each store is always fetched one page at a time. | | `maxRetries` | integer | | `6` | Retries with backoff for rate limits, timeouts and server errors. | ## Example input ```json { "stores": [ "allbirds.com", "kyliecosmetics.com" ], "maxProductsPerStore": 20, "monitorMode": false, "outputProductsOnFirstRun": true, "monitorStoreName": "shopify-store-monitor", "includeInventory": false, "trackQuantityChanges": false, "includeDescription": true, "proxyConfiguration": { "useApifyProxy": true }, "requestDelaySecs": 1.0, "maxConcurrency": 5, "maxRetries": 6 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: product, change (monitor mode) or error | | `store` | string | Store domain as given in the input | | `storeName` | string | Store name | | `storeUrl` | string | Store base URL | | `currency` | string | Store currency code, e.g. USD | | `productId` | integer/string | Shopify product ID | | `title` | string | Product title | | `handle` | string | Product handle (URL slug) | | `url` | string | Product page URL | | `vendor` | string | Brand / vendor | | `productType` | string | Product type / category set by the store | | `tags` | array | Product tags | | `createdAt` | string | When the product was created (ISO 8601) | | `updatedAt` | string | When the product was last updated (ISO 8601) | | `publishedAt` | string | When the product was published (ISO 8601) | | `price` | number | Lowest variant price in the store currency | | `priceMin` | number | Lowest variant price | | `priceMax` | number | Highest variant price | | `compareAtPrice` | number | Original ("compare at") price of the most-discounted variant | | `discountPercent` | number | Largest variant discount vs compare-at price, in % | | `onSale` | boolean | True when any variant is discounted | | `available` | boolean | True when at least one variant is in stock | | `variantsCount` | integer | Number of variants | | `availableVariantsCount` | integer | Number of in-stock variants | | `inventoryQuantity` | integer | Total units in stock (only when includeInventory is on and the store exposes it) | | `image` | string | Main product image URL | | `images` | array | All product image URLs | | `options` | array | Product options (e.g. Size, Color) with their values | | `variants` | array | Variants with id, title, sku, price, compareAtPrice, available, options, grams | | `description` | string | Product description as plain text | | `collection` | string | Collection handle the product or error relates to | | `availableCollections` | array | Collections that exist on the store (error rows) | | `scrapedAt` | string | When this row was produced (ISO 8601, UTC) | | `changeType` | string | Monitor mode: new, price_changed, stock_changed or removed | | `priceDirection` | string | Monitor mode: up, down or mixed | | `priceChangePercent` | number | Monitor mode: price change in % | | `stockEvent` | string | Monitor mode: back_in_stock, out_of_stock or variant_stock_changed | | `previous` | object | Monitor mode: previous values | | `current` | object | Monitor mode: current values | | `variantChanges` | array | Monitor mode: per-variant price or stock changes | | `product` | object | Monitor mode: full product row for new products | | `detectedAt` | string | Monitor mode: when the change was detected | | `previousRunAt` | string | Monitor mode: when the previous snapshot was taken | | `input` | string | Error rows: the input value that failed | | `errorType` | string | Error rows: unreachable, not_shopify, password_protected, feed_disabled, fetch_failed, product_not_found, collection_not_found, invalid_input or internal_error | | `error` | string | Error rows: human-readable error message | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Telegram Channel Scraper - Posts, Views, No Login > Scrape public Telegram channels without login, phone number or API keys. Get posts with text and HTML, date, views, reactions, forwards, replies, photos, video thumbnails, files and link previews, plus channel info with exact subscriber counts. Date range, keyword filter and deep history. - Category: Jobs & content - Price: $1 per 1,000 × post result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/telegram-channel-scraper - Human page: https://wrenfielddata.com/tools/telegram-channel-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~telegram-channel-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/telegram-channel-scraper (appears as `wrenfield-data--telegram-channel-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~telegram-channel-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"channels": ["durov"], "maxPostsPerChannel": 20, "keywordMode": "contains", "matchAllKeywords": false, "wholeWordsOnly": true, "maxScannedPostsPerChannel": 5000, "includeChannelInfo": true, "includeHtml": true, "includeServiceMessages": false, "proxyConfiguration": {"useApifyProxy": true}, "alwaysUseProxy": false, "maxConcurrency": 10}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `channels` | array | yes | `["durov"]` | Public Telegram channels, one per line: a username (durov, @durov) or a link (https://t.me/durov, https://t.me/s/durov). A post link (https://t.me/durov/400) starts from that post and goes back in time. Private invite links, groups, users and bots are reported as free error rows. | | `maxPostsPerChannel` | integer | | `100` | Newest posts to return per channel (after date and keyword filters). Set 0 for no limit when you use From date. Pagination goes as deep as the channel's history (thousands of posts are fine). | | `dateFrom` | string | | | Only posts published on or after this date. YYYY-MM-DD, an ISO date-time (UTC), or relative: 7 days, 24 hours, 3 months. | | `dateTo` | string | | | Only posts published on or before this date (a plain date includes the whole day, UTC). The scraper jumps straight to that point in the channel history, so old ranges are fast. | | `keywords` | array | | | Only return posts containing any of these words or phrases (case-insensitive; checked in the post text, file names, link preview and poll question). Posts that don't match are not charged. Leave empty for all posts. | | `keywordMode` | string | | `"contains"` | Contains scans the channel history (respecting the date range) and keeps matching posts - exact and as deep as you need. Telegram search uses Telegram's own search (matches word forms) but Telegram returns only about 20 of the newest matches per keyword. | | `matchAllKeywords` | boolean | | `false` | Only keep posts that contain every keyword (default: any keyword). | | `wholeWordsOnly` | boolean | | `true` | Match keywords as whole words (SEC won't match "second"). Turn off to also match inside words, e.g. word forms (Трамп → "Трампа") or prefixes (crypto → "cryptocurrency"). Chinese, Japanese, Korean and Thai keywords always match anywhere. | | `maxScannedPostsPerChannel` | integer | | `5000` | With a keyword filter, stop scanning a channel after this many posts even if fewer matches were found. Scanned posts that don't match are free. | | `includeChannelInfo` | boolean | | `true` | Add one row per channel with title, description, exact subscriber count, photo, verified / scam / fake flags and media counters. | | `includeHtml` | boolean | | `true` | Add textHtml (formatting, links, custom emoji) next to the plain text. | | `includeServiceMessages` | boolean | | `false` | Include 'Channel created', 'Channel photo updated' and similar service messages. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Telegram's web preview usually works without a proxy. This proxy is used only if Telegram starts rate-limiting the run (then the rest of the run goes through it). The default Apify datacenter proxy is enough. | | `alwaysUseProxy` | boolean | | `false` | Send every request through the proxy above instead of connecting directly first. | | `maxConcurrency` | integer | | `10` | Parallel page requests. Large single channels are split into parallel page streams. | ## Example input ```json { "channels": [ "durov" ], "maxPostsPerChannel": 20, "keywordMode": "contains", "matchAllKeywords": false, "wholeWordsOnly": true, "maxScannedPostsPerChannel": 5000, "includeChannelInfo": true, "includeHtml": true, "includeServiceMessages": false, "proxyConfiguration": { "useApifyProxy": true }, "alwaysUseProxy": false, "maxConcurrency": 10 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: post, channel (channel info) or error (free) | | `status` | string | channel/error rows: ok, not_found, no_web_preview, private, is_group, is_user, is_bot, invalid_input, no_posts, no_matches, fetch_failed | | `channel` | string | Channel username | | `channelTitle` | string | Channel title | | `postId` | integer | Post ID (message ID within the channel) | | `url` | string | Post or channel URL | | `date` | string | Published (ISO 8601, UTC) | | `text` | string | Post text (plain, emoji kept, line breaks preserved) | | `textHtml` | string | Post text as HTML (formatting, links, custom emoji) | | `views` | integer | Views (Telegram rounds large numbers: 18.9M) | | `viewsText` | string | Views as shown | | `author` | string | Author signature, if the channel signs posts | | `isEdited` | boolean | Post was edited | | `forwardedFrom` | object | Original channel/user of a forwarded post: name, url, username, postId | | `replyTo` | object | Replied-to post: postId, channel, url, author, text | | `mediaType` | string | text, photo, video, album, document, audio, voice, round_video, sticker, gif, location, poll, service, unsupported | | `media` | array | Media items: type, url, thumbnailUrl, duration, fileName, fileSize | | `mediaCount` | integer | Number of media items | | `photoUrls` | array | Photo URLs | | `videoThumbnailUrls` | array | Video thumbnail URLs | | `documentNames` | array | Attached file names | | `linkPreview` | object | Link preview: url, siteName, title, description, imageUrl | | `poll` | object | Poll: question, type, options (text, percent), voters | | `links` | array | Links in the post text | | `hashtags` | array | Hashtags | | `mentions` | array | @mentions | | `reactions` | array | Reactions: emoji, customEmojiId, isPaid (Stars), count | | `reactionsTotal` | integer | Sum of all reaction counts | | `isService` | boolean | Service message (channel created, photo updated...) | | `matchedKeywords` | array | Keywords found in the post | | `title` | string | Channel title (channel rows) | | `description` | string | Channel description | | `descriptionHtml` | string | Channel description HTML | | `subscribers` | integer | Exact subscriber count | | `subscribersText` | string | Subscribers as shown in the preview (10.5M) | | `photoUrl` | string | Channel photo URL | | `isVerified` | boolean | Verified channel | | `isScam` | boolean | Marked as scam by Telegram | | `isFake` | boolean | Marked as fake by Telegram | | `photosCount` | integer | Photos in the channel | | `videosCount` | integer | Videos in the channel | | `filesCount` | integer | Files in the channel | | `linksCount` | integer | Links in the channel | | `lastPostId` | integer | Newest post ID | | `lastPostDate` | string | Newest post date | | `webPreviewUrl` | string | t.me/s/ URL | | `error` | string | Why the channel could not be scraped (error rows) | | `input` | string | Your input this row came from | | `scrapedAt` | string | Scraped at (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Tripadvisor Reviews Scraper - Hotels & Restaurants > Get Tripadvisor reviews for any hotel, restaurant or attraction: text, star rating, date, trip date, sub-ratings, photos, owner responses and reviewer info. Paste URLs or search "hotels in Lisbon". Filter by stars, traveler type, month, language or date. No blocking, no proxies. - Category: E-commerce & reviews - Price: $1 per 1,000 × review, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/tripadvisor-reviews-scraper - Human page: https://wrenfielddata.com/tools/tripadvisor-reviews-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~tripadvisor-reviews-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/tripadvisor-reviews-scraper (appears as `wrenfield-data--tripadvisor-reviews-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~tripadvisor-reviews-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"startUrls": ["https://www.tripadvisor.com/Attraction_Review-g187147-d188151-Reviews-Eiffel_Tower-Paris_Ile_de_France.html"], "maxPlacesPerSearch": 5, "maxReviewsPerPlace": 20, "sortBy": "most_recent", "translateReviews": true, "includePlaceDetails": false, "includeReviewerInfo": true}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `startUrls` | array | | | Tripadvisor pages of hotels, restaurants, attractions, tours or vacation rentals, e.g. https://www.tripadvisor.com/Hotel_Review-g60763-d93437-Reviews-Hotel_Edison_Times_Square-New_York_City_New_York.html. Any Tripadvisor country site works (.co.uk, .de, .fr...). A single-review link also works: the Actor takes the place it belongs to. | | `searchQueries` | array | | | Find places by keyword instead of URL, e.g. hotels in Lisbon, Portugal, sushi restaurants in Austin, TX or museums in Rome. The Actor takes the top places from Tripadvisor search and gets their reviews. Write "... in City, Country" or fill in Search location below. | | `searchLocation` | string | | | Optional location used for every search query: City, Country (e.g. Lisbon, Portugal), City, State (e.g. Portland, Maine) or a region. Leave empty to read it from each query ("hotels in Lisbon"). | | `maxPlacesPerSearch` | integer | | `5` | How many top Tripadvisor search results (places) to take for each search query. | | `maxReviewsPerPlace` | integer | | `100` | Maximum number of reviews to get for each place. Set 0 to get only place details (name, address, rating, review count and star distribution) without reviews. | | `sortBy` | string | | `"most_recent"` | Order in which reviews are collected. With a limit, this decides which reviews you get. | | `reviewsNewerThan` | string | | | Only reviews published on or after this date, e.g. 2026-09-01 or 30 days. Great for scheduled monitoring: run daily or weekly and get only new reviews. | | `ratings` | array | | | Only reviews with these star ratings, e.g. 1 and 2 to collect complaints. Empty = all ratings. | | `travelerTypes` | array | | | Only reviews from these types of travelers (mainly hotels and attractions). Empty = all. | | `visitMonths` | array | | | Only reviews from trips in these months (seasonality analysis). Empty = all. | | `language` | string | | | Language to get reviews in, as a code: en, fr, de, es, it, ja, zh-CN... With translations on, Tripadvisor machine-translates reviews into this language where it can. Leave empty to use the language of the URL's site (English for tripadvisor.com). Every row keeps originalLanguage, so you can filter by the language reviews were written in. | | `translateReviews` | boolean | | `true` | When on, reviews written in other languages come in Tripadvisor's machine translation into the site's language (English for tripadvisor.com). originalLanguage and isTranslated tell you which ones were translated. | | `includePlaceDetails` | boolean | | `false` | Also save one row per place (rowType = place) with name, address, rating, total review count, the 1-5 star distribution and, for searches, the search rank, category and price. Charged as a separate, small event. | | `includeReviewerInfo` | boolean | | `true` | Include the reviewer's public display name, profile link, home location, review count and avatar. Turn off if you don't need personal data (recommended for GDPR-sensitive use). | | `maxItems` | integer | | | Stop after this many reviews across all places. You can also cap spending with Apify's "Maximum cost per run"; the Actor stops exactly there and never buys data it cannot return. | ## Example input ```json { "startUrls": [ "https://www.tripadvisor.com/Attraction_Review-g187147-d188151-Reviews-Eiffel_Tower-Paris_Ile_de_France.html" ], "maxPlacesPerSearch": 5, "maxReviewsPerPlace": 20, "sortBy": "most_recent", "translateReviews": true, "includePlaceDetails": false, "includeReviewerInfo": true } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `rowType` | string | review, place or error (error rows are free) | | `placeId` | string | Tripadvisor location id (the d-number in the URL) | | `placeName` | string | Place name | | `placeType` | string | hotel, restaurant, attraction, tour, vacation_rental... | | `placeUrl` | string | Tripadvisor URL of the place | | `placeAddress` | string | Address | | `placeRating` | number | Overall Tripadvisor rating (1-5) | | `placeReviewsCount` | integer | Total reviews on Tripadvisor | | `reviewId` | string | Tripadvisor review id | | `reviewUrl` | string | Link to the review | | `rating` | number | Review star rating (1-5) | | `title` | string | Review title | | `text` | string | Review text | | `publishedAt` | string | Publication timestamp (UTC) | | `publishedDate` | string | Publication date YYYY-MM-DD | | `visitDate` | string | Month of the trip YYYY-MM | | `language` | string | Language of the returned text | | `originalLanguage` | string | Language the review was written in | | `isTranslated` | boolean | Text is a Tripadvisor translation | | `subRatings` | object | Sub-ratings such as Value, Rooms, Location, Cleanliness, Service, Sleep Quality | | `photos` | array | Photo URLs attached to the review | | `photoCount` | integer | Number of photos | | `ownerResponse` | string | Management response text | | `ownerResponseDate` | string | Management response date | | `hasOwnerResponse` | boolean | Whether management replied | | `reviewerName` | string | Reviewer display name | | `reviewerProfileUrl` | string | Reviewer profile | | `reviewerLocation` | string | Reviewer home location | | `reviewerReviewsCount` | integer | Reviewer's total reviews | | `ratingDistribution` | object | Place rows: number of reviews per star (1-5) | | `searchQuery` | string | Search that found the place | | `searchRank` | integer | Position in Tripadvisor search | | `error` | string | Error rows: what went wrong | | `errorCode` | string | Error rows: machine-readable code | | `input` | string | The URL or search query this row came from | | `scrapedAt` | string | When the row was collected (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Walmart Scraper - Product Prices, Stock & Reviews > Scrape Walmart.com products by keyword, category URL, product URL or item ID: price, was-price, unit price, stock, pickup/delivery, seller (Walmart vs marketplace), UPC/GTIN, variants, specs, images, ratings and optional reviews. Fast HTTP, no browser, auto-retries blocked requests. - Category: E-commerce & reviews - Price: $3.50 per 1,000 × product with full details, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/walmart-product-scraper - Human page: https://wrenfielddata.com/tools/walmart-product-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~walmart-product-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/walmart-product-scraper (appears as `wrenfield-data--walmart-product-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~walmart-product-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"searchKeywords": ["coffee"], "startUrls": [{"url": "https://www.walmart.com/browse/food/coffee/976759_1086446"}], "productIds": ["578550306"], "maxItems": 5, "maxItemsPerQuery": 40, "includeDetails": true, "sort": "best_match", "includeReviews": false, "maxReviewsPerProduct": 20, "reviewsSort": "relevancy", "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "maxConcurrency": 10, "maxRetries": 8}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `searchKeywords` | array | | | Keywords to search on Walmart.com, one per line (e.g. coffee, air fryer). Each keyword returns up to Max products per search/category products. | | `startUrls` | array | | | Walmart URLs: category pages (/browse/..., /cp/...), search result pages with filters (/search?q=...), brand/shop pages, or product pages (/ip/...). | | `productIds` | array | | | Walmart item IDs (the number at the end of a product URL, e.g. 578550306) or full /ip/ product URLs, one per line. | | `maxItems` | integer | | `50` | Maximum number of product rows for the whole run (reviews are not counted). Duplicate products across keywords/categories are skipped automatically. | | `maxItemsPerQuery` | integer | | `40` | How many products to take from each keyword or category URL. Walmart shows about 40 products per page and up to 25 pages (about 1,000 products) per search. | | `includeDetails` | boolean | | `true` | Open each product page for brand, UPC/GTIN, specifications, variants, description, all images, seller details and pickup/delivery options. Turn off for a faster, cheaper listing-only scrape (title, price, rating, seller, availability from the search grid). | | `sort` | string | | `"best_match"` | Sort order for keyword searches and category pages. | | `minPrice` | integer | | | Only products at or above this price (search and category pages). | | `maxPrice` | integer | | | Only products at or below this price (search and category pages). | | `zipCode` | string | | | Optional 5-digit US ZIP code. Prices, stock, delivery dates and the pickup store (Walmart picks the nearest store) are returned for this ZIP. Every product row includes the location Walmart actually used, so you can verify it. Leave empty for Walmart's default location for the proxy IP. | | `includeReviews` | boolean | | `false` | Also scrape customer reviews for every product (output rows with type = review). | | `maxReviewsPerProduct` | integer | | `20` | Reviews are loaded 10 per page. | | `reviewsSort` | string | | `"relevancy"` | Order of the reviews. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Defaults to Apify datacenter proxy (cheapest) with automatic residential fallback when Walmart blocks it. Choose the RESIDENTIAL group to always use US residential IPs. | | `residentialFallback` | boolean | | `true` | Retry blocked requests on US residential IPs with a fresh browser session. Recommended - this is what keeps the success rate above 95%. | | `maxConcurrency` | integer | | `10` | Parallel requests. | | `maxRetries` | integer | | `8` | Each blocked page is retried with a new IP and browser fingerprint, with backoff. | ## Example input ```json { "searchKeywords": [ "coffee" ], "startUrls": [ { "url": "https://www.walmart.com/browse/food/coffee/976759_1086446" } ], "productIds": [ "578550306" ], "maxItems": 5, "maxItemsPerQuery": 40, "includeDetails": true, "sort": "best_match", "includeReviews": false, "maxReviewsPerProduct": 20, "reviewsSort": "relevancy", "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": true, "maxConcurrency": 10, "maxRetries": 8 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `type` | string | Row type: product, review or error (errors are free) | | `itemId` | string | Walmart item ID (usItemId) | | `productId` | string | Walmart catalog product ID | | `title` | string | Product title | | `brand` | string | Brand | | `url` | string | Product URL | | `price` | number | Current price | | `wasPrice` | number | Previous price (strike-through) | | `listPrice` | number | List price | | `unitPrice` | number | Price per unit | | `unitPriceString` | string | Unit price as shown, e.g. 50.0 ¢/oz | | `unitOfMeasure` | string | Unit of measure | | `currency` | string | Currency | | `savingsAmount` | number | Savings vs was-price | | `rating` | number | Average rating 1-5 | | `reviewCount` | integer | Number of ratings/reviews | | `sellerId` | string | Seller ID | | `sellerName` | string | Seller name | | `sellerType` | string | WALMART (1P) or MARKETPLACE (3P) | | `fulfilledByWalmart` | boolean | Sold or fulfilled by Walmart (WFS) | | `offerCount` | integer | Number of offers for the item | | `availability` | string | IN_STOCK, OUT_OF_STOCK, ... | | `inStock` | boolean | In stock | | `shipping` | object | Shipping option: available, date, price, label | | `pickup` | object | Store pickup option: store, date, aisle | | `delivery` | object | Delivery-from-store option | | `location` | object | ZIP / store Walmart used for price and availability | | `image` | string | Main image URL | | `images` | array | All image URLs | | `categories` | array | Category breadcrumb | | `upc` | string | UPC | | `gtin14` | string | GTIN-14 (UPC zero-padded) | | `model` | string | Model number | | `variants` | array | Variants with item ID, attributes, price, availability | | `specifications` | object | Specifications name -> value | | `description` | string | Long description (plain text) | | `shortDescription` | string | Short description | | `badges` | array | Badges, e.g. Rollback, Best seller | | `isSponsored` | boolean | Sponsored placement in search | | `detailsScraped` | boolean | True when the product page was scraped (full details) | | `source` | object | Where the product came from: search/category/product input, page, position | | `reviewId` | string | Review ID | | `text` | string | Review text | | `date` | string | Review date (YYYY-MM-DD) | | `userNickname` | string | Reviewer nickname | | `verifiedPurchase` | boolean | Verified purchase | | `error` | string | Error message for type = error | | `scrapedAt` | string | Scrape time (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Contact Scraper - Website Emails, Phones & Socials > Extract emails, phone numbers and social media profiles (LinkedIn, Facebook, Instagram, X, YouTube, TikTok...) from any list of company websites or domains. One clean row per website, contact-page aware, email provider (MX) detection. Pay only for websites with contacts. - Category: Lead & company data - Price: $4 per 1,000 × website with contacts, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/website-contact-scraper - Human page: https://wrenfielddata.com/tools/website-contact-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~website-contact-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/website-contact-scraper (appears as `wrenfield-data--website-contact-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~website-contact-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"urls": ["apify.com", "https://www.katzsdelicatessen.com", "levainbakery.com"], "maxPagesPerDomain": 6, "extractPhones": true, "extractSocials": true, "defaultCountry": "US", "onlyRoleEmails": false, "onlyOwnDomainEmails": false, "checkMx": true, "respectRobotsTxt": true, "maxConcurrency": 30, "proxyMode": "fallback", "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": false}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `urls` | array | | | Company websites or bare domains, one per line: acme.com, https://www.acme.com or a specific page like acme.com/contact. The Actor always starts at the homepage and then visits the pages most likely to list contacts (Contact, About, Team, Impressum, Locations...). Duplicates are skipped. | | `datasetId` | string | | | ID of an Apify dataset to enrich, e.g. from Google Maps Scraper or Company Name to Domain Finder. The Actor reads each item's website from the field below and adds sourceName / sourceIndex so you can join the results back. | | `datasetUrlField` | string | | | Field holding the website in that dataset. Leave empty to auto-detect (website, url, domain, companyWebsite...). | | `maxPagesPerDomain` | integer | | `6` | Homepage plus the highest-ranked contact/about/team/legal pages. 4-8 finds most contacts; more pages = slower, never more expensive per website. | | `extractPhones` | boolean | | `true` | Phone numbers from tel: links, structured data and text next to a phone label, validated and normalised to E.164 (+14155550132). | | `extractSocials` | boolean | | `true` | LinkedIn, Facebook, Instagram, X/Twitter, YouTube, TikTok, Pinterest, GitHub, Threads, WhatsApp, Telegram, Discord, Yelp and Trustpilot profile links. Share buttons and post links are ignored. | | `defaultCountry` | string | | `"US"` | 2-letter country used to read local phone numbers (without +country code) on sites with a generic TLD like .com. Country TLDs (.de, .co.uk...) and the page language (en-GB) override it. | | `onlyRoleEmails` | boolean | | `false` | Drop personal addresses (jane.doe@...) and free-mail addresses. Useful for GDPR-sensitive outreach. | | `onlyOwnDomainEmails` | boolean | | `false` | Drop addresses on other domains (agencies, parent companies, gmail.com...). | | `checkMx` | boolean | | `true` | DNS check: drops emails whose domain cannot receive mail, and adds the website's email provider (Google Workspace, Microsoft 365, Zoho...) and security gateway (Proofpoint, Mimecast...). No emails are sent. | | `respectRobotsTxt` | boolean | | `true` | Skip pages the website's robots.txt disallows for all crawlers. Websites that disallow everything return a free robots_disallowed row. | | `maxConcurrency` | integer | | `30` | How many websites are crawled at the same time. | | `maxResults` | integer | | | Stop after this many paid results (websites with at least one contact). Leave empty for no limit. You can also cap spending with the run's maximum cost. | | `proxyMode` | string | | `"fallback"` | Most company websites don't block, so pages are fetched directly and only blocked requests are retried through the proxy. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Proxy used for websites that block direct requests. Apify datacenter proxy is included in the price. | | `residentialFallback` | boolean | | `false` | Retry still-blocked websites through residential IPs. Slightly higher success on heavily protected sites. | ## Example input ```json { "urls": [ "apify.com", "https://www.katzsdelicatessen.com", "levainbakery.com" ], "maxPagesPerDomain": 6, "extractPhones": true, "extractSocials": true, "defaultCountry": "US", "onlyRoleEmails": false, "onlyOwnDomainEmails": false, "checkMx": true, "respectRobotsTxt": true, "maxConcurrency": 30, "proxyMode": "fallback", "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": false } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `input` | string | Website or domain as given | | `domain` | string | Registrable domain (after redirects) | | `url` | string | Homepage URL after redirects | | `status` | string | ok (charged) \| no_contacts \| error \| invalid_input \| robots_disallowed (all free) | | `companyName` | string | Name from structured data, og:site_name or page title | | `primaryEmail` | string | Best email: own domain, explicit mailto, contact page first | | `emails` | array | All emails found, best first | | `primaryPhone` | string | Best phone in E.164 | | `phones` | array | All phone numbers in E.164 | | `linkedin` | string | LinkedIn company/profile URL | | `facebook` | string | Facebook page | | `instagram` | string | Instagram profile | | `twitter` | string | X / Twitter profile | | `youtube` | string | YouTube channel | | `tiktok` | string | TikTok profile | | `pinterest` | string | Pinterest profile | | `github` | string | GitHub org/user | | `threads` | string | Threads profile | | `whatsapp` | string | WhatsApp click-to-chat link | | `telegram` | string | Telegram link | | `discord` | string | Discord invite | | `yelp` | string | Yelp business page | | `trustpilot` | string | Trustpilot review page | | `socialProfiles` | array | All social profile URLs | | `address` | string | Postal address from structured data | | `contactPageUrl` | string | Contact / Impressum page found | | `hasContactForm` | boolean | A contact form (email + message) was found | | `emailProvider` | string | Mail provider of the domain from MX records | | `emailSecurityGateway` | string | Email security gateway (Proofpoint, Mimecast...) | | `mxRecords` | array | MX hosts | | `emailDetails` | array | Per email: type (role/personal/free), onDomain, source, page, domainAcceptsMail | | `phoneDetails` | array | Per phone: international format, country, source, page | | `title` | string | Homepage title | | `description` | string | Meta description | | `language` | string | | | `logo` | string | Logo URL from structured data | | `legalName` | string | Legal name from structured data | | `pagesCrawled` | integer | Pages fetched | | `crawledUrls` | array | Pages fetched | | `pagesFailed` | integer | Pages that failed | | `proxyUsed` | array | Proxy tiers used, if any | | `redirectedFrom` | string | Original domain if the website redirected to another domain | | `sourceName` | string | Name from the enriched dataset item | | `sourceIndex` | integer | Index in the enriched dataset | | `errorType` | string | dns_not_found \| timeout \| connection_failed \| blocked \| http_error \| ssl_error \| not_html \| invalid_input \| robots_disallowed | | `error` | string | Why there are no contacts | | `scrapedAt` | string | UTC timestamp | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # Tech Stack Detector like Wappalyzer & BuiltWith > Detect the technologies behind any list of websites: CMS, ecommerce platform, analytics, ad pixels, marketing tools, payment, CDN, hosting, frameworks and 7,600+ more, plus email provider and SPF senders from DNS. One clean row per website. Pay only for websites analysed. - Category: Domain & website intelligence - Price: $2.50 per 1,000 × website analyzed, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/website-tech-stack-detector - Human page: https://wrenfielddata.com/tools/website-tech-stack-detector/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~website-tech-stack-detector/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/website-tech-stack-detector (appears as `wrenfield-data--website-tech-stack-detector`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~website-tech-stack-detector/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"urls": ["apify.com", "wordpress.org", "allbirds.com"], "outputFilteredOut": false, "minConfidence": 50, "includeTechnologyDetails": true, "checkDnsAndTls": true, "maxPagesPerWebsite": 1, "maxConcurrency": 25, "proxyMode": "fallback", "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": false}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `urls` | array | | | Websites or bare domains, one per line: acme.com, https://www.acme.com or a specific page like acme.com/pricing. Duplicates are skipped. Up to 100,000 per run. | | `datasetId` | string | | | ID of an Apify dataset to enrich, e.g. from Google Maps Scraper, Website Contact Scraper or Company Name to Domain Finder. Each item's website is read from the field below; sourceName / sourceIndex are added so you can join the results back. | | `datasetUrlField` | string | | | Field holding the website in that dataset. Leave empty to auto-detect (website, url, domain, companyWebsite...). | | `onlyWithTechnologies` | array | | | Keep only websites where at least one of these technologies is detected, e.g. Shopify, WooCommerce, HubSpot, Klaviyo. Names as in Wappalyzer, case-insensitive. Websites without a match are not charged and not output (unless enabled below). Great for building lead lists by technology. | | `outputFilteredOut` | boolean | | `false` | When the filter above is set, add a free filtered_out row for each website without a match (status only, no technologies). | | `minConfidence` | integer | | `50` | Hide weak detections below this confidence. 50 keeps everything the fingerprints are reasonably sure about; 100 = only certain detections; 0 = everything. | | `includeTechnologyDetails` | boolean | | `true` | Add technologyDetails: version, confidence, categories, vendor website, SaaS / open-source flags, pricing tier and how each technology was detected. | | `checkDnsAndTls` | boolean | | `true` | Read the domain's MX, TXT (SPF + site verifications), NS, SOA and CNAME records and the TLS certificate issuer: adds email provider (Google Workspace, Microsoft 365...), email security gateway, email-sending services from SPF (HubSpot, Salesforce, SendGrid, Zendesk...), DNS provider and SSL issuer. No emails are sent. | | `maxPagesPerWebsite` | integer | | `1` | 1 = homepage only (fastest, finds most technologies). 2-5 also scans pages from different sections (shop, pricing, blog...) to catch tools only loaded there. Never more expensive per website. | | `maxConcurrency` | integer | | `25` | How many websites are analysed at the same time. | | `maxResults` | integer | | | Stop after this many paid results (websites with at least one technology detected). Leave empty for no limit. You can also cap spending with the run's maximum cost. | | `proxyMode` | string | | `"fallback"` | Most websites don't block, so pages are fetched directly and only blocked requests are retried through the proxy. | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Proxy used for websites that block direct requests. Apify datacenter proxy is included in the price. | | `residentialFallback` | boolean | | `false` | Retry still-blocked websites through residential IPs. Slightly higher success on heavily protected sites. | ## Example input ```json { "urls": [ "apify.com", "wordpress.org", "allbirds.com" ], "outputFilteredOut": false, "minConfidence": 50, "includeTechnologyDetails": true, "checkDnsAndTls": true, "maxPagesPerWebsite": 1, "maxConcurrency": 25, "proxyMode": "fallback", "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": false } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `input` | string | Website or domain as given | | `domain` | string | Registrable domain (after redirects) | | `url` | string | Homepage URL after redirects | | `status` | string | ok (charged) \| no_technologies \| filtered_out \| error \| invalid_input (all free) | | `technologyCount` | integer | Number of technologies detected | | `technologies` | array | All technology names, most important categories first | | `cms` | array | Technologies in categories: CMS, Blogs, Page builders, Static site generator, Wikis, DMS, LMS | | `ecommerce` | array | Technologies in categories: Ecommerce, Ecommerce frontends | | `ecommerceAddOns` | array | Technologies in categories: Shopify apps, Cart abandonment, Loyalty & rewards, Returns, Fulfilment, Cross border ecommerce, Shipping carriers, Referral marketing, Affiliate programs | | `paymentProcessors` | array | Technologies in categories: Payment processors, Buy now pay later | | `analytics` | array | Technologies in categories: Analytics, RUM, Surveys, Browser fingerprinting, Customer data platform, Segmentation | | `tagManagers` | array | Technologies in categories: Tag managers | | `advertising` | array | Technologies in categories: Advertising, Retargeting | | `marketingAutomation` | array | Technologies in categories: Marketing automation, Personalisation, Content curation | | `emailServices` | array | Technologies in categories: Email, Webmail | | `crm` | array | Technologies in categories: CRM | | `liveChat` | array | Technologies in categories: Live chat, User onboarding | | `abTesting` | array | Technologies in categories: A/B Testing, Feature management | | `reviews` | array | Technologies in categories: Reviews | | `cookieConsent` | array | Technologies in categories: Cookie compliance | | `javascriptFrameworks` | array | Technologies in categories: JavaScript frameworks, Mobile frameworks | | `javascriptLibraries` | array | Technologies in categories: JavaScript libraries, JavaScript graphics, Font scripts | | `uiFrameworks` | array | Technologies in categories: UI frameworks | | `webFrameworks` | array | Technologies in categories: Web frameworks | | `programmingLanguages` | array | Technologies in categories: Programming languages | | `webServers` | array | Technologies in categories: Web servers, Reverse proxies, Load balancers, Caching, Web server extensions | | `cdn` | array | Technologies in categories: CDN | | `hosting` | array | Technologies in categories: PaaS, IaaS, Hosting, Hosting panels | | `security` | array | Technologies in categories: Security, Authentication | | `searchAndAI` | array | Technologies in categories: Search engines, Artificial Intelligence | | `bookingAndScheduling` | array | Technologies in categories: Appointment scheduling, Reservations & delivery, Ticket booking | | `forms` | array | Technologies in categories: Form builders | | `recruiting` | array | Technologies in categories: Recruitment & staffing | | `seo` | array | Technologies in categories: SEO | | `emailProvider` | string | Email host from MX records (Google Workspace, Microsoft 365, Zoho...) | | `emailSecurityGateway` | string | Email security gateway from MX (Proofpoint, Mimecast...) | | `emailSendingServices` | array | Services allowed to send email for the domain (SPF includes): HubSpot, Salesforce, SendGrid... | | `dnsProvider` | string | DNS host from NS records | | `sslIssuer` | string | TLS certificate issuer organisation | | `sslValidUntil` | string | TLS certificate expiry | | `paidSaasCount` | integer | Detected SaaS tools with a paid plan (pricing data from the fingerprints) | | `techSpendScore` | integer | Rough spend signal: sum of price tiers of paid tools (low=1, mid/poa=2, high=3) | | `technologiesByCategory` | object | Category name -> technologies | | `technologyDetails` | array | Per technology: name, version, confidence, categories, groups, website, description, saas, openSource, pricing, cpe, detectedBy | | `dnsRecords` | object | mx, ns, spf, txtVerifications (services that verified the domain), cname | | `title` | string | Homepage title | | `description` | string | Meta description | | `language` | string | | | `httpStatus` | integer | HTTP status of the homepage | | `pagesScanned` | integer | Pages analysed | | `scannedUrls` | array | URLs analysed | | `pagesFailed` | integer | Extra pages that could not be fetched | | `proxyUsed` | array | Proxy tiers needed (null = direct) | | `redirectedFrom` | string | Original domain if the site redirected to another domain | | `sourceName` | string | Name from the enriched dataset item | | `sourceIndex` | integer | Index of the enriched dataset item | | `errorType` | string | dns_not_found \| timeout \| connection_failed \| blocked \| http_error \| not_html \| ssl_error \| invalid_input | | `error` | string | Why the row is free | | `scrapedAt` | string | UTC timestamp | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # YouTube Transcript Scraper - Subtitles & Captions > Get YouTube transcripts (captions/subtitles) in bulk for videos, Shorts, channels, playlists or search results. Plain text, timestamped segments, SRT, VTT or RAG-ready chunks, with language fallback and video metadata. No browser, no API key. Pay only for transcripts found. - Category: Jobs & content - Price: $3 per 1,000 × transcript result, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`. - Store page: https://apify.com/wrenfield-data/youtube-transcript-scraper - Human page: https://wrenfielddata.com/tools/youtube-transcript-scraper/ - OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~youtube-transcript-scraper/builds/default/openapi.json - MCP tool: https://mcp.apify.com?tools=wrenfield-data/youtube-transcript-scraper (appears as `wrenfield-data--youtube-transcript-scraper`) ## Call it Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec): ```bash curl -X POST \ "https://api.apify.com/v2/acts/wrenfield-data~youtube-transcript-scraper/run-sync-get-dataset-items" \ -H "Authorization: Bearer $APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"urls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"], "maxVideos": 1, "channelContentType": "videos", "maxTotalVideos": 1000, "languages": ["en"], "fallbackToAnyLanguage": true, "autoTranslate": false, "preferManualCaptions": true, "skipAutoGenerated": false, "outputFormats": ["text", "segments"], "chunkSize": 2000, "chunkOverlap": 200, "includeDescription": true, "proxyConfiguration": {"useApifyProxy": true}, "residentialFallback": true, "maxConcurrency": 20, "maxRetries": 6}' ``` ## Input | Field | Type | Required | Default | Description | |---|---|---|---|---| | `urls` | array | | | One per line, mixed freely: video URLs (watch?v=, youtu.be/, /shorts/, /live/, /embed/), 11-character video IDs, channel URLs or @handles (/@name, /channel/UC…, /c/, /user/; add /shorts or /streams to pick that tab) and playlist URLs (playlist?list=). The type is detected automatically. | | `searchQueries` | array | | | Search YouTube and get transcripts of the top Max videos results (videos only) for each query, e.g. how transformers work. | | `maxVideos` | integer | | `10` | How many videos to take from each channel, playlist or search query (newest first for channels). Single video URLs are always included. | | `channelContentType` | string | | `"videos"` | Which uploads to take from a channel. A tab in the channel URL (e.g. /@name/shorts) overrides this. | | `maxTotalVideos` | integer | | `1000` | Upper limit for the whole run, after removing duplicates. | | `languages` | array | | `["en"]` | Language codes in order of preference, e.g. en, es, pt-BR. en also matches en-US/en-GB. Leave empty to always get the video's original (spoken) language. | | `fallbackToAnyLanguage` | boolean | | `true` | If none of the preferred languages exists, return the transcript in the video's original language (manual captions first, then auto-generated). Turn off to get a free no_transcript row instead. | | `autoTranslate` | boolean | | `false` | If no transcript exists in your preferred languages, ask YouTube to machine-translate the original transcript into the first preferred language. If YouTube refuses the translation, the original language is returned and translationError is set. | | `preferManualCaptions` | boolean | | `true` | Pick creator-uploaded captions over auto-generated (ASR) ones in the same language. | | `skipAutoGenerated` | boolean | | `false` | Ignore auto-generated captions. Videos with only auto-generated captions get a free no_transcript row. | | `outputFormats` | array | | `["text", "segments"]` | Which transcript formats to include in each row. Every format is included in the same price. | | `chunkSize` | integer | | `2000` | Only for the RAG chunks format. Chunks follow caption boundaries (no cut words). 2,000 characters ≈ 400-500 tokens. | | `chunkOverlap` | integer | | `200` | Text repeated from the end of one chunk at the start of the next. | | `includeDescription` | boolean | | `true` | Add the video description and chapters (parsed from description timestamps). | | `proxyConfiguration` | object | | `{"useApifyProxy": true}` | Defaults to Apify datacenter proxy with automatic residential fallback when YouTube asks to 'confirm you're not a bot'. Choose the RESIDENTIAL group to always use residential IPs. | | `residentialFallback` | boolean | | `true` | Retry blocked requests on residential IPs. Recommended - this is what keeps the success rate high. | | `reliabilityFallback` | boolean | | `true` | If YouTube blocks or rate-limits a video (bot check, HTTP 429, empty caption file), fetch its subtitles from a licensed backup source instead of returning an error. Charged at the normal transcript price; no extra cost to you. | | `maxConcurrency` | integer | | `20` | Videos processed in parallel. | | `maxRetries` | integer | | `6` | Each blocked request is retried on a new IP, with backoff. | | `videoUrl` | string | | | Single video URL, same as videoUrl in pintostudio/youtube-transcript-scraper. Added to the URL list. | | `targetLanguage` | string | | | Same as targetLanguage in pintostudio/youtube-transcript-scraper (e.g. en, es). Overrides Languages and turns on auto-translate. | | `youtube_url` | string | | | Same as youtube_url in starvibe/youtube-video-transcript. Added to the URL list. | | `channel_url` | string | | | Same as channel_url in starvibe/youtube-video-transcript. Added to the URL list. | | `language` | string | | | Same as language in starvibe/youtube-video-transcript. Overrides Languages. | | `max_videos` | integer | | | Same as max_videos in starvibe/youtube-video-transcript. Overrides Max videos per channel / playlist / search. | | `start_date` | string | | | YYYY-MM-DD. Only videos published on or after this date are returned (others are skipped and not charged). | | `end_date` | string | | | YYYY-MM-DD. Only videos published on or before this date are returned (others are skipped and not charged). | | `include_transcript_text` | boolean | | | Accepted so starvibe/youtube-video-transcript inputs work unchanged. Use Output formats to choose what is returned. | ## Example input ```json { "urls": [ "https://www.youtube.com/watch?v=jNQXAC9IVRw" ], "maxVideos": 1, "channelContentType": "videos", "maxTotalVideos": 1000, "languages": [ "en" ], "fallbackToAnyLanguage": true, "autoTranslate": false, "preferManualCaptions": true, "skipAutoGenerated": false, "outputFormats": [ "text", "segments" ], "chunkSize": 2000, "chunkOverlap": 200, "includeDescription": true, "proxyConfiguration": { "useApifyProxy": true }, "residentialFallback": true, "maxConcurrency": 20, "maxRetries": 6 } ``` ## Output fields One flat row per result: | Field | Type | Description | |---|---|---| | `videoId` | string | YouTube video ID | | `url` | string | Video URL | | `status` | string | ok, no_transcript, no_videos or error (only ok rows are charged) | | `noTranscriptReason` | string | no_captions, language_not_available, only_auto_generated, video_unavailable, private_video, age_restricted, members_only, geo_restricted, live_not_started, login_required | | `error` | string | Error or YouTube message | | `title` | string | Video title | | `channelName` | string | Channel name | | `channelId` | string | Channel ID (UC...) | | `channelUrl` | string | Channel URL | | `publishDate` | string | Publish date (ISO 8601 with offset) | | `durationSeconds` | integer | Duration in seconds | | `duration` | string | Duration (m:ss or h:mm:ss) | | `viewCount` | integer | View count | | `category` | string | YouTube category | | `isLive` | boolean | Live stream / was live | | `isUnlisted` | boolean | Unlisted video | | `description` | string | Video description | | `chapters` | array | Chapters from description timestamps [{start, title}] | | `language` | string | Transcript language code | | `languageName` | string | Transcript language name | | `originalLanguage` | string | Spoken (original) language | | `languageMatch` | string | preferred = one of your languages, original = fallback to the original language | | `isAutoGenerated` | boolean | Auto-generated (ASR) captions | | `isTranslated` | boolean | Machine-translated by YouTube (autoTranslate) | | `translatedFrom` | string | Source language of a translation | | `translationError` | string | Why auto-translation failed (original returned) | | `transcriptAvailable` | boolean | A transcript was returned | | `text` | string | Full transcript as plain text | | `wordCount` | integer | Words in the transcript | | `segmentCount` | integer | Number of caption segments | | `segments` | array | [{start, end, text}] in seconds | | `timestampedText` | string | Transcript as [m:ss] lines | | `srt` | string | SRT subtitles | | `vtt` | string | WebVTT subtitles | | `chunks` | array | RAG chunks [{index, text, start, end, url, chars}] | | `availableLanguages` | array | All caption tracks [{code, name, isAutoGenerated}] | | `source` | string | Input this video came from | | `sourceType` | string | video, channel, playlist or search | | `scrapedAt` | string | Scrape time (UTC) | ## Notes - Auth: an Apify API token as `Authorization: Bearer `; the MCP server also supports OAuth sign-in. - Failed or empty results are not charged on most tools; check the pricing on the Store page. - Questions: hello@wrenfielddata.com --- # AI Search Index 2026-W43 (2026-10-22) https://wrenfielddata.com/ai-search-index/2026-w43/ (CSV: https://wrenfielddata.com/ai-search-index/2026-w43/ai-search-index-2026-w43-brands.csv). CC BY 4.0. - HubSpot is named in 100% of CRM software answers (95% CI 86.2–100%). - QuickBooks is named in 100% of Accounting software answers (95% CI 86.2–100%). - Wix is named in 100% of Website builders answers (95% CI 86.2–100%). - In 5 of 10 categories the four engines do not agree on a top pick. - 69% of citations point to third-party sites (reviews, media, forums), not to the vendors themselves. - The most-cited domain across all answers is zapier.com (51 of 231 answers). - CRM software: HubSpot 100%, Zoho CRM 100%, Pipedrive 70.8%, Salesforce 62.5%, Freshsales 25%, monday CRM 20.8% - Project management software: Asana 95.7%, ClickUp 82.6%, monday.com 82.6%, Trello 69.6%, Jira 43.5%, Wrike 39.1% - Email marketing software: MailerLite 71.4%, Klaviyo 66.7%, Brevo 66.7%, Mailchimp 47.6%, ActiveCampaign 42.9%, Kit 42.9% - Accounting software: QuickBooks 100%, Xero 91.7%, FreshBooks 91.7%, Wave 87.5%, Zoho Books 83.3%, Sage 20.8% - Help desk software: Freshdesk 81.8%, Intercom 68.2%, Zendesk 68.2%, Help Scout 63.6%, Zoho Desk 54.5%, Gorgias 31.8% - SEO tools: Semrush 95.5%, Ahrefs 81.8%, SE Ranking 72.7%, Google Search Console 63.6%, Mangools 40.9%, Screaming Frog 31.8% - AI coding assistants: GitHub Copilot 95.7%, Cursor 91.3%, Claude Code 87%, Windsurf 47.8%, Devin 30.4%, OpenAI Codex 30.4% - Payroll & HR software: Gusto 91.7%, Rippling 75%, Deel 58.3%, ADP 50%, OnPay 45.8%, QuickBooks Payroll 33.3% - Website builders: Wix 100%, Squarespace 95.8%, Shopify 75%, Webflow 66.7%, Hostinger 54.2%, WordPress 50% - Ecommerce platforms: Shopify 91.7%, BigCommerce 66.7%, WooCommerce 62.5%, Etsy 33.3%, Wix 33.3%, Payhip 25%