<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Techforce Global</title>
    <description>The latest articles on DEV Community by Techforce Global (@techforce_global).</description>
    <link>https://dev.to/techforce_global</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3791307%2Fe567a47d-83d2-4124-b208-1047cfe838a1.jpg</url>
      <title>DEV Community: Techforce Global</title>
      <link>https://dev.to/techforce_global</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/techforce_global"/>
    <language>en</language>
    <item>
      <title>Build a LinkedIn Candidate Shortlist in Python Without a LinkedIn Cookie</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Thu, 24 Sep 2026 12:05:59 +0000</pubDate>
      <link>https://dev.to/techforce_global/build-a-linkedin-candidate-shortlist-in-python-without-a-linkedin-cookie-1je8</link>
      <guid>https://dev.to/techforce_global/build-a-linkedin-candidate-shortlist-in-python-without-a-linkedin-cookie-1je8</guid>
      <description>&lt;p&gt;If you've ever been asked to "just pull a list of senior Java devs in Pune" for the hiring team, this post is for you. We'll build a candidate shortlist from public LinkedIn profiles in about 15 lines of Python, with &lt;strong&gt;no LinkedIn account, no cookie and no li_at token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We'll use &lt;a href="https://scraper.techforce.global/actors/linkedin-candidate-search" rel="noopener noreferrer"&gt;LinkedIn Candidate Search (No Cookies)&lt;/a&gt;, an Apify Actor we built at Techforce Global. It composes the X-ray search query for you, runs it through Brave Search and returns structured results.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install the client
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;apify-client
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Describe the role and run it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;techforce.global/linkedin-candidate-search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job_role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Java Developer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seniority&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Senior&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Spring Boot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Kafka&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exclude_keywords&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recruiter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intern&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pune&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mumbai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_profiles&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deliveryMode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;list_items&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Read the results
&lt;/h2&gt;

&lt;p&gt;Each item has four fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aditi Ranganathan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Senior Java Developer at FinServe Systems"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"profile_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://in.linkedin.com/in/aditi-ranganathan-1a2b3c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"snippet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Senior Java Developer with 8 years building Spring Boot microservices..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;snippet&lt;/code&gt; is your best relevance signal, so filter on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;strong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kafka&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;profile_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gotchas worth knowing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Always set a search signal.&lt;/strong&gt; Set at least one of &lt;code&gt;job_role&lt;/code&gt;, &lt;code&gt;technologies&lt;/code&gt; or &lt;code&gt;keywords&lt;/code&gt;. With none, the Actor falls back to a default query and you get unrelated results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max 50 per run&lt;/strong&gt; (5 on free plans). For more, loop by city or seniority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The query is capped at 450 characters.&lt;/strong&gt; Very long tech lists get cut. Keep briefs tight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedupe on &lt;code&gt;profile_url&lt;/code&gt;&lt;/strong&gt; across runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No emails or phone numbers.&lt;/strong&gt; It's search-result depth by design.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: call it from an AI agent
&lt;/h2&gt;

&lt;p&gt;It's a native MCP tool, so you can add it to Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http apify &lt;span class="s2"&gt;"https://mcp.apify.com?tools=techforce.global/linkedin-candidate-search"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just ask: &lt;em&gt;"Find 20 senior React developers in Bangalore, no recruiters."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Full input reference, JavaScript and cURL examples: &lt;strong&gt;&lt;a href="https://scraper.techforce.global/actors/linkedin-candidate-search" rel="noopener noreferrer"&gt;LinkedIn Candidate Search (No Cookies) - Talent Sourcing API&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>automation</category>
      <category>recruiting</category>
    </item>
    <item>
      <title>Building a Finance Lead Pipeline with the Google Maps Lead Scraper API</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 09 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/techforce_global/building-a-finance-lead-pipeline-with-the-google-maps-lead-scraper-api-2n37</link>
      <guid>https://dev.to/techforce_global/building-a-finance-lead-pipeline-with-the-google-maps-lead-scraper-api-2n37</guid>
      <description>&lt;p&gt;This actor covers 28 finance business types, five optional intelligence blocks, and MCP delivery into six different destination apps enough surface area that a proper API walkthrough is worth more than the standard input/output table. This post covers a real Python integration, the MCP connector delivery modes, and the specific execution rules worth knowing before you build a production pipeline on top of it.&lt;/p&gt;

&lt;p&gt;The gap between reading the README and building a working pipeline usually comes down to a handful of quiet behaviours that don't show up until a run returns something unexpected a silent fallback here, an omitted field there. This post front-loads those specifically, since they're the difference between a pipeline that works the first time and one that needs a debugging session to figure out why results look wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;Standard &lt;strong&gt;Apify&lt;/strong&gt; bearer token auth applies for direct API calls available from Settings → Integrations in your Apify account. No target-site credentials are needed at all; the actor reads only public Google Maps listings and public website content, so there's no separate authentication layer for the data source itself, unlike the official Google Places API, which requires a GCP project and a billing-enabled key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Input configuration the essentials
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdm4dsnzmwl7sqdbplbye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdm4dsnzmwl7sqdbplbye.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Error handling the codes worth checking for explicitly
&lt;/h2&gt;

&lt;p&gt;This actor documents its own error/condition matrix in unusual detail, which is worth taking advantage of directly in your integration code rather than treating every non-success as a generic failure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SILENT_DEFAULT - results are CA Firms in London you never asked for, because no field is required and both defaulted. Always pass subcategories and location explicitly to avoid this entirely.&lt;/li&gt;
&lt;li&gt;CAP_REACHED - itemCount equals maxResults equals 100, meaning the per-run ceiling truncated results. Partition larger jobs across sequential runs.&lt;/li&gt;
&lt;li&gt;FREE_PLAN_CAP - itemCount caps at 10 with an upgrade banner in the log. This is a successful run, not a failure worth distinguishing in your monitoring so it doesn't trigger a false alert.&lt;/li&gt;
&lt;li&gt;EMPTY_RESULTS - status SUCCEEDED with itemCount 0. Also not a failure it means the business type and location combination genuinely had no Google Maps matches.&lt;/li&gt;
&lt;li&gt;DELIVERY_SKIPPED an MCP connector was set but mcpTool was left empty, so the delivery step is skipped with a warning while the dataset is still written in full.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running it Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
from apify_client import ApifyClient

client = ApifyClient(os.getenv('APIFY_TOKEN'))

run = client.actor('techforce.global/finance-google-maps-lead-scraper').call(run_input={
    'subcategories': ['CA Firm', 'Accounting Firm', 'Tax Consultant'],
    'location': 'London',
    'maxResults': 90,
    'includeLeadOverview': True,
    'includeWebsiteHealthScorecard': True,
    'includeServiceRecommendations': True,
    'includeTechnicalIntel': False,
    'deliveryMode': 'none',
})

items = client.dataset(run['defaultDatasetId']).list_items().items
firms = [i for i in items if i.get('businessName')]

weak_sites = [
    i for i in firms
    if i.get('WEBSITE_HEALTH_SCORECARD', {}).get('finalGrade') in {'C', 'D', 'F'}
]
print(f'{len(weak_sites)} firms with a weak website — best prospects')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Execution rules that will bite you if skipped
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nothing is required. An empty input {} silently scrapes 'CA Firm in London' rather than raising an error — always pass subcategories, location, and maxResults explicitly from API or MCP calls&lt;/li&gt;
&lt;li&gt;subcategories values must match the 28-item enum exactly — 'ca firm' (lowercase) or an unlisted type like 'Hedge Fund' gets logged as a warning and skipped; if every value is invalid, the actor silently falls back to 'CA Firm'&lt;/li&gt;
&lt;li&gt;Empty fields are omitted from each item, not set to null — always check key presence ("website" in item), never compare to None&lt;/li&gt;
&lt;li&gt;A missing email is the literal string "NA", not an empty value — check emailStatus first (ok / no_email_found / failed / no_website)&lt;/li&gt;
&lt;li&gt;maxResults is split evenly across every selected business type — 10 types with maxResults: 100 gives roughly 10 practices each, not 100 each&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fene0f8w077u9qpmmjg7e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fene0f8w077u9qpmmjg7e.jpg" alt="Finance lead scraper API output example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP connector delivery pushing straight to Slack
&lt;/h2&gt;

&lt;p&gt;This actor supports four delivery modes: summary (one digest call), chunked (split across calls for long lists), perLead (one call per practice), or none. Setting up a Slack digest for every run looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "subcategories": ["Insurance Broker", "Life Insurance Agency"],
  "location": "Manchester",
  "maxResults": 60,
  "mcpConnector": "&amp;lt;your-authorized-slack-connector&amp;gt;",
  "deliveryMode": "summary",
  "mcpTool": "send_message",
  "mcpArguments": { "channel": "#finance-leads", "text": "{message}" },
  "mcpMessageTemplate": "{leadCount} {subcategories} leads in {location}:\n\n{leads}"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a long lead list going into Notion specifically, chunked mode groups lead lines into parts under roughly 72,000 characters each, so services with per-request size limits Notion in particular never reject the call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a delivery mode for the right use case
&lt;/h2&gt;

&lt;p&gt;Summary mode makes sense for a scheduled digest one message per run, listing every lead found. Chunked mode exists specifically for services with strict per-request size limits, splitting a long lead list into numbered parts. PerLead mode fires one connector call per individual practice, which is the right choice for pushing directly into CRM records but risks connector rate limits on a large batch a 100-practice run in perLead mode against a rate-limited service is a common source of dropped calls, worth testing on a small batch before scaling up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What's the fastest way to get a contacts-only run?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Set all five include* toggles to false this skips the website crawl and audit entirely and returns just the base practice profile.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I avoid overspending on a large automated run?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Pass maxTotalChargeUsd as a query parameter on the run endpoint for a hard per-execution spend ceiling important for any pipeline running unattended.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did my run return fewer items than maxResults?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;This is expected the budget splits across business types, duplicate listings are removed, and Google may simply have fewer matches for that type/location combination than requested.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I search more than 100 practices in one call?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;No 100 is a hard per-run ceiling. Partition by city or business-type group across sequential runs and merge on googleMapsUrl&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Full documentation and the interactive input schema: &lt;br&gt;
&lt;strong&gt;&lt;a href="https://apify.com/techforce.global/finance-google-maps-lead-scraper" rel="noopener noreferrer"&gt;Finance Google Maps Lead Intelligence Scraper&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>automation</category>
      <category>python</category>
      <category>mcp</category>
    </item>
    <item>
      <title>The Engineering Case for AI in Europe's Trucking Industry</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 09 Sep 2026 09:32:53 +0000</pubDate>
      <link>https://dev.to/techforce_global/the-engineering-case-for-ai-in-europes-trucking-industry-528o</link>
      <guid>https://dev.to/techforce_global/the-engineering-case-for-ai-in-europes-trucking-industry-528o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fro8wnj9o3ugvdqyzslk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fro8wnj9o3ugvdqyzslk5.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conversation around Europe's truck driver shortage often focuses on recruitment. That makes sense, but it leaves out an important part of the problem: the amount of operational work surrounding every driver.&lt;/p&gt;

