<?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: Benedict Mendoza</title>
    <description>The latest articles on DEV Community by Benedict Mendoza (@benedictmendoza).</description>
    <link>https://dev.to/benedictmendoza</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%2F4085031%2F31f1765d-fa0b-437c-9f85-5186c22e16d2.jpg</url>
      <title>DEV Community: Benedict Mendoza</title>
      <link>https://dev.to/benedictmendoza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benedictmendoza"/>
    <language>en</language>
    <item>
      <title>Job Postings Are the Most Underused B2B Intent Signal (And You Don't Even Need to Scrape)</title>
      <dc:creator>Benedict Mendoza</dc:creator>
      <pubDate>Thu, 20 Aug 2026 23:31:53 +0000</pubDate>
      <link>https://dev.to/benedictmendoza/job-postings-are-the-most-underused-b2b-intent-signal-and-you-dont-even-need-to-scrape-p3k</link>
      <guid>https://dev.to/benedictmendoza/job-postings-are-the-most-underused-b2b-intent-signal-and-you-dont-even-need-to-scrape-p3k</guid>
      <description>&lt;p&gt;A funding announcement tells you a company has money. A job posting tells you exactly where they're about to spend it — and it's published weeks before the pain becomes a purchase.&lt;/p&gt;

&lt;p&gt;If a target account just opened its first platform-engineer role, they're about to have infrastructure problems. First "Head of Demand Gen"? Marketing budget incoming. Three sales roles in a month? They found product-market fit and every vendor selling to sales teams should already be in their inbox. Job postings are, I think, the most underused intent signal in B2B — and unlike most intent data, they're public, structured, and free to read.&lt;/p&gt;

&lt;p&gt;This post covers the mechanics: where the data actually lives, why you don't need to "scrape" in any painful sense, and how to turn it into an alerting system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The secret: almost nobody hosts their own job board
&lt;/h2&gt;

&lt;p&gt;Most companies' careers pages are a skin over an ATS (applicant tracking system) — Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, and a few others. And the big ones expose public JSON endpoints per company, no auth required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://boards-api.greenhouse.io/v1/boards/{company}/jobs
https://api.lever.co/v0/postings/{company}?mode=json
https://api.ashbyhq.com/posting-api/job-board/{company}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not scraping; that's a GET request. When I tested this, &lt;code&gt;stripe&lt;/code&gt; on Greenhouse returned 576 open roles and &lt;code&gt;openai&lt;/code&gt; on Ashby returned 734, each with title, location, and apply URL, in a couple of seconds. No headless browser, no proxies, no anti-bot war — companies &lt;em&gt;want&lt;/em&gt; this data distributed.&lt;/p&gt;

&lt;p&gt;The two actual problems are less obvious:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Discovery&lt;/strong&gt; — which ATS does a given company use? You can probe: normalize the company name into slug candidates and try each ATS endpoint until one answers. It works surprisingly often. For stragglers, the careers link on their website gives it away instantly (&lt;code&gt;jobs.lever.co/...&lt;/code&gt; in the href).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Newness&lt;/strong&gt; — for intent purposes you don't care about the 576 open roles; you care about the 3 that appeared &lt;em&gt;this week&lt;/em&gt;. That means state: store the job IDs you've seen per company, diff on each run, and emit only the delta. This is the step everyone skips and then regrets, because without it your "alerts" are the same 576 jobs every morning.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input&lt;/strong&gt;: a list of target companies (your dream accounts, competitors, whoever)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolve&lt;/strong&gt;: detect each company's ATS and fetch its board as JSON&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normalize&lt;/strong&gt;: six ATS formats into one schema — title, department, location, remote flag, employment type, URL, posted date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diff&lt;/strong&gt;: compare against the stored seen-set; keep only new postings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter&lt;/strong&gt;: keyword match on titles ("sales", "engineer", whatever maps to your product) and locations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alert&lt;/strong&gt;: push the delta to a webhook (n8n/Make/Zapier) or straight into Slack&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run it daily on a schedule and you get a morning message like "Acme just posted: Head of RevOps (Remote)" — which for the right seller is worth more than any purchased lead list, for the same reason fresh beats stale everywhere in sales.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who actually uses this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales/GTM&lt;/strong&gt;: hiring in your category = budget + timing. The trigger beats the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recruiters&lt;/strong&gt;: watch competitor postings to know who's growing and what talent they're fighting for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job seekers&lt;/strong&gt; (underrated): monitor your 20 dream companies directly instead of refreshing aggregators that lag by days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analysts/founders&lt;/strong&gt;: a competitor's job board is their roadmap, published voluntarily. Watch what they hire for.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you'd rather not build the plumbing
&lt;/h2&gt;

&lt;p&gt;I packaged this whole loop as an Apify Actor: &lt;a href="https://apify.com/benedictmendoza/job-postings-monitor" rel="noopener noreferrer"&gt;Job Postings Monitor&lt;/a&gt;. Disclosure: mine. You give it company names (it auto-detects the ATS — typing &lt;code&gt;stripe&lt;/code&gt; is enough), flip on monitor mode, and schedule it; it remembers what it's seen, returns only new postings, and can hit your webhook or Slack directly. Pay-per-job-returned, and in monitor mode you only pay for the new ones — watching 50 quiet companies costs cents.&lt;/p&gt;

&lt;p&gt;But honestly, if you're comfortable with a cron job, the endpoints above plus a key-value store get you a working version in an afternoon. The moat isn't the code — it's actually running it every day, which is exactly the part people stop doing by week three. (That's the real argument for scheduling it on managed infrastructure, whether mine or your own.)&lt;/p&gt;

