Google Maps Website Lead Scorer avatar

Google Maps Website Lead Scorer

Pricing

from $0.25 / 1,000 website lead records

Go to Apify Store
Google Maps Website Lead Scorer

Google Maps Website Lead Scorer

Post-process Google Maps Scraper datasets and local business lists. Extract visible emails, phones and social links, score each lead, and output CRM/n8n-ready records with offers, sales angles and next actions.

Pricing

from $0.25 / 1,000 website lead records

Rating

0.0

(0)

Developer

Mathieu

Mathieu

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Turn Google Maps business datasets into enriched, prioritized lead records.

More than an email finder. Extract visible contacts from business websites, then layer on commercial signals, priority scores, and CRM-ready notes. No AI. No API keys. No email sending.

Not a Google Maps scraper. This Actor analyzes websites you already have, from a Google Maps Scraper run, a CSV export, or a direct URL list. It does not touch Google Maps itself.


Quick start

Pick the scenario that matches your input and run the Actor. All three produce the same output format.

Scenario 1: I have a list of websites

Paste URLs directly. No scraper needed.

{
"urls": [
"https://northside-plumbing.com",
"https://brightdental.co.uk",
"https://greenleaf-restaurant.com"
],
"categoryHint": "plumber",
"languageHint": "en"
}

Key fields to check: public_emails_csv, public_phones_csv, lead_priority_score, workflow_action


Scenario 2: I have business objects from a local business dataset

Pass objects that include a website field and optionally a name, category, or city. Field names are auto-detected. Items without a website URL produce a skipped record with workflow_action: find_website - never silently dropped.

{
"items": [
{
"business_name": "Northside Plumbing",
"website": "https://northside-plumbing.com",
"category": "plumber",
"city": "Chicago"
},
{
"title": "Bright Dental Studio",
"url": "https://brightdental.co.uk"
}
],
"categoryHint": "plumber",
"languageHint": "en"
}

Key fields to check: workflow_action, lead_segment, sales_priority_label, recommended_offer, crm_note


Scenario 3: I have an Apify dataset from Google Maps Scraper

Pass the dataset ID from any Google Maps Scraper run. Field names are auto-detected.

{
"datasetId": "YOUR_DATASET_ID_HERE",
"maxItems": 200,
"categoryHint": "restaurant",
"languageHint": "en"
}

Running locally? Set APIFY_TOKEN before running python run_local.py. On the Apify platform it is set automatically.

Custom field names? If your dataset uses a non-standard field for the website URL (e.g. homepage instead of website), set datasetWebsiteField: "homepage". Same for business name with datasetNameField.

Key fields to check: workflow_action, lead_segment, outreach_ready, manual_review_recommended

After the run, start with workflow_action: send_to_crm for ready leads, manual_review for uncertain records, find_website for missing websites, enrich_later for low-priority leads. Use sales_priority_label (hot/warm/cold/invalid) for colour-coding in Google Sheets.

See docs/EXAMPLE_RUN_LOCAL_BUSINESS.md for a full end-to-end walkthrough with a 100-plumber dataset.


Contents


What this Actor does

You already have a list of local businesses, from a Google Maps Scraper run, a CSV export, or a direct URL list. This Actor fetches each business website (static HTML only), analyzes it for commercial signals, and returns a scored, enriched dataset ready for your CRM or no-code workflow.

This Actor extracts visible emails, phone numbers and social links from business websites, then scores and prioritizes each lead. Your team sees who to call first and what to say.

For each business you get:

Contact extraction:

  • Visible emails: extracted from public HTML, deduplicated, CSV-ready
  • Phone numbers: FR and international formats, CSV-ready
  • Social profile links: Facebook, Instagram, LinkedIn, YouTube and more, CSV-ready
  • Primary contact method: phone, email, phone_and_email, contact_form, or none
  • Website status: reachable, unreachable, error, redirected
  • CMS detected: WordPress, Wix, Squarespace, Shopify, and more

Lead prioritization:

  • Lead priority score (0-100): who to contact first
  • Website quality score (0-100): how complete and trustworthy the site is
  • Conversion leaks: what is missing (no booking, no form, no phone, no HTTPS...)
  • Recommended offer: the best service to pitch this business
  • Sales angle: a ready-to-use conversation opener
  • CRM note: pre-written, paste directly into HubSpot or Pipedrive
  • Next action: what your SDR should do with this lead
  • CSV-compatible fields: all array fields available as comma-separated strings

