<?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: Cooki</title>
    <description>The latest articles on DEV Community by Cooki (@cooki).</description>
    <link>https://dev.to/cooki</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%2F4015668%2Fc4b1b933-2b6b-435f-a748-3fce152874e6.png</url>
      <title>DEV Community: Cooki</title>
      <link>https://dev.to/cooki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cooki"/>
    <language>en</language>
    <item>
      <title>Exporting any Bluesky profile's followers with the open API</title>
      <dc:creator>Cooki</dc:creator>
      <pubDate>Sun, 05 Jul 2026 02:49:35 +0000</pubDate>
      <link>https://dev.to/cooki/exporting-any-bluesky-profiles-followers-with-the-open-api-3flb</link>
      <guid>https://dev.to/cooki/exporting-any-bluesky-profiles-followers-with-the-open-api-3flb</guid>
      <description>&lt;p&gt;Every big social network locks audience data behind auth walls and anti-bot systems. Bluesky went the other way. The AT Protocol is open by design, so public profile data (bios, follower counts, full follower and following lists) is queryable through a documented API without logging in.&lt;/p&gt;

&lt;p&gt;The whole surface is basically two endpoints:&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;GET https://api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=HANDLE
GET https://api.bsky.app/xrpc/app.bsky.graph.getFollowers?actor=HANDLE&amp;amp;limit=100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also &lt;code&gt;getProfiles&lt;/code&gt; for batching 25 handles per call. Follower lists paginate with a normal &lt;code&gt;cursor&lt;/code&gt;, which still works on the graph endpoints. Search is a different story, cursor pagination 403s there now, but that's a topic for another post.&lt;/p&gt;

&lt;p&gt;For one-off lookups, curl is honestly all you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it gets tedious
&lt;/h2&gt;

&lt;p&gt;Bulk. Thousands of profiles, follower exports that run into six figures, weekly snapshots for tracking. Pagination, rate-limit backoff, and stitching the pages together is boring code that has to run reliably.&lt;/p&gt;

&lt;p&gt;I packaged that part as an Apify actor: &lt;a href="https://apify.com/cooki/bluesky-profile-scraper" rel="noopener noreferrer"&gt;Bluesky Profile Scraper&lt;/a&gt;. Paste handles or profile URLs, optionally turn on follower/following export, and you get JSON or CSV back with a &lt;code&gt;sourceProfile&lt;/code&gt; field linking each follower record to the profile it belongs to. $2 per 1,000 records, runs on a schedule if you want snapshots over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What people use this for
&lt;/h2&gt;

&lt;p&gt;Vetting an influencer's real audience before paying them. Exporting who follows a competitor and what their bios say. Charting follower growth from weekly runs. And enrichment: find who's talking about you with a &lt;a href="https://apify.com/cooki/bluesky-mentions-scraper" rel="noopener noreferrer"&gt;mentions monitor&lt;/a&gt;, then profile those authors to see their actual reach.&lt;/p&gt;

&lt;p&gt;Bluesky is the only major network right now where any of this is straightforward and stable. Worth using while it lasts.&lt;/p&gt;

</description>
      <category>bluesky</category>
      <category>api</category>
      <category>datascience</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Checking whether ChatGPT actually recommends your product</title>
      <dc:creator>Cooki</dc:creator>
      <pubDate>Sun, 05 Jul 2026 02:39:47 +0000</pubDate>
      <link>https://dev.to/cooki/checking-whether-chatgpt-actually-recommends-your-product-dh8</link>
      <guid>https://dev.to/cooki/checking-whether-chatgpt-actually-recommends-your-product-dh8</guid>
      <description>&lt;p&gt;Ask ChatGPT or Perplexity "what's the best note-taking app" and you get a shortlist of three to five names. Either you're on it or you don't exist in that channel. And buying research keeps moving there.&lt;/p&gt;

&lt;p&gt;People call measuring this GEO or AEO tracking now. The way most teams do it is pasting questions into chatbots by hand and eyeballing the answers. That stops scaling at about ten questions, and you can't trend it week over week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing it programmatically
&lt;/h2&gt;

&lt;p&gt;Don't scrape the chat UIs. It's fragile, against ToS, and breaks weekly. The engines all have official APIs with web search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perplexity's &lt;code&gt;sonar&lt;/code&gt; models return answers with citations built in&lt;/li&gt;
&lt;li&gt;OpenAI has &lt;code&gt;gpt-4o-search-preview&lt;/code&gt; for live web search&lt;/li&gt;
&lt;li&gt;Gemini's &lt;code&gt;gemini-2.5-flash&lt;/code&gt; supports Google Search grounding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One OpenRouter key covers all three through a single endpoint, which keeps the code boring.&lt;/p&gt;

&lt;p&gt;For each buyer question you care about, record four things per engine: was the brand mentioned, how early in the answer, was your domain cited as a source, and how often competitors appeared. That last one gives you share of voice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The packaged version
&lt;/h2&gt;