&lt;p&gt;Dispatchers answer calls. Drivers provide status updates. Customers request delivery information. Recruiters process applications. Operations teams coordinate schedules and handle exceptions.&lt;/p&gt;

&lt;p&gt;Much of this work is repetitive and predictable.&lt;/p&gt;

&lt;p&gt;That makes logistics an interesting environment for applied AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Think in Workflows, Not Chatbots
&lt;/h2&gt;

&lt;p&gt;A useful AI system for a transport company should not exist simply to answer questions.&lt;/p&gt;

&lt;p&gt;It should be connected to a workflow.&lt;/p&gt;

&lt;p&gt;Consider a driver calling to report a delayed loading appointment. A basic chatbot might provide a generic response. A properly integrated AI voice agent could identify the driver, understand the shipment context, capture the delay, update the appropriate system through an API, and escalate the issue when a human decision is required.&lt;/p&gt;

&lt;p&gt;The difference is significant.&lt;/p&gt;

&lt;p&gt;The first system produces conversation. The second completes work.&lt;/p&gt;

&lt;p&gt;This distinction should guide how logistics companies evaluate AI projects.&lt;/p&gt;

&lt;p&gt;For a broader look at how AI can address operational pressures associated with Europe's driver shortage, see &lt;strong&gt;&lt;a href="https://techforceglobal.com/ai-truck-driver-shortage-europe/" rel="noopener noreferrer"&gt;AI and Europe's truck driver shortage&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Voice Interfaces Make Sense
&lt;/h2&gt;

&lt;p&gt;A traditional software interface assumes that the user can stop what they are doing and interact with a screen.&lt;/p&gt;

&lt;p&gt;A driver often cannot.&lt;/p&gt;

&lt;p&gt;That makes voice a compelling interface for specific logistics tasks.&lt;/p&gt;

&lt;p&gt;Drivers can provide updates verbally while keeping their attention on the job. AI can convert the conversation into structured information and pass it into the relevant workflow.&lt;/p&gt;

&lt;p&gt;Potential use cases include:&lt;/p&gt;

&lt;p&gt;Delivery status updates&lt;br&gt;
Appointment changes&lt;br&gt;
Basic dispatch enquiries&lt;br&gt;
Driver check-ins&lt;br&gt;
Customer delivery notifications&lt;br&gt;
Recruitment screening and scheduling&lt;/p&gt;

&lt;p&gt;Not every task is appropriate for voice automation. The key is choosing interactions where conversation is already the natural method of communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Collection Is Another Opportunity
&lt;/h2&gt;

&lt;p&gt;AI automation becomes more effective when businesses have clean, structured information.&lt;/p&gt;

&lt;p&gt;Recruitment provides a simple example. Transport companies need information such as driving experience, licence details, availability, location, and contact information. Collecting that information consistently can reduce unnecessary back-and-forth.&lt;/p&gt;

&lt;p&gt;AI can then operate around that structured information rather than trying to interpret scattered emails and documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration Is the Hard Part
&lt;/h2&gt;

&lt;p&gt;The most impressive AI demo can still fail when it reaches production.&lt;/p&gt;

&lt;p&gt;A logistics AI system may need to communicate with transportation management systems, CRM platforms, scheduling tools, telephony providers, databases, and internal applications.&lt;/p&gt;

&lt;p&gt;That introduces familiar engineering concerns: authentication, API reliability, permissions, monitoring, error handling, logging, and data security.&lt;/p&gt;

&lt;p&gt;It also creates an important architectural principle: an AI agent should have only the access it needs to perform its assigned task.&lt;/p&gt;

&lt;p&gt;For example, an agent responsible for appointment scheduling does not necessarily need unrestricted access to fleet or financial systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human Escalation Should Be Designed In
&lt;/h2&gt;

&lt;p&gt;Automation works best when its boundaries are explicit.&lt;/p&gt;

&lt;p&gt;If an AI agent encounters an unusual delivery issue, a safety concern, a dispute, or a request outside its permissions, it should know when to stop and involve a person.&lt;/p&gt;

&lt;p&gt;Good escalation design is not a weakness. It is part of production-grade automation.&lt;/p&gt;

&lt;p&gt;The objective is to remove repetitive work while preserving human control over decisions that require judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Starting Point
&lt;/h2&gt;

&lt;p&gt;Companies considering AI should resist the temptation to launch a huge transformation program immediately.&lt;/p&gt;

&lt;p&gt;Choose one workflow with high transaction volume and measurable friction.&lt;/p&gt;

&lt;p&gt;Automate it. Integrate it with the existing systems. Monitor the results. Then improve the workflow based on real usage.&lt;/p&gt;

&lt;p&gt;For Europe's logistics sector, AI will not solve the driver shortage by itself. But it can reduce the administrative burden surrounding drivers, help operations teams work more efficiently, and make limited human capacity go further.&lt;/p&gt;

&lt;p&gt;That is a much more practical, and ultimately more valuable definition of AI adoption.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>logistics</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building AI Voice Agents for European Businesses: What Actually Matters</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 26 Aug 2026 19:12:46 +0000</pubDate>
      <link>https://dev.to/techforce_global/building-ai-voice-agents-for-european-businesses-what-actually-matters-4935</link>
      <guid>https://dev.to/techforce_global/building-ai-voice-agents-for-european-businesses-what-actually-matters-4935</guid>
      <description>&lt;p&gt;AI voice technology has moved beyond simple IVR replacement.&lt;/p&gt;

&lt;p&gt;Today's voice agents can understand natural language, maintain conversational context, connect with APIs, and trigger business workflows. That creates interesting possibilities for European companies but building a useful voice agent requires considerably more than connecting a speech model to a phone number.&lt;/p&gt;

&lt;p&gt;The engineering decisions behind the system often determine whether the result becomes a reliable business tool or an impressive demo that fails in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start With the Workflow, Not the Model
&lt;/h3&gt;

&lt;p&gt;A common mistake is choosing an AI model first and then searching for a problem it can solve.&lt;/p&gt;

&lt;p&gt;A better approach is to map the workflow.&lt;/p&gt;

&lt;p&gt;Consider appointment scheduling. The system needs to understand what the caller wants, collect the required information, check availability, book the appointment, confirm the details, and handle exceptions.&lt;/p&gt;

&lt;p&gt;The language model is only one component.&lt;/p&gt;

&lt;p&gt;A production architecture may also require speech-to-text, text-to-speech, authentication, business APIs, databases, observability, access controls, and escalation logic.&lt;/p&gt;

&lt;p&gt;The business workflow should therefore define the architecture not the other way around.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrations Are Where Voice AI Becomes Useful
&lt;/h3&gt;

&lt;p&gt;A voice agent that can only answer general questions has limited operational value.&lt;/p&gt;

&lt;p&gt;The real advantage appears when it can interact with existing systems.&lt;/p&gt;

&lt;p&gt;For example, a customer might call a logistics company to ask about a delivery. The agent could authenticate the customer, retrieve shipment information through an API, explain the current status, and create a support ticket if something has gone wrong.&lt;/p&gt;

&lt;p&gt;That requires reliable integration between the conversational layer and backend systems.&lt;/p&gt;

&lt;p&gt;For teams evaluating the broader use cases, this overview of &lt;strong&gt;&lt;a href="https://techforceglobal.com/ai-voice-agents-european-businesses/" rel="noopener noreferrer"&gt;AI voice agents for European businesses&lt;/a&gt;&lt;/strong&gt; offers useful context around where conversational automation can fit into business operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Europe Adds Another Engineering Layer
&lt;/h3&gt;

&lt;p&gt;European deployments introduce additional considerations around privacy, security, language support, and regulatory requirements.&lt;/p&gt;

&lt;p&gt;A voice system may need to support several languages and regional accents while maintaining consistent intent detection. At the same time, organizations need to understand where conversation data is processed, how long it is retained, and which systems the agent can access.&lt;/p&gt;

&lt;p&gt;This makes data architecture especially important.&lt;/p&gt;

&lt;p&gt;Sensitive information should not simply flow through every component of the application. Permissions should be scoped to specific tasks, and important actions should be logged for auditing and troubleshooting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design for Failure From Day One
&lt;/h3&gt;

&lt;p&gt;Voice conversations are unpredictable.&lt;/p&gt;

&lt;p&gt;Customers interrupt. They change their minds. Background noise affects transcription. APIs fail. A caller may provide incomplete information or ask something outside the system's defined capabilities.&lt;/p&gt;

&lt;p&gt;Production voice agents therefore need graceful failure paths.&lt;/p&gt;

&lt;p&gt;Instead of guessing, the agent should be able to clarify the request, retry an operation, or transfer the conversation to a human.&lt;/p&gt;

&lt;p&gt;Human escalation is particularly important for complex or sensitive interactions. The handoff should also preserve relevant conversation context so the customer does not have to explain everything again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measure Business Outcomes, Not Just Conversation Quality
&lt;/h3&gt;

&lt;p&gt;A voice agent can achieve impressive language-model evaluation scores and still provide little business value.&lt;/p&gt;

&lt;p&gt;Engineering teams should track operational metrics such as task completion rate, successful transfers, average handling time, escalation frequency, booking accuracy, API failure rates, and customer drop-off.&lt;/p&gt;

&lt;p&gt;These measurements reveal whether the system is actually improving the process.&lt;/p&gt;