&lt;h2&gt;
  
  
  One closing thought
&lt;/h2&gt;

&lt;p&gt;Most intent data is inferred: someone visited a page, downloaded a whitepaper, matched a lookalike model. Job postings are &lt;em&gt;declared&lt;/em&gt; intent — the company wrote down what it's investing in and posted it publicly, with a date on it. It's the difference between guessing someone is hungry and watching them book a table.&lt;/p&gt;

&lt;p&gt;Feature requests (more ATS platforms — Workday and BambooHR are the common asks) land in the Actor's &lt;a href="https://apify.com/benedictmendoza/job-postings-monitor" rel="noopener noreferrer"&gt;Issues tab&lt;/a&gt; and genuinely shape what I build next.&lt;/p&gt;

</description>
      <category>sales</category>
      <category>webscraping</category>
      <category>automation</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Company Enrichment Without the Per-Credit Tax: Website to Firmographics JSON With an LLM</title>
      <dc:creator>Benedict Mendoza</dc:creator>
      <pubDate>Wed, 19 Aug 2026 22:08:44 +0000</pubDate>
      <link>https://dev.to/benedictmendoza/company-enrichment-without-the-per-credit-tax-website-to-firmographics-json-with-an-llm-4b0j</link>
      <guid>https://dev.to/benedictmendoza/company-enrichment-without-the-per-credit-tax-website-to-firmographics-json-with-an-llm-4b0j</guid>
      <description>&lt;p&gt;Most of what B2B enrichment vendors sell is information companies publish about themselves, for free, on their own websites. What you're paying per-credit prices for is mostly the reading.&lt;/p&gt;

&lt;p&gt;I noticed this while burning through enrichment credits on accounts that turned out to be obvious non-fits — agencies when I needed SaaS, enterprise when I needed SMB. The data that would have disqualified them in seconds (what they sell, who they sell to, how they price) was sitting on their homepages the whole time. No vendor needed. Just reading.&lt;/p&gt;

&lt;p&gt;So I did the obvious thing: pointed an LLM at company websites and made it fill out a fixed schema. This post covers what that looks like, what it costs (spoiler: about a cent per company), and the failure modes I hit building it into a production tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can extract from a website alone
&lt;/h2&gt;