&lt;p&gt;I built this as an Apify actor: &lt;a href="https://apify.com/cooki/ai-brand-visibility-tracker" rel="noopener noreferrer"&gt;AI Brand Visibility Tracker&lt;/a&gt;. You give it a brand name, domain, competitors, and topics. It generates realistic buyer questions and returns one JSON row per check: &lt;code&gt;brandMentioned&lt;/code&gt;, &lt;code&gt;positionScore&lt;/code&gt;, &lt;code&gt;brandCited&lt;/code&gt;, &lt;code&gt;shareOfVoice&lt;/code&gt;, &lt;code&gt;citedDomains&lt;/code&gt;, plus a per-engine summary. Schedule it weekly and you have an AI visibility trendline for client reports. $0.05 per check.&lt;/p&gt;

&lt;h2&gt;
  
  
  The field that actually matters
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;citedDomains&lt;/code&gt; is the actionable one. It tells you which sites the AI engines treat as sources for your category. Getting mentioned on those specific domains is how you move your visibility. It's link building, except the target list comes from the AI's own citations instead of a guess.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>seo</category>
      <category>marketing</category>
      <category>api</category>
    </item>
    <item>
      <title>Nobody is monitoring Bluesky, so I built a mentions scraper for it</title>
      <dc:creator>Cooki</dc:creator>
      <pubDate>Sun, 05 Jul 2026 02:39:14 +0000</pubDate>
      <link>https://dev.to/cooki/nobody-is-monitoring-bluesky-so-i-built-a-mentions-scraper-for-it-19mi</link>
      <guid>https://dev.to/cooki/nobody-is-monitoring-bluesky-so-i-built-a-mentions-scraper-for-it-19mi</guid>
      <description>&lt;p&gt;I wanted to know when people mention a brand on Bluesky. Simple ask. Turns out Brandwatch, Mention, Hootsuite, basically every social listening tool, still doesn't cover it. They're all busy with X and Instagram while Bluesky sits at 27M+ monthly users.&lt;/p&gt;

&lt;p&gt;So I looked at doing it myself and found out something most people miss: you don't need to scrape anything. Bluesky runs on the AT Protocol, which is open by design. Public posts are searchable through a documented endpoint. No login, no API key.&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;GET https://api.bsky.app/xrpc/app.bsky.feed.searchPosts?q=YOUR_BRAND&amp;amp;sort=latest&amp;amp;limit=100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That returns full post objects. Text, author handle, timestamps, like/repost/reply counts, embedded links, hashtags. Everything you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things that broke my first version
&lt;/h2&gt;

&lt;p&gt;Worth writing down because most tutorials get this wrong now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;public.api.bsky.app&lt;/code&gt; host that older guides point to returns 403 for search. Use &lt;code&gt;api.bsky.app&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;As of July 2026, unauthenticated search rejects &lt;code&gt;cursor&lt;/code&gt; pagination. Page one works fine, page two gets you a 403 with "request forbidden by administrative rules". The nasty part is it looks like rate limiting, but it isn't. The workaround: paginate by time. Use &lt;code&gt;sort=latest&lt;/code&gt;, then pass &lt;code&gt;until=&lt;/code&gt; with the &lt;code&gt;createdAt&lt;/code&gt; of the oldest post from the previous page. Dedupe on &lt;code&gt;uri&lt;/code&gt; because the boundary post shows up twice.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  If you don't want to maintain any of that
&lt;/h2&gt;

&lt;p&gt;I packaged the whole job as an Apify actor: &lt;a href="https://apify.com/cooki/bluesky-mentions-scraper" rel="noopener noreferrer"&gt;Bluesky Mentions Scraper&lt;/a&gt;. Keywords in, clean JSON out. It handles the pagination and retry stuff above, filters replies if you want, scores basic sentiment, and can pull follower counts for each author so you can sort mentions by reach. Runs on a schedule, exports CSV, plugs into Slack or n8n through Apify's integrations. It also works as an MCP tool inside Claude or Cursor.&lt;/p&gt;

&lt;p&gt;Pricing is per result, $4 per 1,000 mentions. No subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually monitor
&lt;/h2&gt;

&lt;p&gt;Brand and product names plus the common misspellings. Competitor names, because share of voice on Bluesky is cheap to win while nobody else is looking. The domain itself, since people share links without naming you. And category phrases like "best CRM", which is where the buying-intent threads live.&lt;/p&gt;

&lt;p&gt;One last thing. Bluesky's culture is rough on brands that show up three days late to a complaint thread. If you set up monitoring, run it hourly, not weekly.&lt;/p&gt;

</description>
      <category>bluesky</category>
      <category>api</category>
      <category>marketing</category>
      <category>socialmedia</category>
    </item>
  </channel>
</rss>