&lt;p&gt;For example, reducing average call duration is not necessarily positive if more customers require repeat calls. Likewise, increasing automation rates may be counterproductive if customers cannot reach a human when they need one.&lt;/p&gt;

&lt;p&gt;The right metrics depend on the workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Narrow, Then Expand
&lt;/h3&gt;

&lt;p&gt;The strongest approach is usually to start with one clearly defined use case.&lt;/p&gt;

&lt;p&gt;Appointment scheduling, order-status enquiries, candidate screening, reservation management, or basic customer support can provide controlled environments for testing.&lt;/p&gt;

&lt;p&gt;Once the system performs reliably, additional workflows can be introduced.&lt;/p&gt;

&lt;p&gt;This incremental approach makes it easier to evaluate accuracy, security, integration reliability, and user experience without turning the first deployment into an unnecessarily complex platform.&lt;/p&gt;

&lt;p&gt;AI voice agents are ultimately less about making phone conversations sound intelligent and more about connecting natural language with dependable software systems.&lt;/p&gt;

&lt;p&gt;For European businesses, that means combining conversational AI with thoughtful architecture, secure integrations, clear operational boundaries, and human oversight. When those pieces work together, voice automation becomes more than a chatbot on a phone it becomes another interface to the business itself.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>From Google Maps to a Sales Pipeline: How I Realized Scraping Was the Easy Part</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:54:29 +0000</pubDate>
      <link>https://dev.to/techforce_global/from-google-maps-to-a-sales-pipeline-how-i-realized-scraping-was-the-easy-part-2313</link>
      <guid>https://dev.to/techforce_global/from-google-maps-to-a-sales-pipeline-how-i-realized-scraping-was-the-easy-part-2313</guid>
      <description>&lt;p&gt;A build story for the &lt;a href="https://apify.com/techforce.global/google-maps-leads-sales-intelligence-tool" rel="noopener noreferrer"&gt;Google Maps Business Leads Scraper &amp;amp; Sales Intelligence&lt;/a&gt; Actor&lt;/p&gt;

&lt;p&gt;When I first started working on this Actor, the idea was actually pretty simple.&lt;/p&gt;

&lt;p&gt;I wanted to build a Google Maps scraper that could help us find businesses and collect their basic information: business name, address, phone number, website, Google rating, reviews.&lt;/p&gt;

&lt;p&gt;Nothing too complicated. And it worked.&lt;/p&gt;

&lt;p&gt;But after looking at the output, I had the same thought I've had with a lot of scraping projects: okay, I have the data, now what?&lt;/p&gt;

&lt;p&gt;A salesperson doesn't need another CSV with 500 business names. They need to know which businesses are worth contacting, why they should contact them, and ideally, they shouldn't have to spend three hours opening websites one by one to figure that out.&lt;/p&gt;

&lt;p&gt;That was the point where this stopped being a Google Maps scraper for me. I wanted to turn it into a lead intelligence tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: manual research is where the time disappears
&lt;/h2&gt;

&lt;p&gt;The original problem was manual effort. A salesperson might start with something as simple as "search for resorts in Los Angeles." Then comes the actual work open Google Maps, check the business, open the website, find an email, check whether the website is actually good, look for SEO problems, look for technical problems, try to understand what service could be sold to that business, then decide whether the lead is worth contacting. Repeat for dozens or hundreds of businesses.&lt;/p&gt;

&lt;p&gt;Scraping is the easy part. The manual research after scraping is where the time disappears. So I started asking whether the Actor could do more of that work automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first version was just a Google Maps scraper
&lt;/h2&gt;

&lt;p&gt;I started with the basic version: search Google Maps → collect businesses → return structured data. That proved the idea worked, but there was nothing special about it. There are already loads of Google Maps scrapers on Apify I didn't want to build another one just because I could.&lt;/p&gt;

&lt;p&gt;So instead of asking "how can I scrape more businesses," I asked: what information would actually help a salesperson make a decision? That changed the direction of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  From scraping to sales intelligence a real run, with real numbers
&lt;/h2&gt;

&lt;p&gt;The Actor now starts with Google Maps, but it doesn't stop there. In one of my tests I searched "Resorts", location “Los Angeles”, capped at 10 businesses, with all four intelligence modules enabled: &lt;strong&gt;Sales &amp;amp; Growth Strategy, Website Performance Report, Suggested Business Improvements,&lt;/strong&gt; &lt;strong&gt;and Website Technology Details&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F162uuzv14xp4kc2dyt86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F162uuzv14xp4kc2dyt86.png" alt=" " width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Actor visits the Google Maps results, collects the business information, then visits the business website and starts analyzing it this is where Playwright matters, since the Actor needs to work with real rendered websites, not static HTML responses.&lt;/p&gt;

&lt;p&gt;Here's a, run, with actual Console evidence rather than just a description:&lt;/p&gt;

&lt;p&gt;Run: "Resorts" in "Los Angeles" - 10 results, 2m 28s, succeeded 2026-08-26&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qxmtp0exjrzo60g3mti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qxmtp0exjrzo60g3mti.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
The actual configuration for this run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;run_input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"searchQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Resorts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Los Angeles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subcategory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxResults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeSalesStrategy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeServiceRecommendations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeTechnicalIntel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeWebsiteHealthScorecard"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deliveryMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mcpConnector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your Notion connector ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mcpTool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"notion-create-pages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mcpArguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"parent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"page_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your Notion page ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Leads: {searchQuery} in {location} ({leadCount})"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{leads}"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"proxyConfiguration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"useApifyProxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with the Apify client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_APIFY_TOKEN&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;techforce.global/google-maps-leads-sales-intelligence-tool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;businessName&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;googleRating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;totalReviews&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output columns from that run: business name, company email, phone, address, Google rating, total reviews, category, website, social media, Google Maps URL, search query, and a Business Growth Opportunity block generated per lead.&lt;/p&gt;

&lt;p&gt;The final result isn't just a business record. It's a combination of business data, website intelligence, and sales intelligence and that combination is the part I actually cared about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the output look like?
&lt;/h2&gt;

&lt;p&gt;Here's an actual result from the Four Seasons test run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business name:&lt;/strong&gt; Four Seasons Hotel Los Angeles At Beverly Hills&lt;br&gt;
&lt;strong&gt;Address:&lt;/strong&gt; 300 S Doheny Dr, Los Angeles, CA 90048&lt;br&gt;
&lt;strong&gt;Phone:&lt;/strong&gt; (310) 273-2222&lt;br&gt;
&lt;strong&gt;Google rating:&lt;/strong&gt; 4.6&lt;br&gt;
&lt;strong&gt;Total reviews:&lt;/strong&gt; 2,411&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; Available&lt;br&gt;
&lt;strong&gt;Company email:&lt;/strong&gt; No email found&lt;br&gt;
That alone is useful. But the interesting part starts after that the Actor generated a lead overview:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lead priority:&lt;/strong&gt; Hot Lead&lt;br&gt;
&lt;strong&gt;Revenue opportunity:&lt;/strong&gt; High&lt;br&gt;
&lt;strong&gt;Sales angle:&lt;/strong&gt; Strong reputation but website trust and SEO polish gaps&lt;br&gt;
&lt;strong&gt;Estimated monthly service potential:&lt;/strong&gt; $300–$900&lt;br&gt;
&lt;strong&gt;Estimated one-time project potential:&lt;/strong&gt; $900–$2,400&lt;/p&gt;

&lt;p&gt;Instead of saying "here's a hotel with a 4.6 rating," I can say: "this business already has strong social proof, but there are website trust, SEO, and conversion opportunities worth discussing." That's a much better starting point and it was probably the biggest shift in the whole project. I stopped thinking about the output as scraped data. I started thinking about it as a sales decision.&lt;/p&gt;

&lt;p&gt;A note on differentiation: at the time of writing I don't yet have a saved example of a Low Priority lead to show side by side I've seen the Actor produce them, but I didn't keep one from an earlier run. What I can show instead is exactly how the tool tells the two apart, which is arguably more useful than one more example: see the scoring logic below.&lt;/p&gt;
&lt;h2&gt;
  
  
  How lead priority and recommendations actually get decided
&lt;/h2&gt;

&lt;p&gt;I didn't want "Hot Lead" to be a field that just sounds confident without any reasoning behind it. Here's the actual shape of the logic, with exact thresholds abstracted since this is scoring logic I'd rather not hand verbatim to every other Google Maps scraper on the market:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;recommendations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required_work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_impact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;why_this_matters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_after_update&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;service_rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;HIGH_QUALITY_THRESHOLD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# already strong, no recommendation needed
&lt;/span&gt;    &lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;High&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;LOW_QUALITY_THRESHOLD&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;grade_from_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;recommendations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;priority&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currentGrade&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;professionalClassification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requiredWork&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;required_work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expectedImpact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected_impact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whyThisChangeMatters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;why_this_matters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whatWillBeAchievedAfterUpdate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected_after_update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;recommendations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Every scored category came back strong — recommend monitoring, not a rebuild
&lt;/span&gt;    &lt;span class="n"&gt;recommendations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Website Monitoring and Continuous Optimization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;priority&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currentGrade&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;professionalClassification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Growth-ready: maintain current quality through regular checks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requiredWork&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Monitor speed, SEO, security headers, structured data, and conversion paths after every website update.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expectedImpact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keeps the website stable, competitive, and ready for future growth.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whyThisChangeMatters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A strong website can still lose performance over time as plugins, content, tracking scripts, and search requirements change.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whatWillBeAchievedAfterUpdate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Regular monitoring should preserve website quality, keep growth campaigns stable, and help catch issues before they affect leads or revenue.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;recommendations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;High&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;priority&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In plain language: each website gets scored across several categories (SEO, security, performance, and a few others). Anything scoring above the high-quality threshold gets skipped no point recommending work on something that's already solid. Anything below the lower threshold becomes a High priority recommendation; the middle band becomes Medium. If a business scores well across the board, instead of returning nothing, the Actor recommends ongoing monitoring rather than forcing a fake "issue" just to have something to say. Recommendations are then sorted so the highest-priority, highest-impact items surface first.&lt;/p&gt;

&lt;p&gt;That's also why a Hot Lead and a genuinely well-optimized business get treated differently under the hood, even if both show up with good Google ratings — the lead score and the website-quality score are measuring different things.&lt;/p&gt;