Every input item produces exactly one output record, including unreachable or broken sites.


What this Actor does NOT do

  • Does not scrape Google Maps: bring your own list from any scraper or CSV
  • Does not use AI or require any API key: fully deterministic, no LLM calls
  • Does not send emails or contact businesses: analysis only
  • Does not deep-crawl websites: homepage analysis by default; one-hop contact page optional
  • Does not render JavaScript: static HTML only (see Limitations)
  • Does not provide a full SEO audit: commercial conversion signals only
  • Does not guarantee sales: it surfaces opportunities, your team closes them

How this Actor is different

The Apify Store has Google Maps scrapers, email finders, website checkers, and SEO audit tools. This Actor is different from all of those. It is a commercial post-processor designed to run after a Google Maps Scraper and before your CRM or outreach workflow.

AlternativeWhat it gives youWhat this Actor adds
Google Maps ScraperBusiness names, addresses, reviews, phones from MapsFetches each website, extracts contacts, detects gaps, and scores the commercial opportunity
Email finderEmail addresses from websitesPhones and social links too, plus lead_priority_score, recommended_offer, sales_angle, crm_note, next_action
Website checkerSite up/down, response timeCommercial readiness score, conversion leaks, CRM-ready next action for each site
SEO audit toolDetailed technical SEO report (backlinks, keywords, Core Web Vitals)Fast commercial qualification: who to contact first and what to pitch
CRM enrichment toolCompany data from third-party databasesActual analysis of each business website, based on real HTML (not cached records)

Designed for outreach preparation, not automated outreach. Use it after a Google Maps Scraper run. Extract visible contacts, then prioritize who to contact first. Built for agencies, automation freelancers, local SEO teams and growth teams. The output works with Google Sheets, n8n, Make, Airtable, HubSpot or Pipedrive. It does not guarantee sales. It helps you qualify leads faster.

In practice: an email finder returns a flat list of addresses. This Actor returns those contacts plus a commercial score, evidence for each signal, a pitch paragraph, and a paste-ready CRM note for every business in your list.

What makes it different in practice:

  • evidence field: Every output record includes an evidence trace: which keyword triggered booking_found, which path detected the CMS, which button text triggered cta_found. You can verify every score claim without visiting the site manually.
  • outreach_ready flag: Boolean shortcut. true when the site is reachable, has a visible contact method, and scores >= 60. Filter your n8n/Make workflow with one field check.
  • manual_review_recommended flag: true for JS-heavy sites, 403 errors, or sites with no contact info. Automatically routes uncertain leads to a review queue instead of your SDR's inbox.
  • categoryHint: Tell the Actor what type of business you are scoring. Restaurant, dentist, and plumber keywords are detected separately and appended to the sales angle. Scores stay objective; context becomes specific.
  • CRM-ready output: crm_note is paste-ready. next_action is task-ready. CSV variants for every array field. No post-processing formulas needed.

[Google Maps Scraper] apify/google-maps-scraper (any variant)
output dataset
[Google Maps Website Lead Scorer] ← you are here
[Google Sheets / Airtable / n8n / Make / HubSpot / Pipedrive / CSV]

Step 1. Run any Google Maps Scraper on Apify Store. Save the output dataset.
Step 2. Pass the dataset ID (or a JSON export) to this Actor via the datasetId or items input.
Step 3. Get back a scored, enriched, CRM-ready dataset in seconds.


Who is this for

Web agencies

Find local businesses with outdated sites to pitch a redesign, landing page, booking system, or contact form. The lead priority score and recommended offer tell you exactly who to call and what to propose.

Example: You scrape 500 plumbers in Chicago. This Actor identifies the 87 with a reachable site but no booking flow, the top targets for a booking system pitch.

Automation freelancers

You sell n8n, Make, or Zapier setups for lead capture, appointment booking, or CRM integration. This Actor identifies businesses with no form, no booking, or no CRM-ready contact point.

Example: You scrape 200 dentists in Austin. This Actor surfaces the ones with no contact form and no booking. Your pitch: "I can add a patient booking form to your site in a day."

Local SEO agencies

Prioritize prospects with weak meta descriptions, no HTTPS, or incomplete contact pages. The conversion leaks field gives you a ranked list of what is missing for each business.

Example: You scrape 300 restaurants in Manchester. This Actor flags 40 with no meta description, no social links, and no CTA, your entry point for an SEO audit proposal.

Sales and growth teams