&lt;p&gt;More than you'd guess. From the homepage plus three or four key pages (/about, /pricing, /careers, /contact), reliably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt;: name, one-line description, industry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business model&lt;/strong&gt;: B2B SaaS vs. ecommerce vs. agency vs. marketplace — the single most useful ICP filter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who they sell to&lt;/strong&gt;: an ICP summary inferred from their own positioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing model&lt;/strong&gt;: freemium / subscription / usage-based / "book a demo" — and visible tiers. "Book a demo" vs. self-serve alone tells you a lot about deal size&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech stack hints&lt;/strong&gt;: integrations and technologies they mention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hiring signals&lt;/strong&gt;: careers page contents — hiring roles are spend commitments, which makes them intent data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contacts and socials&lt;/strong&gt;: generic emails (info@, sales@), phone numbers, social links&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firmographics&lt;/strong&gt;: HQ location, founded year, a size estimate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a real extraction — I ran it against apify.com as a test:&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;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apify.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"companyName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"industry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Technology"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"businessModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"B2B SaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pricingModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subscription"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"icpSummary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Individuals, startups, and large enterprises looking for web data solutions and automation tools."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"employeeCountEstimate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"51-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;"hqLocation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Prague, Czech Republic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isHiring"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&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;"contactEmails"&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="s2"&gt;"hello@apify.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"techStackHints"&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="s2"&gt;"Python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JavaScript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TypeScript"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&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;Every field came from their own pages. Nothing purchased, nothing stale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture (it's short)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fetch the homepage. Plain HTTP — most marketing sites don't need a headless browser.&lt;/li&gt;
&lt;li&gt;Parse internal links and pick the useful pages by URL pattern: about, pricing, careers, contact, product.&lt;/li&gt;
&lt;li&gt;Strip the HTML to text, concatenate with page labels, truncate to a sane token budget.&lt;/li&gt;
&lt;li&gt;One LLM call with a strict JSON schema and a hard rule: &lt;strong&gt;never invent — use null/"unknown" when absent.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Validate the JSON, attach the source URLs, done.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With a small model (gpt-4o-mini class) the LLM step costs a fraction of a cent; with fetches included you land around &lt;strong&gt;a cent per company&lt;/strong&gt;. Compare that to the $0.75–1.50 per row that credit-based AI enrichment effectively costs on paid plans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure modes worth knowing before you build this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hallucinated firmographics.&lt;/strong&gt; Rare but real — the model occasionally "remembers" a company instead of reading the page. The strict schema plus explicit permission to answer "unknown" kills most of it; keeping a confidence score exposes the rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS-only websites.&lt;/strong&gt; Some sites render nothing without a browser. Accept the miss or add a headless fallback; I chose to accept the miss (error rows, clearly marked) to keep speed and cost down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal data temptation.&lt;/strong&gt; Scraping personal emails puts you in GDPR territory for no good reason. Restrict extraction to generic company addresses (info@, sales@) — the compliance surface drops to almost nothing and, honestly, generic inboxes are where cold email belongs anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect chains and www quirks.&lt;/strong&gt; Boring, but half your early failures will be URL normalization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you'd rather not maintain it
&lt;/h2&gt;

&lt;p&gt;I packaged mine as an Apify Actor: &lt;a href="https://apify.com/benedictmendoza/ai-company-enrichment" rel="noopener noreferrer"&gt;AI Company Enrichment&lt;/a&gt;. Disclosure: I built it, pay-per-company, and everything above is how it works internally — so if you want to own the pipeline, this post is the spec.&lt;/p&gt;