&lt;h2&gt;
  
  
  The website analysis: every site is different
&lt;/h2&gt;

&lt;p&gt;Once the Actor had the business information, the next challenge was pulling something useful from the website itself and this wasn't as straightforward as I expected. Some sites load fast, some don't. Some have clean HTML, some rely heavily on JavaScript. Some expose an email, some don't. Some have good SEO, some look untouched since 2014 and some manage to have both problems and a great Google rating.&lt;/p&gt;

&lt;p&gt;The Actor checks multiple parameters before generating its technical and sales analysis. For the Four Seasons test, the generated analysis flagged issues around on-page SEO, SSL/security, and technical SEO which gives a salesperson something concrete to open a conversation with:&lt;/p&gt;

&lt;p&gt;Not: "Hi, we provide digital marketing services."&lt;/p&gt;

&lt;p&gt;But something closer to: "We noticed that your business already has strong reviews and a good online foundation, but there are a few trust, SEO, and conversion improvements that could help improve enquiry confidence and organic visibility."&lt;/p&gt;

&lt;p&gt;The first message sounds like an advertisement. The second one sounds like someone actually looked at the business. That difference was the entire goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardest problem wasn't scraping Google Maps
&lt;/h2&gt;

&lt;p&gt;Ironically, the hardest part of this project wasn't Google Maps, and it wasn't even getting the website data. It was accuracy. If I'm going to give a salesperson a field called "Hot Lead," I need to be careful about what that actually means. If I say a business has a high revenue opportunity, there should be reasoning behind it, not a generic template with the business name inserted.&lt;/p&gt;

&lt;p&gt;The way I actually tested this: run it, look at the result, find something that doesn't make sense, change the implementation, run it again, check the output again, repeat. One concrete example early on, businesses with genuinely excellent websites were still occasionally getting flagged with generic "improve your website" recommendations, because the scoring only looked at surface-level signals like page load time. Adding the category-by-category threshold logic above (rather than one blended score) is what fixed that a business can now score well on security but poorly on SEO, and get a recommendation that reflects the actual gap instead of an average that hides it.&lt;/p&gt;

&lt;p&gt;There wasn't a magic switch that made results suddenly perfect. It was a lot of small improvements, and it's the least glamorous part of building a tool like this you don't see it on the Actor page, but it's where most of the work happens&lt;/p&gt;

&lt;h2&gt;
  
  
  The timeout problem
&lt;/h2&gt;

&lt;p&gt;The basic Google Maps scraping was relatively fast. Once I added website analysis, technical analysis, and sales intelligence, every business became more expensive in execution time the Actor wasn't doing one operation anymore, it was doing several per business. If I scrape 100 businesses, I don't just have 100 Google Maps pages, I potentially have 100 websites that also need visiting and analyzing.&lt;/p&gt;

&lt;p&gt;That's a genuinely different performance problem, and it meant keeping a close eye on execution time to keep the whole thing practical to run on the Apify platform which is also one of the reasons I like building on Apify: I don't have to build and manage the infrastructure around the crawler myself. I can focus on the Actor's actual logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually used from Apify
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Actor : the core execution unit&lt;/li&gt;
&lt;li&gt;Playwright : handles browser-based website interaction, since static HTML fetching isn't enough for modern sites&lt;/li&gt;
&lt;li&gt;Dataset : where structured lead results go&lt;/li&gt;
&lt;li&gt;Key-value store : useful for data that doesn't fit a table-like dataset&lt;/li&gt;
&lt;li&gt;Integrations : what turns the output into part of another workflow, not a dead end&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each run gets its own dataset and key-value store, which is convenient for development and testing I don't have to build a storage layer around every scraping project. I build the Actor, run it, and inspect results from the Console or the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The development cycle was short testing it properly wasn't
&lt;/h2&gt;

&lt;p&gt;The first usable version took two to three days, but that doesn't mean two days of coding and done. I tested the Actor against hundreds of businesses during that process. The goal wasn't just making the Actor run successfully a run finishing with status "SUCCEEDED" is not the same thing as a run producing something anyone wants to use. That distinction mattered more than I expected going in.&lt;/p&gt;

&lt;p&gt;The Apify Console made this testing loop much easier, since I could see input, logs, output, and storage for each run without building separate tooling. The runs used Apify SDK 3.4.1, Apify Client 2.5.1, and Crawlee 1.9.1.&lt;/p&gt;

&lt;h2&gt;
  
  
  From dataset to actual sales workflow
&lt;/h2&gt;

&lt;p&gt;I didn't want the output to live forever inside an Apify dataset a sales team isn't going to open Apify every morning to check a dataset. They already have tools they use. For this workflow, results get pushed directly into Notion via Apify's MCP connector, using the notion-create-pages tool each run creates a page under a parent Notion page, titled with the search query, location, and lead count, with the leads themselves as page content.&lt;/p&gt;

&lt;p&gt;So the pipeline is: Google Maps → the Lead Intelligence Actor → Apify Dataset → Notion → the sales workflow. The Actor isn't sitting at the end of the pipeline as a scraper it's one component in the middle of it. The same output could just as easily be pushed into a CRM, sent through an n8n workflow, or used to trigger another Actor entirely, since Apify supports Actor-to-Actor workflows where one Actor's output becomes the next step's input or trigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Apify?
&lt;/h2&gt;

&lt;p&gt;I could have built the infrastructure myself managed browser instances, managed proxies, built storage, handled scaling and deployment and monitoring and eventually gotten back to the actual problem I wanted to solve. I didn't want to do that. Apify gives me a developer-friendly platform where I can focus on building the Actor instead of the infrastructure around it, and proxy support mattered too infrastructure problems can quickly become the project if you're not careful, and I wanted the project to stay the Actor.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would do differently next time
&lt;/h2&gt;

&lt;p&gt;If I were starting this again, I'd talk to more salespeople before writing the first line of code not developers, not scraping experts, actual salespeople and agencies. What do you actually look at before contacting a lead? What makes you reject one? Which website problems are actually worth knowing? What makes a lead "hot" for you? What information helps you personalize a first message, and what's completely useless?&lt;/p&gt;

&lt;p&gt;I built a lot of the intelligence based on what I thought would be useful. That works to a point, but there's a difference between "this is interesting information" and "this information actually changes whether I contact this lead." The second one is what I'd optimize for if I rebuilt this today I'd rather have ten highly useful fields than fifty nobody looks at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I want to take this next
&lt;/h2&gt;

&lt;p&gt;The current version can discover businesses, collect their information, visit their websites, analyze technical aspects, generate website health information, identify improvements, and generate sales-oriented intelligence. But I don't think the interesting part ends there.&lt;/p&gt;

&lt;p&gt;Instead of just saying "Hot Lead," I want to surface why. Instead of just giving a sales angle, I want the salesperson to understand why that angle was selected. Instead of just generating a recommended pitch, I want the recommendation traceable back to actual signals from the business and its website not a black box.&lt;/p&gt;

&lt;p&gt;The original idea was a Google Maps scraper. That version worked, but it wasn't enough. The interesting part started when I stopped asking "how many businesses can I scrape" and started asking "what can I tell a salesperson that will actually save them time." That question changed the entire project, and it's probably the biggest thing I learned building it.&lt;/p&gt;

&lt;p&gt;Scraping the data is only half the job. Making the data useful is the real work. And sometimes the best scraper isn't the one that gives you the most data it's the one that makes you open the next lead and think: okay, this one is actually worth calling.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does this work for any business category, or just hotels and dental practices?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Actor works with any Google Maps search query and location — the examples in this article (resorts, dentists) are just what I happened to test with. The intelligence modules apply the same scoring logic regardless of category&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is "Lead Priority" actually calculated?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Each business's website is scored across several categories (SEO, security, performance, and others). Scores below a threshold generate prioritized recommendations; scores above it don't. See the scoring logic section above for the actual (lightly abstracted) code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if a business has no email or no website at all?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Actor still returns the Google Maps data (name, address, phone, rating, reviews) website-dependent fields like technical intel and website health scoring are simply left empty rather than guessed at.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I deliver results somewhere other than Notion?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Yes, Apify's MCP connector supports multiple delivery targets (Slack, Airtable, Google Sheets, and others depending on what's configured on your account). The dataset is always written in full regardless of delivery settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it yourself:&lt;/strong&gt; &lt;a href="https://apify.com/techforce.global/google-maps-leads-sales-intelligence-tool" rel="noopener noreferrer"&gt;Google Maps Business Leads Scraper &amp;amp; Sales Intelligence on Apify&lt;/a&gt; start with a small maxResults value (5–10) to see the output shape before scaling up a run.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building an AI Agent Workflow with a LinkedIn MCP Connector</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 26 Aug 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/techforce_global/building-an-ai-agent-workflow-with-a-linkedin-mcp-connector-3pb8</link>
      <guid>https://dev.to/techforce_global/building-an-ai-agent-workflow-with-a-linkedin-mcp-connector-3pb8</guid>
      <description>&lt;p&gt;Most tutorials on MCP cover the protocol in the abstract the spec, the message format, a toy example. This post is the opposite: a working walkthrough of wiring a real MCP connector (this actor, which finds &lt;a href="https://apify.com/techforce.global/linkedin-company-decision-makers" rel="noopener noreferrer"&gt;LinkedIn decision makers&lt;/a&gt;) into an agent, plus the API-level details for anyone who wants to call it directly instead of through an MCP client.&lt;/p&gt;

&lt;p&gt;If you've read the protocol docs and still aren't quite sure what an actual integration looks like end to end, this should close that gap three concrete paths (MCP client, direct API, real-time endpoint), each with working code, so you can pick whichever fits your existing stack rather than starting from the spec every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two directions of MCP on Apify, and which one this uses
&lt;/h2&gt;

&lt;p&gt;Apify's own MCP server exposes actors as tools TO outside AI clients Claude, Cursor, and others discover and call Apify actors as part of their toolset. MCP connectors work in the opposite direction: an actor calls OUT to a third-party service (Notion, Slack, Jira) on the user's behalf. This actor supports both it can be called as a tool by an agent, and it can push its own results out via a connector. Understanding which direction you're working with matters, since the setup differs, and mixing them up is the most common early confusion when first working with MCP-enabled actors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting via MCP client config
&lt;/h2&gt;