Enrich a list of business targets with a priority score and pre-written CRM notes before handing off to SDRs. The output drops directly into HubSpot or Pipedrive via CSV or Apify integration.


Two ways to use this Actor

Way 1: Contact enrichment from business websites

You have a list of local businesses and you want their contact details in a clean, deduplicated CSV.

Run this Actor and export the output dataset as CSV. Use these fields:

FieldWhat you get
business_nameBusiness name
source_websiteInput URL
website_statusWhether the site is reachable
public_emails_csvAll visible emails, comma-separated
public_phones_csvAll visible phones, comma-separated
social_links_csvSocial profile URLs, comma-separated
primary_contact_methodphone, email, phone_and_email, contact_form, or none
cms_detectedWordPress, Wix, Shopify, etc.
analysis_statuscompleted, partial, failed, skipped
data_quality_score0-100 confidence score for this record

This mode is useful when you just need a contact list from a batch of websites: no scoring, no pitching, just extraction.

Way 2: Sales prioritization and CRM-ready recommendations

You want to know not just who to contact, but who to contact first and what to say.

Add these fields to your workflow:

FieldWhat you get
lead_priority_score0-100 opportunity score
priority_levelvery_high, high, medium, low
outreach_readyBoolean: safe to route to outreach immediately
manual_review_recommendedBoolean: route to review queue
conversion_leaksWhat is missing on the site
recommended_offerWhat to pitch this business
sales_angleReady-to-use pitch opening
crm_notePre-written CRM note
next_actionWhat your SDR should do next
evidencePer-signal audit trail

Both ways use the same Actor run and the same output dataset. You choose which fields to use.

Business-ready routing fields

Every record also includes four pre-computed routing fields that let you connect the output to your CRM or no-code workflow without building your own logic:

FieldValuesUse for
sales_priority_labelhot, warm, cold, invalidColour-code rows; filter hot in Google Sheets or CRM
lead_segmentready_to_contact, review_first, low_priority, unreachable, missing_websiteHuman-readable routing bucket for Switch nodes
workflow_actionsend_to_crm, manual_review, enrich_later, skip, find_websiteSingle-field routing: replaces the outreach_ready + manual_review_recommended boolean chain
crm_statusnew_qualified, needs_review, not_ready, invalid_or_unreachableCRM import status label; use as pipeline stage or tag

Example: in n8n, a single Switch node on workflow_action replaces two chained IF nodes and handles all five lead states.


Which fields should I use?

GoalFields to use
Extract contacts onlypublic_emails_csv, public_phones_csv, social_links_csv, primary_contact_method
Find the best leadslead_priority_score, priority_level, outreach_ready
Avoid bad datadata_quality_score, analysis_status, manual_review_recommended
Understand why a lead is interestingconversion_leaks, evidence, score_reasons
Prepare a CRM importcrm_note, next_action, recommended_offer, crm_status
Route leads in one node (n8n/Make)workflow_action: 5 values, no boolean chain needed
Colour-code leads by prioritysales_priority_label: hot, warm, cold, invalid
Route or debug errorsfailure_category, failure_reason

When to use this instead of a simple email finder

If you want...Use this Actor
Emails from a batch of local business websites✓ Extracts visible emails into public_emails_csv
Phone numbers as well as emails✓ Extracts visible phones into public_phones_csv
Social links alongside contact details✓ Detects Facebook, Instagram, LinkedIn, YouTube and more
A single CSV column per contact type✓ Every array field has a parallel _csv variant
To know which leads to call firstlead_priority_score and priority_level
To know what to pitch each leadrecommended_offer, sales_angle, crm_note
To avoid contacting leads with no real opportunityoutreach_ready and manual_review_recommended flags
To use the output in n8n / Make / Google Sheets✓ Flat JSON, CSV fields, no post-processing needed

A simple email finder gives you a list. This Actor gives you a prioritized, pitch-ready list: emails, phones, social links, scores, notes, and next actions, all in one dataset.


Input

At least one of urls, items, or datasetId is required.