&lt;p&gt;Called via API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/benedictmendoza~ai-company-enrichment/runs?token=&lt;/span&gt;&lt;span class="nv"&gt;$APIFY_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"companies": ["stripe.com", "notion.so", "yourprospect.com"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It slots into the usual places: a Clay table's HTTP enrichment column (do the cheap firmographic pass first, spend real credits only on accounts that pass ICP fit), an n8n/Make workflow between "new lead" and "score lead," or just a CSV in, CSV out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general principle
&lt;/h2&gt;

&lt;p&gt;Split your enrichment bill in two: data that genuinely requires a vendor (verified emails, direct dials, funding data) and data that's self-published on the prospect's website. Pay vendors for the first category. Read the second one yourself — with an LLM, "yourself" now costs a cent and takes eight seconds.&lt;/p&gt;

&lt;p&gt;If you try the Actor and want extra fields extracted, the &lt;a href="https://apify.com/benedictmendoza/ai-company-enrichment" rel="noopener noreferrer"&gt;Issues tab&lt;/a&gt; reaches me directly — field requests are cheap to ship.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>sales</category>
      <category>webscraping</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Track Your Brand's Visibility in ChatGPT, Perplexity &amp; Gemini (GEO Monitoring, With Code)</title>
      <dc:creator>Benedict Mendoza</dc:creator>
      <pubDate>Wed, 19 Aug 2026 12:51:14 +0000</pubDate>
      <link>https://dev.to/benedictmendoza/how-to-track-your-brands-visibility-in-chatgpt-perplexity-gemini-geo-monitoring-with-code-5701</link>
      <guid>https://dev.to/benedictmendoza/how-to-track-your-brands-visibility-in-chatgpt-perplexity-gemini-geo-monitoring-with-code-5701</guid>
      <description>&lt;p&gt;This week I ran a simple test. I asked ChatGPT, Perplexity, and Gemini the same question — "what is the best note-taking app for teams?" — and compared how they treated the brands in the answer.&lt;/p&gt;

&lt;p&gt;ChatGPT flat-out recommended Notion, by name, ten times in one answer. Perplexity refused to pick a winner ("there is no single best note-taking app for teams") but still mentioned Notion three times and cited ten sources. Gemini mentioned it eight times and name-dropped Obsidian once. Evernote — a brand that owned this category for a decade — got two mentions across all three engines combined.&lt;/p&gt;

&lt;p&gt;If you're Evernote, nobody sends you a report about this. There's no Search Console for ChatGPT. A growing share of product research now happens inside AI assistants, the answers steer real purchase decisions, and most brands have no idea what's being said.&lt;/p&gt;

&lt;p&gt;The practice of measuring and improving this is getting called GEO (Generative Engine Optimization). Fancy name, but the underlying job is plain: figure out what the AI engines say when your buyers ask about your category, and track how it changes. Here's how to do it with actual data instead of vibes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's worth measuring
&lt;/h2&gt;

&lt;p&gt;While building the tracker, I settled on four numbers per prompt, per engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mention&lt;/strong&gt; — does the answer name your brand at all?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Position&lt;/strong&gt; — first name in the answer, or an afterthought behind three competitors?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share of voice&lt;/strong&gt; — across your whole prompt set, how often do you appear vs. each competitor?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Citations&lt;/strong&gt; — which pages did the engine cite, and is your site one of them?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The citations one is underrated. Engines with web search build answers from a small pool of pages they trust. In my Notion test, the sources were things like Zapier's "best note-taking apps" listicle. If the engines keep citing the same three roundups for your category, getting into those roundups probably moves your AI visibility more than anything you publish on your own domain. Citations are the new backlinks, basically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is doing this every week
&lt;/h2&gt;

&lt;p&gt;Checking by hand works exactly once. Open each engine, ask, read, tally mentions in a spreadsheet. For three prompts that's twenty minutes. For a real setup — say 25 prompts across 3 engines, weekly, because answers drift with every model update — it's hours of tedium that nobody sustains past week two.&lt;/p&gt;

&lt;p&gt;There are SaaS tools for this now (Otterly, Peec, Profound, Ahrefs Brand Radar), and some are good, but pricing runs from $29 to over $800 a month with seat licenses and prompt quotas. For an agency juggling ten client brands, or a solo founder who wants one weekly number, the economics are annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built instead
&lt;/h2&gt;

&lt;p&gt;I made an Apify Actor that does single prompt-checks and charges per check rather than per month: &lt;a href="https://apify.com/benedictmendoza/ai-search-visibility-tracker" rel="noopener noreferrer"&gt;AI Search Visibility Tracker&lt;/a&gt;. Disclosure: I'm the author, so weigh that however you like — the methodology below works whether or not you use my tool.&lt;/p&gt;

&lt;p&gt;You give it a brand, aliases, competitors, and the prompts your buyers actually ask. It runs every prompt through ChatGPT, Perplexity, and Gemini with live web search and returns a structured row per prompt-engine pair:&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;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"What is the best note-taking app for teams?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chatgpt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brandMentioned"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&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;"brandMentionCount"&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;"brandRank"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"competitorsMentioned"&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;"Obsidian"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Evernote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Coda"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&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;"brandCited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&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;"citations"&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://zapier.com/blog/best-note-taking-apps/"&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;"answerText"&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="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;plus a run summary with overall visibility %, per-engine breakdown, and share of voice. Those numbers at the top of this post came straight out of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating the weekly run
&lt;/h2&gt;

&lt;p&gt;One run is a snapshot; the value is the trend line. The whole loop via API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/benedictmendoza~ai-search-visibility-tracker/runs?token=&lt;/span&gt;&lt;span class="nv"&gt;$APIFY_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; @tracking-config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in JavaScript:&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="k"&gt;import&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="k"&gt;from&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APIFY_TOKEN&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;benedictmendoza/ai-search-visibility-tracker&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;brandName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YourBrand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;competitors&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;CompetitorA&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;CompetitorB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;yourPromptList&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lazy-but-solid production setup: an &lt;a href="https://docs.apify.com/platform/schedules" rel="noopener noreferrer"&gt;Apify Schedule&lt;/a&gt; every Monday morning, dataset auto-exported to Google Sheets. After four Mondays you have a trend line per engine, and the data starts saying interesting things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking prompts (don't invent them)
&lt;/h2&gt;

&lt;p&gt;Bad prompt sets produce useless dashboards. Mine yours from places where real phrasing lives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your highest-converting search queries, reworded as questions&lt;/li&gt;
&lt;li&gt;"best X for Y" patterns in your category — these dominate AI product recommendations&lt;/li&gt;
&lt;li&gt;questions your sales team actually gets asked on calls&lt;/li&gt;
&lt;li&gt;"[competitor] alternative" phrasings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Twenty well-chosen prompts beat two hundred generic ones, and they cost 10x less to track.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading the results
&lt;/h2&gt;

&lt;p&gt;A few patterns I've already seen and what they mean:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're invisible, competitors aren't.&lt;/strong&gt; Go read the &lt;code&gt;citations&lt;/code&gt; field before touching your own site. The pages the engines trust for your category are your outreach hit-list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mentioned, but always last.&lt;/strong&gt; The engines know you exist and don't prefer you. Diff the &lt;code&gt;answerText&lt;/code&gt; descriptions of you vs. the leader — the gap is usually positioning or recency of third-party coverage, not product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Great on Perplexity, absent on ChatGPT.&lt;/strong&gt; Normal. They cite different source pools. Start with whichever engine your audience actually uses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;brandCited: false&lt;/code&gt; even when you're mentioned.&lt;/strong&gt; The engines describe you from other people's pages. Structured comparison content on your own domain tends to move this one first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start the clock now
&lt;/h2&gt;

&lt;p&gt;Whatever tooling you choose, the thing that matters is starting the time series. AI answers about your category are drifting right now, quietly, and you can't retroactively measure last quarter. Fixed prompt set, three engines, weekly cadence — the trend line does the rest.&lt;/p&gt;

&lt;p&gt;If you try the Actor and want another engine (Google AI Overviews is next on my list), sentiment scoring, or Slack alerts — the &lt;a href="https://apify.com/benedictmendoza/ai-search-visibility-tracker" rel="noopener noreferrer"&gt;Issues tab&lt;/a&gt; is the fastest way to reach me. I answer fast.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>marketing</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