&lt;p&gt;If you're using Claude Desktop, Cursor, or another MCP-compatible client, connecting to Apify's hosted MCP server looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "mcpServers": {&lt;br&gt;
    "apify": {&lt;br&gt;
      "url": "https://mcp.apify.com",&lt;br&gt;
      "headers": {&lt;br&gt;
        "Authorization": "Bearer YOUR_APIFY_API_TOKEN"&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once connected, the agent can discover and call this actor (and any other Apify actor) as a tool, passing companyName as an argument the same way it would call any other function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling it directly via API Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests

api_token = 'YOUR_APIFY_API_TOKEN'
actor_id = 'techforce.global~linkedin-company-decision-makers'

response = requests.post(
    f'https://api.apify.com/v2/acts/{actor_id}/runs',
    headers={'Authorization': f'Bearer {api_token}'},
    json={'companyName': 'Acme Corp', 'exactMatch': True}
)
dataset_id = response.json()['data']['defaultDatasetId']`

## Using the real-time Standby endpoint Node.js
For agent workflows that need an instant answer rather than waiting on an async run, the Standby mode exposes a live HTTP endpoint:

`const response = await fetch(
  'https://techforce-global--linkedin-company-decision-makers.apify.actor/lookup',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_APIFY_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ companyName: 'Acme Corp' })
  }
);
const decisionMakers = await response.json();
console.log(decisionMakers[0]);
// { name, linkedin_url, title, location, headline }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Standby endpoint is capped at a small number of free profiles for testing, with a higher limit on paid plans worth checking current limits before building a high-volume real-time integration around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up an MCP connector to push results to Notion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Apify Account Settings → API &amp;amp; Integrations → MCP connectors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authorise a new connector, selecting Notion Apify provides automatic OAuth setup for Notion, so this is a one-click authorisation, not a manual API key exchange&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When configuring a run of this actor, select the authorised Notion connector from the picker the actor will push results into the connected Notion database automatically on completion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Output schema reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe50ml8rgit6enlp8sc5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe50ml8rgit6enlp8sc5q.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication and credential handling
&lt;/h2&gt;

&lt;p&gt;For the MCP client and direct API paths, your Apify API token authenticates the request standard bearer token auth, available from Settings → Integrations in your Apify account. For the connector path specifically, your Notion/Slack/Jira credentials never pass through this actor's code at all Apify's platform holds the authorised connection and injects it server-side at runtime, which is worth knowing if credential handling is something your security team asks about before approving an integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error handling
&lt;/h2&gt;

&lt;p&gt;As with any scraping-based actor, individual lookups can return no results a company with no meaningful LinkedIn presence, or a name specific enough that exact matching finds nothing. Check for an empty result set explicitly in your integration code rather than assuming every lookup returns at least one decision maker.&lt;/p&gt;

&lt;p&gt;For the async batch path specifically, poll the run status endpoint until it reports SUCCEEDED before fetching the dataset treating FAILED or ABORTED runs as an explicit case in your code avoids a pipeline silently proceeding with empty or partial data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common integration patterns
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Agent-triggered lookup : an agent calls this as an MCP tool mid-conversation, using the Standby endpoint for a fast response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduled enrichment : a batch run against a fixed list of target companies, on a weekly or monthly schedule, pushing results to Notion via connector&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Event-triggered : a new row in a CRM or spreadsheet triggers a real-time lookup via a webhook-driven automation (n8n, Make, or a custom function)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scheduled-enrichment pattern is worth a closer look for teams managing an ongoing pipeline rather than a one-time list. Wiring this actor into a weekly n8n or Make workflow trigger, run, fetch results, push to Notion via the connector turns decision-maker research from something someone remembers to do manually into something that simply happens, with the team only reviewing the output rather than generating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need to use the MCP connector, or can I just get a normal dataset?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Both are supported connector output is optional, not required. Skip it entirely and use the standard Apify dataset if you don't need direct third-party delivery.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I chain this with other Apify actors in one agent workflow?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Yes, since Apify's MCP server exposes all actors as tools, an agent can call this actor and any other actor (like a contact-enrichment tool) in the same session, chaining outputs together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the rate limit on the Standby endpoint?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;This depends on your Apify plan tier check current limits in your account before building a high-frequency real-time integration.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I test the connector setup without a real Notion/Slack workspace?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Not directly for the connector delivery itself, since it requires an authorised real connection but you can fully test the actor's data output via the standard dataset API first, then add the connector once you're confident in the data, decoupling the two concerns during development.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Full documentation and the interactive input schema: &lt;br&gt;
&lt;a href="https://apify.com/techforce.global/linkedin-company-decision-makers" rel="noopener noreferrer"&gt;LinkedIn Decision Makers MCP Connector for Notion &amp;amp; Slack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>automation</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building an Agency Sourcing Pipeline with the TopDevelopers.co API</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 12 Aug 2026 09:47:15 +0000</pubDate>
      <link>https://dev.to/techforce_global/building-an-agency-sourcing-pipeline-with-the-topdevelopersco-api-4i59</link>
      <guid>https://dev.to/techforce_global/building-an-agency-sourcing-pipeline-with-the-topdevelopersco-api-4i59</guid>
      <description>&lt;p&gt;If you're building an internal tool for vendor sourcing, CRM enrichment, or partnership discovery, pulling agency data from TopDevelopers.co programmatically beats manual research the same way any API beats manual browsing but the interesting part isn't the extraction, it's what you do with the enrichment layer once you have it. This post covers the actor's input/output schema, two full working integration examples, and a few practical patterns for using this as part of a larger pipeline rather than a one-off pull.&lt;/p&gt;

&lt;p&gt;Most agency-directory scrapers stop at raw listing data name, rating, maybe a website. What makes this API worth integrating rather than just running manually through the Apify Console is the enrichment layer: a real email pulled from the agency's own site rather than a directory contact form, and an insights object that turns unstructured review text into something you can actually filter and sort on programmatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;Like any Apify actor, this runs through the standard Apify REST API. You'll need an API token from your Apify account under Settings → Integrations, passed either as a Bearer header or a query parameter depending on which endpoint you're calling.&lt;br&gt;
Input schema&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3428huvy65nghbsi7a1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3428huvy65nghbsi7a1z.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;At least one of searchQuery, companyName, or selectedDomain must be set.&lt;br&gt;
**Starting a run Python&lt;/em&gt;*&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;api_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;actor_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;techforce.global~it-agency-lead-finder-enricher-topdevelopers-co&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/acts/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;actor_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/runs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;api_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;searchQuery&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Flutter developers in UAE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;maxResults&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;maxReviewsPerCompany&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dataset_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching and filtering results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wait_for_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/actor-runs/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SUCCEEDED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;FAILED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ABORTED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIMED-OUT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;agencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/datasets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/items&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api_token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;top_agencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agencies&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.5&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NA&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top_agencies&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;qualified agencies with email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Node.js pushing enriched profiles to a CRM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApifyClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apify-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;techforce.global/it-agency-lead-finder-enricher-topdevelopers-co&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selectedDomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ecommerce Development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;selectedCategory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;platform:shopify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maxResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;listItems&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withBudgetFit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insights&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;common_project_budgets&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$10,001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://your-crm.example.com/webhook/vendors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withBudgetFit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output schema full reference&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbz0dr0gps2v1jq3ymut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbz0dr0gps2v1jq3ymut.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdttzt8mmt5qprpf6i6pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdttzt8mmt5qprpf6i6pk.png" alt="TopDevelopers scraper API output schema agency data" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering on the insights object
&lt;/h2&gt;

&lt;p&gt;The insights.common_project_budgets and insights.top_project_types fields are arrays of strings rather than structured ranges, since they're derived from natural-language review content. Matching on substring, as in the Node example above, is the practical approach checking whether a budget bracket string like "$10,001 - $50,000" appears in the array rather than trying to parse them into strict numeric ranges, which risks breaking if the underlying review phrasing varies.&lt;/p&gt;

&lt;p&gt;This matters for anyone building automated scoring on top of the raw data: treat insights fields as signals to combine with your own weighting logic, not as a substitute for a full lead-score calculation. A practical middle ground is a simple point system award points for rating above a threshold, more points for a matching budget bracket, more again for a matching project type and sort by total rather than trying to build a single authoritative score into the pipeline itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the two-tier pricing in code
&lt;/h2&gt;

&lt;p&gt;Since basic (listing-only) and enriched (full profile) results are priced differently, a cost-conscious integration pattern is to run a broad basic search first to map out the category, then a second, narrower enriched run against just the shortlist that passed initial filtering — rather than enriching every result from the first pass. This mirrors the manual research pattern of browsing broadly first and only digging deep on serious candidates, just automated.&lt;/p&gt;

&lt;p&gt;In practice this means two API calls chained together: the first with a higher maxResults and no need for maxReviewsPerCompany depth, the second with a much smaller maxResults (just the shortlist) but a higher maxReviewsPerCompany, since review depth matters more once you're down to serious candidates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common integration patterns
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Manual pull a BD or procurement team member runs a search through the Apify Console directly and downloads CSV for immediate use, no code required&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduled pipeline a cron job or n8n workflow re-runs key categories monthly or quarterly, refreshing a CRM's vendor table automatically&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On-demand internal tool an internal sourcing tool calls the API in the background when a user searches, so end users never need to know Apify is involved&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two-stage enrichment a broad basic run followed by a narrow enriched run against the resulting shortlist, as described above, to control cost on large category sweeps&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Error handling
&lt;/h2&gt;

&lt;p&gt;As with any scraping-based actor, individual runs can fail due to transient issues an unusually specific query returning no matches, or a temporary network issue on the source site. Explicitly checking for FAILED or ABORTED status rather than assuming every run reaches SUCCEEDED avoids silent failures in a scheduled pipeline going unnoticed. It's also worth logging the input parameters alongside any failure, since a query that returns zero matches often indicates a category name that doesn't quite match TopDevelopers' own taxonomy rather than an actual system failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate limits and concurrency
&lt;/h2&gt;