ParameterTypeDefaultDescription
urlsstring[][]Direct list of website URLs to analyze
itemsobject[][]Business objects: auto-detects website and name fields
datasetIdstringnullApify dataset ID from a Google Maps Scraper run
datasetWebsiteFieldstringautoOverride field name for website URL in dataset
datasetNameFieldstringautoOverride field name for business name in dataset
maxItemsinteger100Maximum items to process
concurrencyinteger10Concurrent HTTP requests
timeoutPerItemSecondsinteger20Per-site request timeout in seconds
totalTimeoutSecondsinteger300Approximate total run timeout
languageHintstring"en"Keyword language: en or fr
countryHintstringnullISO country code, e.g. "FR" for France
categoryHintstring"generic"Business category: generic, restaurant, plumber, contractor, dentist, clinic, salon, agency
includeContactExtractionbooleantrueExtract visible emails and phone numbers
includeSocialLinksbooleantrueExtract social media profile links
includeContactPageCheckbooleanfalseFollow one contact page link per site
minLeadPriorityScoreinteger0Score threshold: items below are flagged, not dropped

Input example: URL list

{
"urls": [
"https://northside-plumbing.com",
"https://brightdental.co.uk",
"https://greenleaf-restaurant.com"
],
"languageHint": "en",
"maxItems": 100,
"minLeadPriorityScore": 40
}

Input example: Google Maps dataset items

{
"items": [
{
"title": "Northside Plumbing",
"website": "https://northside-plumbing.com",
"phone": "+1 555 234 5678",
"address": "Chicago, IL 60601"
},
{
"businessName": "Bright Dental Studio",
"businessWebsite": "https://brightdental.co.uk",
"phoneNumber": "+44 207 123 4567"
}
],
"languageHint": "en",
"includeContactPageCheck": true,
"minLeadPriorityScore": 30
}

Field names are auto-detected. Supported variants: website, url, website_url, businessWebsite, homepage, site, domain for URLs; name, title, business_name, businessName, company for names.

Input example: dataset ID

{
"datasetId": "aBcDeFgHiJkL1234",
"maxItems": 500,
"concurrency": 15,
"languageHint": "en"
}

Pass the dataset ID from any Google Maps Scraper run. The Actor reads items directly from the dataset without downloading the full export.


Output

Every input item produces exactly one output record, including unreachable sites, failed URLs, and items with no website URL. No records are silently dropped.

Output example: key fields

{
"business_name": "Northside Plumbing",
"source_website": "https://northside-plumbing.com",
"analysis_status": "completed",
"data_quality_score": 80,
"lead_priority_score": 82,
"priority_level": "very_high",
"sales_priority_label": "hot",
"lead_segment": "ready_to_contact",
"workflow_action": "send_to_crm",
"outreach_ready": true,
"manual_review_recommended": false,
"public_emails_csv": "",
"public_phones_csv": "+1 555 234 5678",
"recommended_offer": "booking_system",
"crm_note": "Northside Plumbing: Site reachable, phone visible. No booking or contact form. Recommended: pitch booking_system.",
"next_action": "Contact this week. Very high conversion potential."
}

For the complete record structure, including evidence, score_breakdown, score_reasons, all boolean signals, and failure fields, see docs/OUTPUT_SCHEMA.md. Full example records (reachable, unreachable, partial, and missing-website) are in examples/output_sample.json.


Field reference

See docs/OUTPUT_SCHEMA.md for the complete field reference with all 55+ fields.

Key fields for immediate use:

FieldUse for
public_emails_csv, public_phones_csvContact extraction: paste directly into spreadsheets
social_links_csvSocial profile links: Facebook, Instagram, LinkedIn and more
lead_priority_score (0-100)Sort leads by commercial opportunity
workflow_actionSingle-field routing: send_to_crm, manual_review, enrich_later, skip, find_website
outreach_readyBoolean gate: true when safe to route to automated outreach
manual_review_recommendedBoolean gate: true when a human should verify before outreach
crm_notePaste directly into HubSpot, Pipedrive, or any CRM notes field
next_actionUse as CRM task title
evidencePer-signal audit trail: verify every score claim without visiting the site
analysis_statuscompleted, partial, failed, skipped
failure_reasonMachine-readable failure code for workflow branching

Scoring model

Lead priority score (0-100): Commercial opportunity score. A site that is reachable and contactable but has no booking system or contact form scores high because there is something clear to sell. Measured across contactability (30 pts), commercial gaps (50 pts), and vitality (20 pts). Levels: 0-30 = low, 31-60 = medium, 61-80 = high, 81-100 = very_high.

Website quality score (0-100): How complete and visitor-friendly the site is: HTTPS, title, meta description, visible contacts, contact form, CTA, social links. Bands: poor / weak / average / good.