&lt;p&gt;The maxConcurrency setting controls how many agency profiles are processed simultaneously within a single run, but if you're running multiple separate API calls in parallel say, one per domain it's worth staggering their start times slightly rather than firing all of them at once, to avoid hitting your account's overall concurrent-run limit, which varies by Apify plan tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked
&lt;/h2&gt;

&lt;p&gt;*&lt;em&gt;Is there a sandbox for testing integration code without spending on real results? *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Running against a narrow companyName lookup for a single known agency is the practical equivalent real data, minimal cost, enough to validate your parsing logic.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Can I run multiple domains in parallel? *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Each run is scoped to one search configuration; running separate parallel API calls for different domains works fine and is the standard pattern for broad multi-category research.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;What's a reasonable maxReviewsPerCompany for a first test? *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Something small, like 3-5, is enough to confirm the reviews array structure without spending on a full review pull across every result.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Does the API support pagination for very large result sets? *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Use the standard Apify dataset offset/limit query parameters when fetching items rather than assuming a single request returns everything, particularly for runs near the 200-result cap.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started&lt;/strong&gt;&lt;br&gt;
Full documentation and the interactive input schema are on the Apify listing: &lt;a href="//apify.com/techforce.global/it-agency-lead-finder-enricher-topdevelopers-co"&gt;apify.com/techforce.global/it-agency-lead-finder-enricher-topdevelopers-co&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;For a first integration test, start with a companyName lookup against one agency you already know, confirm the output shape matches what's documented above, then move to a broader searchQuery or selectedDomain run once your parsing logic is confirmed working end to end.&lt;/p&gt;

</description>
      <category>api</category>
      <category>automation</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Sales Teams Are Automating Hospital and Clinic Contact Discovery</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Fri, 07 Aug 2026 06:33:26 +0000</pubDate>
      <link>https://dev.to/techforce_global/how-sales-teams-are-automating-hospital-and-clinic-contact-discovery-5fd</link>
      <guid>https://dev.to/techforce_global/how-sales-teams-are-automating-hospital-and-clinic-contact-discovery-5fd</guid>
      <description>&lt;h2&gt;
  
  
  How Sales Teams Are Automating Hospital and Clinic Contact Discovery
&lt;/h2&gt;

&lt;p&gt;Finding a hospital or clinic's contact information isn't hard it's finding the right ones worth calling that eats time. This closing piece for the campaign covers exactly how sales teams are using scored Google Maps data to shortcut that process.&lt;/p&gt;

&lt;h2&gt;
  
  
  The old way
&lt;/h2&gt;

&lt;p&gt;Manually searching by specialty and city, opening each listing, checking a website, noting a phone number repeated hundreds of times per territory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The automated way
&lt;/h2&gt;

&lt;p&gt;One run per category/location combination returns a lead-scored dataset with contact info already structured name, phone, address, rating, review count, and the no-website flag ready to import directly into a CRM or call sheet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnn8hr2wgvm4msoap5lo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnn8hr2wgvm4msoap5lo.png" alt="Hospital clinic contact data automated lead scoring Google Maps" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked
&lt;/h2&gt;

&lt;p&gt;*&lt;em&gt;Does this replace a CRM? *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;No, it feeds one. Results export cleanly into any CRM or spreadsheet-based workflow.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Our Other Actors
&lt;/h2&gt;

&lt;p&gt;For enrichment beyond Google Maps data, pair this with our &lt;br&gt;
&lt;strong&gt;Website Contact Scraper&lt;/strong&gt;. &lt;a href="//apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links"&gt;apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//apify.com/techforce.global/google-maps-healthcare-leads-sales-intelligence-tool"&gt;apify.com/techforce.global/google-maps-healthcare-leads-sales-intelligence-tool&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sales</category>
      <category>api</category>
      <category>automation</category>
      <category>healthcare</category>
    </item>
    <item>
      <title>Google Maps Healthcare Leads API Integrating Lead Scoring Into Your Sales Stack</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 29 Jul 2026 13:45:00 +0000</pubDate>
      <link>https://dev.to/techforce_global/google-maps-healthcare-leads-api-integrating-lead-scoring-into-your-sales-stack-f82</link>
      <guid>https://dev.to/techforce_global/google-maps-healthcare-leads-api-integrating-lead-scoring-into-your-sales-stack-f82</guid>
      <description>&lt;p&gt;Most Google Maps scraper APIs return raw extraction name, address, phone, done. If you're piping healthcare leads into a CRM, an outreach tool, or an internal dashboard, raw extraction was never really the hard part. Google Maps already exposes this information to anyone browsing directly; the actual engineering problem is prioritization deciding, programmatically, which of a few hundred results are actually worth acting on.&lt;/p&gt;

&lt;p&gt;This actor's API returns a calculated lead score and a has Website boolean alongside the standard fields, so your integration doesn't have to build a scoring layer on top of the raw data afterward. This post covers the API surface, two working integration examples, and a few of the edge cases worth handling before you wire this into production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication and starting a run
&lt;/h2&gt;

&lt;p&gt;Like any Apify actor, this runs through the standard Apify REST API you'll need an API token from your Apify account, available under Settings → Integrations. Runs are started with a POST request against the actor's runs endpoint, with your search parameters passed as the JSON body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting a run Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;api_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;actor_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;techforce.global~google-maps-healthcare-leads-sales-intelligence-tool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/acts/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;actor_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/runs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;api_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Dental Practices&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Miami, FL&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;websiteFilter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;No Website Only&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;dataset_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Run started: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching results once the run completes
&lt;/h2&gt;

&lt;p&gt;Runs are asynchronous starting one returns immediately, but the actual scraping happens over the next several minutes depending on result volume. Poll the run status endpoint until it reports SUCCEEDED, then fetch the dataset items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wait_for_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/actor-runs/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SUCCEEDED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;FAILED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ABORTED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TIMED-OUT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;wait_for_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;leads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.apify.com/v2/datasets/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/items&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api_token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;top_leads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;leadScore&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top_leads&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pushing top leads to a CRM webhook Node.js
&lt;/h2&gt;

&lt;p&gt;The official apify-client package handles run polling internally, which simplifies the same workflow considerably in a Node environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApifyClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apify-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;techforce.global/google-maps-healthcare-leads-sales-intelligence-tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Clinics &amp;amp; Medical Centers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chicago, IL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;websiteFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No Website Only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;listItems&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;topLeads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;leadScore&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://your-crm.example.com/webhook/leads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topLeads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding the input schema
&lt;/h2&gt;

&lt;p&gt;The actor accepts five parameters, all optional except category and location for a meaningful search. Omitting category returns results across all eight healthcare types for the given location, which is useful for broad market-density research but less useful for targeted outbound prospecting, where narrowing to a single category up front keeps the result set relevant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsc7r7wh9mmayefz9tle6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsc7r7wh9mmayefz9tle6.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the output schema
&lt;/h2&gt;

&lt;p&gt;The consistent use of 'N/A' rather than null or an empty string across every field is a deliberate choice it means your integration code can treat every field as a non-null string without defensive null-checking on each one individually, which simplifies downstream processing meaningfully once you're handling thousands of records rather than a handful in a manual test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F467v5cd677v9uuqqlztu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F467v5cd677v9uuqqlztu.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb5w0sus0n3imqgfjy9xl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb5w0sus0n3imqgfjy9xl.png" alt="Google Maps healthcare leads API output lead score dataset" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling rate limits and large result sets
&lt;/h2&gt;

&lt;p&gt;For high-volume territories, results are paginated at the dataset level — use the standard Apify offset and limit query parameters when fetching items rather than assuming a single request returns everything. If you're running this across many cities on a schedule, staggering run start times rather than firing them all simultaneously avoids hitting your account's concurrent-run limit, which varies by Apify plan tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note on error handling
&lt;/h2&gt;

&lt;p&gt;Runs can fail for reasons unrelated to your integration code — a temporary Google Maps rate limit, an unusually specific location string with no matching results, or a transient network issue on Apify's infrastructure. Checking for a FAILED or ABORTED status explicitly, rather than assuming every run reaches SUCCEEDED, is worth building in from the start rather than retrofitting after a silent failure goes unnoticed in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common integration patterns
&lt;/h2&gt;

&lt;p&gt;Three patterns cover most real-world usage. The first is a one-off manual pull a sales rep or analyst triggers a run through the Apify Console directly, downloads the dataset as CSV, and imports it into whatever tool they're already using. No code required, and the fastest path for a single territory.&lt;/p&gt;

&lt;p&gt;The second is a scheduled batch pull a cron job or n8n workflow triggers a run per territory on a recurring basis (weekly or monthly is typical), fetches results once each completes, and pushes new or changed records into a CRM automatically. This is the pattern that scales past a handful of territories without someone manually re-running searches.&lt;/p&gt;

&lt;p&gt;The third is an on-demand API call triggered from inside another application for instance, a custom internal tool where a user picks a city and category from a dropdown, the tool calls this actor's API in the background, and results populate directly in the requesting application's own interface. This pattern requires the most integration work up front but produces the smoothest experience for end users who never need to know Apify is involved at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the lead score matters for API consumers specifically
&lt;/h2&gt;

&lt;p&gt;If you're integrating this into an automated pipeline rather than reviewing results manually, the lead Score and has Website fields are what make automation actually useful rather than just faster. Without them, an automated pipeline would need to push every single result into a CRM or outreach tool indiscriminately, forcing a human to do the prioritization downstream anyway. With them, you can filter server-side pushing only leads above a chosen score threshold, or only no-website leads and let the pipeline do the triage that would otherwise require manual review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does the API support server-side filtering by lead score?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Filtering happens client-side after fetching results, as shown in the examples above the API returns the complete scored dataset per run, and threshold filtering is applied in your own code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the typical run time for a single city/category search?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;This varies with result volume, but most single-city searches complete within a few minutes. Larger metro areas with broad categories can take longer, proportional to the number of listings being scored.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run this on a schedule without manual intervention?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Yes, wrap either example above in a cron job, an n8n scheduled workflow, or a cloud function trigger, and the entire flow from run start to CRM push runs unattended.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a sandbox or test mode for development?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Running with a very specific, narrow location (a small town rather than a major metro area) is the practical equivalent it returns real data but a small enough result set to test integration logic without burning through your per-result budget.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if I pass an invalid category string?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;The actor validates against the eight fixed categories and returns a clear input validation error rather than silently falling back to an unfiltered search worth handling explicitly in your integration so a typo in a category string fails loudly during testing rather than quietly returning unexpected results in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can results be deduplicated across multiple runs for the same territory?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Deduplication isn't handled automatically at the actor level, since each run is independent if you're running the same territory repeatedly on a schedule, deduplicating on business name and address in your own pipeline before pushing to a CRM avoids creating duplicate records for practices that haven't changed between runs.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Full actor documentation and the input schema reference are available on the Apify listing: &lt;a href="https://apify.com/techforce.global/google-maps-healthcare-leads-sales-intelligence-tool" rel="noopener noreferrer"&gt;apify.com/techforce.global/google-maps-healthcare-leads-sales-intelligence-tool.&lt;/a&gt; Pricing is pay per result, so testing an integration against a small location costs only what that test run actually returns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website :&lt;/strong&gt; &lt;a href="https://techforceglobal.com/" rel="noopener noreferrer"&gt;https://techforceglobal.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>automation</category>
      <category>javascript</category>
      <category>sales</category>
    </item>
    <item>
      <title>Building a Standardized Multi-Platform Event Scraper: The Architecture Behind Smart Event Scraper</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Thu, 16 Jul 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/techforce_global/building-a-standardized-multi-platform-event-scraper-the-architecture-behind-smart-event-scraper-56bi</link>
      <guid>https://dev.to/techforce_global/building-a-standardized-multi-platform-event-scraper-the-architecture-behind-smart-event-scraper-56bi</guid>
      <description>&lt;h2&gt;
  
  
  Building a Standardised Multi-Platform Event Scraper: The Architecture Behind Smart Event Scraper
&lt;/h2&gt;

&lt;p&gt;Event data is scattered by design. AllEvents.in, EventsEye.com, District.in, and Meetup.com each structure their listings differently different field names, different date formats, different ways of representing price and location. Pull from more than one of these sources and you inherit the reconciliation problem: matching fields, renaming columns, deduplicating, before the data is usable for anything downstream.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://apify.com/techforce.global/smart-event-scraper" rel="noopener noreferrer"&gt;Smart Event Scraper by Techforce Global&lt;/a&gt; is an Apify actor that solves this by running all four platforms in a single pass and returning one standardised, deduplicated schema regardless of source. This article walks through the technical decisions behind it: why a fixed category taxonomy beats free-text tagging, how the normalisation layer guarantees identical output fields, the full input/output reference, a working n8n pipeline, and code examples for calling it directly from Python or Node.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://apify.com/techforce.global/smart-event-scraper" rel="noopener noreferrer"&gt;https://apify.com/techforce.global/smart-event-scraper&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem: Four Sources, Four Shapes
&lt;/h2&gt;

&lt;p&gt;Each of the four source platforms exposes event data with a different shape. Dates might be ISO strings on one platform and human-readable text on another. Price might be a number, a currency-formatted string, or simply absent. Location might be a full address or just a city name. None of this is a bug in any individual platform it's just what happens when four independent systems solve the same problem differently.&lt;/p&gt;

&lt;p&gt;The naive approach to combining them is to write four separate scrapers and reconcile the output afterward in your own code four sets of field mappings to maintain, four sets of edge cases to handle, and a reconciliation step that has to be re-run mentally every time you add a fifth source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Fixed Category Taxonomy
&lt;/h2&gt;

&lt;p&gt;Free-text tags look flexible but create long-term inconsistency "tech", "technology", and "Tech &amp;amp; Software" all describe the same events but don't group cleanly when you're filtering across sources. Smart Event Scraper uses six fixed categories Tech &amp;amp; Software, Business &amp;amp; Networking, Food &amp;amp; Beverages, Health &amp;amp; Wellness, Art &amp;amp; Culture, and Education &amp;amp; Learning applied identically across all four platforms. A single category filter reliably returns the same type of event no matter which site it originated from. Leave category blank to pull every event type from all four sources in one run.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works : Four Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt; : Parallel source queries: each platform receives the same category, keyword, location, and date-range parameters, queried independently with per-source result limits controlled by maxEventsPerSource.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt; : Field mapping: each platform's native response is mapped onto a fixed 9-field schema (title, date, location, venue, price, url, category, source, description). Fields with no equivalent on a given platform return "N/A" rather than being omitted or left null.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt; : Category normalization: where a platform doesn't natively support the same 6-category system, category is auto-detected from the event title/description and mapped onto the closest fixed category.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 4&lt;/strong&gt; : Consolidation: all four sources' results merge into a single output list, each record tagged with its source platform, ready for direct import without further transformation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Input Configuration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbk3htcp4mgp794je057h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbk3htcp4mgp794je057h.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;{&lt;br&gt;
  "category": "Tech &amp;amp; Software",&lt;br&gt;
  "location": "Berlin",&lt;br&gt;
  "maxEventsPerSource": 40,&lt;br&gt;
  "dateFrom": "2026-09-01",&lt;br&gt;
  "dateTo": "2026-09-30"&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Output Schema
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4el6a0mtjk4mlzoh1rd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4el6a0mtjk4mlzoh1rd3.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlja4260f5ix9ml2aqiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlja4260f5ix9ml2aqiy.png" alt="Smart Event Scraper Apify output standardized schema four platforms dataset" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  n8n Weekly Event Digest Pipeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Schedule Trigger : every Monday 9:00 AM&lt;/li&gt;
&lt;li&gt;HTTP Request : POST to Apify API to start Smart Event Scraper with category + location + coming week's date range&lt;/li&gt;
&lt;li&gt;Wait/Poll : every 60 seconds until run = SUCCEEDED&lt;/li&gt;
&lt;li&gt;HTTP Request : GET results from the Apify dataset API&lt;/li&gt;
&lt;li&gt;Google Sheets or Slack node : push results, grouped by source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because every event record shares the same 9-field schema regardless of source, the Slack/Sheets node requires no conditional field mapping.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaqne3dk67t8hxj9gnfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaqne3dk67t8hxj9gnfc.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How do I find tech events in a specific city automatically?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Set category to "Tech &amp;amp; Software" and location to your target city the actor pulls matching events from all four platforms in one run.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does this return "N/A" instead of leaving fields blank?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;So every output record is safe to import directly into a spreadsheet or database without conditional null handling.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I call this from a language other than Python or JavaScript?&lt;/strong&gt; &lt;br&gt;
&lt;em&gt;Yes, it's a standard REST API. Any language that can make an HTTP POST request can start a run and fetch results.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Smart Event Scraper on Apify &lt;a href="https://apify.com/techforce.global/smart-event-scraper" rel="noopener noreferrer"&gt;apify.com/techforce.global/smart-event-scraper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click 'Try for Free' : no credit card required&lt;/li&gt;
&lt;li&gt;Set category, location, and date range, or call the API directly using either code example above&lt;/li&gt;
&lt;li&gt;Click Run : first results in 1-5 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/techforce.global/smart-event-scraper" rel="noopener noreferrer"&gt;https://apify.com/techforce.global/smart-event-scraper&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Consultation:&lt;/strong&gt; &lt;a href="//calendly.com/techforce-infotech-pvt-ltd/intro-meeting"&gt;calendly.com/techforce-infotech-pvt-ltd/intro-meeting&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="//techforceglobal.com"&gt;techforceglobal.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>webscraping</category>
      <category>api</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Playwright Bulk Website Contact Extraction Emails, Phone Numbers &amp; Social Links From Any Domain</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Wed, 01 Jul 2026 13:51:41 +0000</pubDate>
      <link>https://dev.to/techforce_global/playwright-bulk-website-contact-extraction-emails-phone-numbers-social-links-from-any-domain-3n0m</link>
      <guid>https://dev.to/techforce_global/playwright-bulk-website-contact-extraction-emails-phone-numbers-social-links-from-any-domain-3n0m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Bulk website contact extraction pulling emails, phone numbers, and social media links from a list of company domains is one of the most common B2B data tasks. The naive implementation using HTML parsing (Cheerio, BeautifulSoup) is fast but has a fundamental blind spot: it cannot see contact data that loads via JavaScript. The &lt;a href="https://apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links" rel="noopener noreferrer"&gt;Website Contact Scraper&lt;/a&gt; by Techforce Global addresses this with Playwright (headless Chromium), which renders every page fully before extraction and returns a single consolidated, deduplicated record per domain with emails, phones, social links, and a transparent summary count. This guide covers the technical approach, input/output structure, and a complete n8n pipeline for automated CRM enrichment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HTML Parsing Fails on Modern Websites
&lt;/h2&gt;

&lt;p&gt;When a browser loads a modern website, two events happen: the server delivers the initial HTML, then JavaScript executes and renders additional content. HTML parsers like Cheerio process only the first event. Contact sections built with React, Vue, or Angular components render in the second event and are completely invisible to them.&lt;br&gt;
Playwright runs a real Chromium browser, completes both events, and extracts from the final rendered DOM. This is the same approach used by enterprise contact discovery tools — applied here to bulk URL processing on Apify.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xkjz8phg57nwvk234nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xkjz8phg57nwvk234nw.png" alt="Cheerio vs Playwright contact scraping HTML parsing stops at step 1 Playwright completes JavaScript execution for full contact data coverage" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Website Contact Scraper Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 : Playwright Crawler with Full JS Rendering
&lt;/h3&gt;

&lt;p&gt;Each URL gets a headless Chromium browser instance. The actor waits for full page load including JavaScript execution before extraction begins. No timeout shortcuts. Full render, then extract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 : Contact Page Auto-Discovery
&lt;/h3&gt;

&lt;p&gt;From the root page, the actor scans all href links for contact-related URL patterns: /contact, /about, /team, /impressum, /kontakt. These pages are always crawled first regardless of depth position they are the highest-value pages for contact data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 : Multi-Source Extraction
&lt;/h3&gt;

&lt;p&gt;Emails: two extraction passes raw HTML attributes (mailto: links) and visible rendered text. Phone numbers: visible text only, which is more accurate for formatted international numbers. Social links: matched against platform URL patterns, grouped by platform name in the output object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 : Consolidation Per Domain
&lt;/h3&gt;