Conversion leaks: Missing commercial elements on the site: missing_booking, missing_contact_form, missing_email, missing_https, no_social_links, etc. Each leak maps to a recommended_offer for your pitch (booking_system, contact_form_setup, ssl_setup, local_seo, website_rebuild, etc.).

For the full per-signal point table and recommended offer mapping, see docs/SCORING_MODEL.md.


Use with n8n / Make / Google Sheets

Field mapping for CRM and automation

This Actor fieldMap to
priority_levelCRM segment or filter condition
outreach_readyGate for immediate outreach routing
manual_review_recommendedFlag for manual review queue
recommended_offerSales segment or deal type
crm_noteCRM notes field (HubSpot, Pipedrive, Salesforce)
next_actionCRM task title or action item
sales_angleOutreach email body or first message template
public_emails_csvContact email column: no parsing needed
public_phones_csvContact phone column: no parsing needed
top_conversion_leakPrimary pitch anchor
category_specific_signalsIndustry context for personalization
evidenceAudit trail for manual review

n8n workflow

  1. Use the Apify node to trigger this Actor with your URL list or datasetId.
  2. Add an IF node: outreach_ready == true → route to CRM / outreach sequence.
  3. Add a second IF node: manual_review_recommended == true → route to Slack notification or review spreadsheet.
  4. Map crm_note to HubSpot "Notes" or Pipedrive "Description".
  5. Map next_action to a task title.
  6. Map recommended_offer to deal type or pipeline stage.
  7. Map public_phones_csv and public_emails_csv as contact fields. No formula needed.

Make (Integromat) workflow

  1. Use the Apify module to run the Actor and watch the output dataset.
  2. Add a Router module:
    • Branch 1: outreach_ready == true → add to CRM immediately
    • Branch 2: manual_review_recommended == true → send to Slack review channel
    • Branch 3: everything else → nurture list or archive
  3. Map recommended_offer to a deal property to pre-segment your pipeline.
  4. Use priority_level as the CRM score or lead rating field.

Google Sheets / Excel

Export the Apify dataset as CSV. All array fields have parallel _csv string variants:

Array fieldCSV variant
public_emailspublic_emails_csv
public_phonespublic_phones_csv
social_linkssocial_links_csv
conversion_leaksconversion_leaks_csv
score_reasonsscore_reasons_csv

These import cleanly into spreadsheet columns without formula parsing.


Best use cases

Web agency prospecting

Scrape 500 local businesses in your city with Google Maps Scraper. Run this Actor with categoryHint="plumber" (or whatever vertical you serve). Filter by outreach_ready=true and priority_level in (high, very_high). You get a ranked list with pitch text already written.

Automation freelancer lead qualification

You build n8n / Make flows for local businesses. Scrape dentists, lawyers, or restaurants in your region. Filter for top_conversion_leak in (missing_booking, missing_contact_form). These businesses have an obvious automation opportunity you can pitch immediately.

Local SEO opportunity detection

Run on a list of businesses in a niche. Filter for conversion_leaks containing missing_meta_description, missing_https, no_social_links. These are your SEO audit prospects. The evidence.title and evidence.meta_description fields give you talking points for the initial call.

Sales team list prioritization

Your BDR team has 1000 inbound leads but no time to research them all. Run this Actor on the website list. Route outreach_ready=true records to the top of the calling queue. Route manual_review_recommended=true records to a research list for junior staff. Route priority_level=low to the archive.

Freelance web developer client hunting

Look for businesses with cms_detected=wordpress and conversion_leaks containing weak_cta, missing_contact_form. These are WordPress sites with a clear UX gap, your target market for a conversion-focused redesign pitch.


Limitations

JavaScript-rendered sites
This Actor uses static HTML analysis only. Sites built entirely with JavaScript frameworks (React, Vue, Next.js) may return an empty or near-empty HTML shell from the server. When minimal content is detected, a js_heavy_or_low_html_detected warning is added and the js_heavy_or_low_html conversion leak is included. Some signals (emails, phones, forms) may be missing for these sites.

Homepage analysis only
By default, only the homepage is analyzed. Enable includeContactPageCheck to make one additional request to a detected contact page per site. This doubles HTTP request count for sites where a contact link is found.

Phone number formats
Phone extraction is optimized for French (FR) and English (EN/US) formats. Numbers in other formats may not be detected.

Bot-protected sites
Sites behind Cloudflare or similar bot protection may return an error page (e.g. "Just a moment...") instead of real content. These sites receive partial scores based on the error page HTML.

No JavaScript execution
Dynamic content loaded after page render (chat widgets, pop-up contact forms, lazy-loaded CTAs) is not detected.

No authentication
Sites behind login pages or cookie consent walls that hide content cannot be analyzed.

CMS detection
8 platforms are covered: WordPress, Wix, Squarespace, Shopify, Joomla, Drupal, Webflow, Jimdo. Sites on other platforms or custom stacks are reported as cms=unknown.

Security: outbound request restrictions
The Actor blocks outbound requests to private IP ranges (10.x, 172.16.x, 192.168.x), localhost, link-local addresses (169.254.x.x including the cloud metadata endpoint 169.254.169.254), and non-HTTP schemes (file://, ftp://). URLs matching these are returned with website_status=unreachable. This is a deliberate SSRF protection; it cannot be disabled.

No sales guarantee
A high lead_priority_score indicates a detectable conversion gap on the website. It does not guarantee that the business owner will buy, respond, or convert. The scores are signal-based heuristics. Human judgment and qualification are required before any outreach.


User tutorial

A step-by-step guide to using this Actor, from pasting your first URL to filtering results in n8n, is available in docs/USER_TUTORIAL.md. A French version is in docs/USER_TUTORIAL_FR.md.

After your first run, follow the docs/FIRST_RUN_CHECKLIST.md to interpret completed, partial, and failed records and calibrate the scoring for your market.


FAQ

Does it scrape Google Maps?
No. This Actor does not touch Google Maps. It only analyzes websites you provide via urls, items, or datasetId. Use a Google Maps Scraper to collect your list first.

Can I use it after running a Google Maps Scraper?
Yes, that is the primary use case. Pass the scraper's output dataset ID via datasetId, or export as JSON and pass via items. Field names from popular Google Maps scrapers are auto-detected.

Does it find emails and phone numbers?
Yes, if they are visible in the static HTML. Emails and phones hidden in JavaScript, images, or behind login walls cannot be extracted. Enable includeContactPageCheck to check the contact page as well.

Why are public_phones and public_emails empty?
The most common causes: (1) the site renders content with JavaScript (static HTML analysis misses React/Vue/Next.js-embedded contacts); (2) contact details are in images or PDFs; (3) the business has no visible contact info. Enable includeContactPageCheck: true and check manual_review_recommended.

Why is analysis_status partial?
The site was fetched but signals are incomplete, typically because the site is JavaScript-heavy (js_heavy_or_low_html) or is behind bot protection (cloudflare_or_bot_protection). Partial records have valid scores but may be missing emails, phones, and social links.

What does manual_review_recommended: true mean?
The record cannot be safely routed to automated outreach. Main triggers: analysis_status: partial, an HTTP error response, or no visible contact info. Route these to a review queue in n8n or Make. The lead may still be good.

Does it use AI or require any API key?
No. All analysis is keyword-based and deterministic. No API key of any kind is required. No LLM calls.

Does it send outreach messages?
No. This Actor only reads and scores websites. It does not send emails, make calls, or contact businesses.


What happens when a website cannot be analyzed?

Every input item produces exactly one output record. The analysis_status field explains what happened:

analysis_statusMeaning
completedFull analysis (all signals extracted)
partialSite fetched but signals incomplete (JS-heavy, bot-blocked, low HTML)
failedSite unreachable: DNS error, timeout, or HTTP error with no usable HTML
skippedNo URL provided, or URL blocked by security policy

Use workflow_action to route each outcome: send_to_crm, manual_review, enrich_later, skip, or find_website. The failure_reason field is machine-readable for fine-grained branching in n8n or Make.

For the full failure_category and failure_reason code reference, interpretation guide, and calibration tips, see docs/FIRST_RUN_CHECKLIST.md.


Local development

# Install dependencies
pip install -r requirements.txt -r requirements-dev.txt
# Run tests
pytest
# Run locally on a URL list (no Apify account needed)
python3 run_local.py examples/input_urls.json
python3 run_local.py examples/input_items.json
# Run on a custom input inline
python3 run_local.py - '{"urls": ["https://example.com"], "languageHint": "en"}'
# Use datasetId locally - requires APIFY_TOKEN
export APIFY_TOKEN=your_token_here
python3 run_local.py - '{"datasetId": "your_dataset_id"}'

When using datasetId locally, the APIFY_TOKEN environment variable must be set. On the Apify platform, it is set automatically.

See docs/DEVELOPMENT_WORKFLOW.md for the full development guide.