&lt;p&gt;All data from all pages crawled for a domain is merged, deduplicated, and returned as one record. Summary counts computed. scannedPages list assembled. Status set to success or no_data_found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjqjdigndpel0hphnw7sy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjqjdigndpel0hphnw7sy.png" alt="Website Contact Scraper technical workflow Playwright render contact discovery extraction one record per domain summary" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Input Configuration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffovkpjqs9y28tm4vqguc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffovkpjqs9y28tm4vqguc.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ "urls": [{ "url": "https://stripe.com" }, { "url": "https://notion.so" }], "maxPagesPerDomain": 10, "maxConcurrency": 5 }&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Output Schema Complete Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31leficn5f3e8u0u20lm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31leficn5f3e8u0u20lm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0sdzgxed0tsx9mnl3qyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0sdzgxed0tsx9mnl3qyh.png" alt="Website Contact Scraper Apify output one record per domain emails phones social links summary count scannedPages" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  n8n CRM Enrichment Pipeline 7 Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Google Sheets Trigger :&lt;/strong&gt; fires when new domain URLs added to column A of your prospect sheet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Request :&lt;/strong&gt; POST to Apify API to start Website Contact Scraper with new URLs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait/Poll :&lt;/strong&gt; every 60 seconds until run = SUCCEEDED&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Request :&lt;/strong&gt; GET results from Apify dataset API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter :&lt;/strong&gt; status = 'success' AND summary.emailCount &amp;gt;= 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HubSpot :&lt;/strong&gt; create or update contacts with extracted emails and social profiles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Sheets :&lt;/strong&gt; write enriched data back to master sheet&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The consistent one-record-per-domain output means the HubSpot node requires no conditional field mapping same schema regardless of how many pages were crawled per domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwwp12qqp3wp7srcqgc6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwwp12qqp3wp7srcqgc6m.png" alt="n8n Website Contact Scraper Apify pipeline automated CRM enrichment Google Sheets HubSpot email phone social extraction" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links" rel="noopener noreferrer"&gt;Website Contact Scraper&lt;/a&gt; on Apify&lt;/li&gt;
&lt;li&gt;Click 'Try for Free'&lt;/li&gt;
&lt;li&gt;Paste your URL list maxPagesPerDomain: 10 recommended&lt;/li&gt;
&lt;li&gt;Enable Apify Proxy for bot-protected sites&lt;/li&gt;
&lt;li&gt;Click Run results in 1–5 minutes depending on URL count&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links" rel="noopener noreferrer"&gt;https://apify.com/techforce.global/website-contact-scraper-emails-phone-numbers-social-links&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Consultation:&lt;/strong&gt; &lt;a href="https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting" rel="noopener noreferrer"&gt;https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://techforceglobal.com" rel="noopener noreferrer"&gt;https://techforceglobal.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>playwright</category>
      <category>apify</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Scrape Quince.com Prices, Auto-Calculated Discounts, Reviews, and Images at Scale</title>
      <dc:creator>Techforce Global</dc:creator>
      <pubDate>Thu, 18 Jun 2026 09:55:53 +0000</pubDate>
      <link>https://dev.to/techforce_global/how-to-scrape-quincecom-prices-auto-calculated-discounts-reviews-and-images-at-scale-4448</link>
      <guid>https://dev.to/techforce_global/how-to-scrape-quincecom-prices-auto-calculated-discounts-reviews-and-images-at-scale-4448</guid>
      <description>&lt;h2&gt;
  
  
  Introduction : Why Quince Data Is Worth Automating
&lt;/h2&gt;

&lt;p&gt;Quince hit $2 billion in annualized revenue in February 2026 after raising a $500 million Series E at a $10.1 billion valuation. The company's manufacturer-to-consumer (M2C) model consistently prices cashmere, linen, silk, denim, and home goods at 50 to 80 percent below traditional retail a pricing strategy that has reset consumer expectations across premium essentials categories.&lt;/p&gt;

&lt;p&gt;For e-commerce teams, brand strategists, affiliate publishers, and market researchers working in these categories, Quince's pricing movements are competitive intelligence worth tracking at scale. The challenge: Quince has no official API, no product data feed, and no bulk export mechanism. This guide explains how the Quince.com Product Scraper by Techforce Global the only dedicated Quince scraper on Apify automates data collection across three input modes and how to integrate it into an automated pricing intelligence pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Input Modes When to Use Each
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskybex5ay7j1u4fjhscm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskybex5ay7j1u4fjhscm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh8laiv9zp1vlwu3gsuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh8laiv9zp1vlwu3gsuj.png" alt="Quince.com scraper three input modes fuzzy keyword search category browse 300 options direct product URLs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mode 1 : Fuzzy Keyword Search&lt;/strong&gt;&lt;br&gt;
The fuzzy_search mode runs your keyword against Quince's search interface. Use this for cross-category research where you want all products of a type regardless of their location in Quince's hierarchy. 'Cashmere' returns results from Women, Men, and Home simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fuzzy_search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"searchQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mongolian cashmere crewneck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"searchLimit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mode 2 : Category Browse (300+ Categories)&lt;/strong&gt;&lt;br&gt;
The category dropdown is built from Quince's live mega-menu, not a static list. New categories Quince adds to their navigation appear in the actor automatically. Navigate to Women &amp;gt; Sweaters &amp;gt; Cashmere or Home &amp;gt; Bedding &amp;gt; Linen with a single dropdown selection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/women/sweaters"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"categoryMaxProducts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mode 3 : Direct Product URLs&lt;/strong&gt;&lt;br&gt;
The product_urls mode accepts a list of specific Quince product page URLs for precise, repeatable monitoring of competing SKUs on a weekly schedule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_urls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"productUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.quince.com/women/lightweight-cotton-cashmere-dolman-sleeve-sweater"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Output Schema Twelve Fields
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0o8rf9qcqxux5uvnm6uc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0o8rf9qcqxux5uvnm6uc.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6fxeunbt69m7jccb4ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6fxeunbt69m7jccb4ec.png" alt="Quince.com Product Scraper Apify output dataset table all fields discount auto-calculated reviews rating structured" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Auto-Calculated Discount % Matters at Pipeline Scale
&lt;/h2&gt;

&lt;p&gt;Most product scrapers return two price strings and leave the calculation to the consumer of the data. At 50 records this is a minor inconvenience. At 2,000 SKUs tracked weekly across five categories, it is a transformation step that must be built, tested, and maintained indefinitely.&lt;/p&gt;

&lt;p&gt;The Quince.com Product Scraper returns discount: '49.5%' as a first-class output field. This eliminates the transformation step entirely: sort by discount immediately, filter in n8n where discount &amp;gt; '40%', display on an affiliate site without a formula, compare month-over-month exports without preprocessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Primary-Color Images Why the Filtering Matters
&lt;/h2&gt;

&lt;p&gt;Quince products come in multiple color variants. A naive scraper returns all variant images for a cashmere crewneck available in 12 colors with 3 photos each, that is 36 images per product. The Quince.com Product Scraper returns only the primary-color hero images: the images that appear by default when a shopper first arrives on the product page. Clean, immediately usable product imagery without a deduplication step.&lt;/p&gt;

&lt;h2&gt;
  
  
  n8n Automated Pricing Intelligence Pipeline Step by Step
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Schedule Trigger&lt;/strong&gt; : runs every Monday at 8:00 AM IST&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Request&lt;/strong&gt; : POST to Apify API to start the Quince Scraper (mode: category, /women/sweaters, max 200, region: US)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait/Poll node&lt;/strong&gt; : checks every 60 seconds until Apify run status = SUCCEEDED&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Request&lt;/strong&gt; : GET request to Apify dataset API to fetch all product records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter node&lt;/strong&gt; : filter records where discount field is NOT equal to 'N/A' (actively discounted products)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Sheets node&lt;/strong&gt; : append all discounted products to weekly pricing tracker with timestamp&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter node (second pass)&lt;/strong&gt; : filter where discount value is greater than '40%'&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack node&lt;/strong&gt; : post top deals to #pricing-alerts channel: title, sellingPrice, retailPrice, discount, URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0e57r61gdisj8s8fn63h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0e57r61gdisj8s8fn63h.png" alt="n8n Quince scraper Apify pipeline weekly pricing intelligence Google Sheets Slack discount alert automation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Use Cases With Example Inputs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case 1 — Weekly Category Benchmarking&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Input:&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/women/sweaters"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"categoryMaxProducts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; Every Monday 8AM&lt;br&gt;
&lt;strong&gt;Result:&lt;/strong&gt; Complete cashmere sweater catalog with current prices and discount % → append to tracking sheet → compare week-over-week&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Case 2 — Affiliate Deal Newsletter&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Filter:&lt;/strong&gt; discount &amp;gt; 45% from any category sweep&lt;br&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Top deals with title, sellingPrice, discount, averageRating, productUrl → format for newsletter template&lt;br&gt;
No manual calculation required discount field is already there&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Case 3 — Competing SKU Monitoring&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Input:&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_urls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="nl"&gt;"productUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specific&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;competing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Quince&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;URLs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Schedule:&lt;/strong&gt; Every Sunday night&lt;br&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Current prices and review scores for each SKU → flag where Quince discount &amp;gt; 30% → inform your own pricing response&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://apify.com/techforce.global/quince-scraper" rel="noopener noreferrer"&gt;Quince.com Product Scraper on Apify&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click 'Try for Free' — Apify provides free trial credits, no card needed&lt;/li&gt;
&lt;li&gt;Select mode, configure input, set limit and region (US or CA)&lt;/li&gt;
&lt;li&gt;Click Run — export as JSON, CSV, Excel, or RSS — or connect via Apify API to n8n&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/techforce.global/quince-scraper" rel="noopener noreferrer"&gt;https://apify.com/techforce.global/quince-scraper&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consultation:&lt;/strong&gt; &lt;a href="https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting" rel="noopener noreferrer"&gt;https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://techforceglobal.com" rel="noopener noreferrer"&gt;https://techforceglobal.com&lt;/a&gt; &lt;br&gt;
&lt;strong&gt;Email:&lt;/strong&gt; &lt;a href="//bhavin.shah@techforceglobal.com"&gt;bhavin.shah@techforceglobal.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ecommerce</category>
      <category>webdev</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
