<?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: Northgrid Data</title>
    <description>The latest articles on DEV Community by Northgrid Data (@northgrid-data).</description>
    <link>https://dev.to/northgrid-data</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%2F4218471%2F98ca9da3-2d26-4692-8db3-3a58da22bb35.png</url>
      <title>DEV Community: Northgrid Data</title>
      <link>https://dev.to/northgrid-data</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/northgrid-data"/>
    <language>en</language>
    <item>
      <title>Find which app version broke things: group App Store 1-star reviews by version in 20 lines</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 08:00:33 +0000</pubDate>
      <link>https://dev.to/northgrid-data/find-which-app-version-broke-things-group-app-store-1-star-reviews-by-version-in-20-lines-5g3</link>
      <guid>https://dev.to/northgrid-data/find-which-app-version-broke-things-group-app-store-1-star-reviews-by-version-in-20-lines-5g3</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked at the end and charge per result. The feed below is Apple's public one and needs no key.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple's public reviews feed includes &lt;code&gt;im:version&lt;/code&gt; on every review, which makes regression-spotting easy: count low-star reviews per app version.&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="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;389801252&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us&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;counts&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="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&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="nx"&gt;r&lt;/span&gt; &lt;span class="o"&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="s2"&gt;`https://itunes.apple.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/rss/customerreviews/page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sortby=mostrecent/json`&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;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;r&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="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &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;e&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;entries&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="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;im:rating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="c1"&gt;// skip the app's own entry&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;im:version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;v&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="na"&gt;n&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="na"&gt;low&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="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;im:rating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;low&lt;/span&gt;&lt;span class="o"&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A version whose low-star share jumps versus the previous one is your suspect. Read its review texts next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The feed only exposes the latest ~500 reviews per app per country, so old versions have thin samples.&lt;/li&gt;
&lt;li&gt;Run it per storefront; one country is not the whole picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted version
&lt;/h2&gt;

&lt;p&gt;Multi-country sweep, star filter, and incremental mode (only new reviews each scheduled run), pay per result: &lt;a href="https://apify.com/northgrid-data/app-store-reviews-multi-country" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/app-store-reviews-multi-country&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>javascript</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Search the App Store and look up app metadata with Apple's free iTunes API</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 02:00:43 +0000</pubDate>
      <link>https://dev.to/northgrid-data/search-the-app-store-and-look-up-app-metadata-with-apples-free-itunes-api-38p8</link>
      <guid>https://dev.to/northgrid-data/search-the-app-store-and-look-up-app-metadata-with-apples-free-itunes-api-38p8</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked at the end and charge per result. The raw endpoints below are free and need no account or key.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple's iTunes Search API covers App Store apps, not just music.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Keyword search
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://itunes.apple.com/search?term=budget+tracker&amp;amp;country=us&amp;amp;entity=software&amp;amp;limit=50"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: returns &lt;code&gt;resultCount&lt;/code&gt; and a &lt;code&gt;results&lt;/code&gt; array in rank order. Each item has &lt;code&gt;trackName&lt;/code&gt;, &lt;code&gt;trackId&lt;/code&gt;, &lt;code&gt;averageUserRating&lt;/code&gt;, &lt;code&gt;userRatingCount&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt; (the first hit was "Budget app - spending tracker", 4.7 stars, 16,274 ratings).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Look up an app by ID
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://itunes.apple.com/lookup?id=389801252&amp;amp;country=us"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: returns Instagram's metadata, including &lt;code&gt;userRatingCount&lt;/code&gt; (29,658,484 at the time). Pass several comma-separated ids to look up many apps in one call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ratings and rankings are per storefront: change &lt;code&gt;country=&lt;/code&gt; (us, gb, de...) to compare markets.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;limit&lt;/code&gt; maxes out at 200 for search.&lt;/li&gt;
&lt;li&gt;Apple rate-limits this API (roughly in the tens of requests per minute per IP), so space out requests and back off on errors.&lt;/li&gt;
&lt;li&gt;Rank = position in &lt;code&gt;results&lt;/code&gt;; it can shift between calls, so log the timestamp if you track it over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted version
&lt;/h2&gt;

&lt;p&gt;If you'd rather not script it, I packaged search with rank, lookup and chart rows as an Apify Actor (pay per result, no subscription): &lt;a href="https://apify.com/northgrid-data/app-store-search-charts-metadata" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/app-store-search-charts-metadata&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>api</category>
      <category>ios</category>
      <category>tutorial</category>
      <category>bash</category>
    </item>
    <item>
      <title>Pull a Bluesky profile and recent posts with the public API (no login, no key)</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 01:30:42 +0000</pubDate>
      <link>https://dev.to/northgrid-data/pull-a-bluesky-profile-and-recent-posts-with-the-public-api-no-login-no-key-f89</link>
      <guid>https://dev.to/northgrid-data/pull-a-bluesky-profile-and-recent-posts-with-the-public-api-no-login-no-key-f89</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked at the end and charge per result. The raw endpoints below are free and need no account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bluesky serves read-only data from &lt;code&gt;public.api.bsky.app&lt;/code&gt;. No auth is needed for profiles and author feeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Profile and follower count
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=bsky.app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: the response includes &lt;code&gt;did&lt;/code&gt;, &lt;code&gt;handle&lt;/code&gt;, &lt;code&gt;displayName&lt;/code&gt;, &lt;code&gt;followersCount&lt;/code&gt; (35,471,536 at the time) and &lt;code&gt;postsCount&lt;/code&gt; (907). &lt;code&gt;actor&lt;/code&gt; accepts a handle or a DID.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Recent posts from one account
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=bsky.app&amp;amp;limit=50&amp;amp;filter=posts_no_replies"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: returns a &lt;code&gt;feed&lt;/code&gt; array; each item has &lt;code&gt;post.uri&lt;/code&gt;, &lt;code&gt;post.record.text&lt;/code&gt;, &lt;code&gt;post.record.createdAt&lt;/code&gt; and like/repost counts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Results are paged: pass the returned &lt;code&gt;cursor&lt;/code&gt; back as &lt;code&gt;cursor=&lt;/code&gt; to get the next page. &lt;code&gt;limit&lt;/code&gt; maxes at 100.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filter&lt;/code&gt; can be &lt;code&gt;posts_no_replies&lt;/code&gt;, &lt;code&gt;posts_with_replies&lt;/code&gt;, &lt;code&gt;posts_with_media&lt;/code&gt; or &lt;code&gt;posts_and_author_threads&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Post search (&lt;code&gt;app.bsky.feed.searchPosts&lt;/code&gt;) returned 403 from my server when I tested it, so don't assume it is open to anonymous clients.&lt;/li&gt;
&lt;li&gt;Be polite with request rates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted version
&lt;/h2&gt;

&lt;p&gt;If you'd rather not script it, I packaged profile, follower and post-feed collection as an Apify Actor (pay per result, no subscription): &lt;a href="https://apify.com/northgrid-data/bluesky-profiles-posts-followers" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/bluesky-profiles-posts-followers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>api</category>
      <category>bluesky</category>
      <category>tutorial</category>
      <category>bash</category>
    </item>
    <item>
      <title>Find when a web page changed using the Wayback Machine CDX API (free, no key)</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 01:00:42 +0000</pubDate>
      <link>https://dev.to/northgrid-data/find-when-a-web-page-changed-using-the-wayback-machine-cdx-api-free-no-key-4lp4</link>
      <guid>https://dev.to/northgrid-data/find-when-a-web-page-changed-using-the-wayback-machine-cdx-api-free-no-key-4lp4</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked at the end and charge per result. The raw endpoints below are free and need no key.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Internet Archive exposes a CDX server that lists every capture it holds for a URL. Two calls cover most needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. List distinct versions of a page
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://web.archive.org/cdx/search/cdx?url=example.com&amp;amp;output=json&amp;amp;collapse=digest&amp;amp;fl=timestamp,statuscode,digest&amp;amp;limit=3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;collapse=digest&lt;/code&gt; drops consecutive captures with identical content, so each row is a real change. Checked 2026-10-31: the first rows were timestamps 20020120142510, 20020328012821 and 20030207055228.&lt;/p&gt;

&lt;p&gt;Open a capture at &lt;code&gt;https://web.archive.org/web/&amp;lt;timestamp&amp;gt;/&amp;lt;url&amp;gt;&lt;/code&gt;; add &lt;code&gt;id_&lt;/code&gt; after the timestamp (&lt;code&gt;/web/&amp;lt;timestamp&amp;gt;id_/&amp;lt;url&amp;gt;&lt;/code&gt;) for the raw page without the Wayback banner.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Find the capture closest to a date
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://archive.org/wayback/available?url=example.com&amp;amp;timestamp=20200101"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: it returned a 200 capture from 2020-01-01 23:10:47.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Timestamps are &lt;code&gt;YYYYMMDDhhmmss&lt;/code&gt;, in UTC.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;from=&lt;/code&gt;/&lt;code&gt;to=&lt;/code&gt; (years or dates) and &lt;code&gt;filter=statuscode:200&lt;/code&gt; to narrow results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;collapse=timestamp:6&lt;/code&gt; gives roughly one capture per month.&lt;/li&gt;
&lt;li&gt;Be gentle with request rates; the archive throttles heavy clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted version
&lt;/h2&gt;

&lt;p&gt;If you'd rather not script it, I packaged both modes as an Apify Actor (pay per result, no subscription): &lt;a href="https://apify.com/northgrid-data/wayback-snapshots-cdx" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/wayback-snapshots-cdx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>bash</category>
    </item>
    <item>
      <title>Search Hacker News "Who is hiring?" threads by keyword with the free Algolia API</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 00:30:51 +0000</pubDate>
      <link>https://dev.to/northgrid-data/search-hacker-news-who-is-hiring-threads-by-keyword-with-the-free-algolia-api-4203</link>
      <guid>https://dev.to/northgrid-data/search-hacker-news-who-is-hiring-threads-by-keyword-with-the-free-algolia-api-4203</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked at the end and charge per result. The raw endpoints below are free and need no key.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every month a "Who is hiring?" thread appears on Hacker News, with hundreds of job comments. Algolia's public HN API lets you search inside one.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Find the latest thread
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://hn.algolia.com/api/v1/search_by_date?query=%22Ask%20HN%3A%20Who%20is%20hiring%22&amp;amp;tags=story,author_whoishiring&amp;amp;hitsPerPage=3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checked 2026-10-31: the newest hit was "Ask HN: Who is hiring? (October 2026)", objectID 49922569.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Search its comments
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://hn.algolia.com/api/v1/search?tags=comment,story_49922569&amp;amp;query=remote%20python&amp;amp;hitsPerPage=20"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each hit has &lt;code&gt;comment_text&lt;/code&gt; (HTML), &lt;code&gt;author&lt;/code&gt;, &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;objectID&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Replace the story id with the one from step 1 each month.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;comment_text&lt;/code&gt; is HTML; strip tags before display.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;&amp;amp;page=1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;... to paginate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted version
&lt;/h2&gt;

&lt;p&gt;If you'd rather not maintain it, I packaged this (plus story and comment search) as an Apify Actor, pay per event, no subscription: &lt;a href="https://apify.com/northgrid-data/hacker-news-search-threads-hiring" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/hacker-news-search-threads-hiring&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Pull App Store reviews for every country in one request (no login, no API key)</title>
      <dc:creator>Northgrid Data</dc:creator>
      <pubDate>Sun, 01 Nov 2026 00:00:25 +0000</pubDate>
      <link>https://dev.to/northgrid-data/pull-app-store-reviews-for-every-country-in-one-request-no-login-no-api-key-4e1k</link>
      <guid>https://dev.to/northgrid-data/pull-app-store-reviews-for-every-country-in-one-request-no-login-no-api-key-4e1k</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I built the Apify Actor linked below and charge per result ($0.0003/review).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple's public customer-reviews feed returns JSON for any app and storefront, with no authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://itunes.apple.com/us/rss/customerreviews/page=1/id=389801252/sortby=mostrecent/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Limits worth knowing: the feed exposes only the latest ~500 reviews per app per country (10 pages of 50), has no developer replies, and one URL covers one country. To compare feedback across markets you loop over storefronts (&lt;code&gt;us&lt;/code&gt;, &lt;code&gt;gb&lt;/code&gt;, &lt;code&gt;de&lt;/code&gt;, ...), paginate, deduplicate and normalise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimal Node version
&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="nx"&gt;r&lt;/span&gt; &lt;span class="o"&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="s2"&gt;`https://itunes.apple.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/rss/customerreviews/page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sortby=mostrecent/json`&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;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;r&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="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="c1"&gt;// first entry on page 1 can be the app itself; reviews have 'im:rating'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pace requests (about 1/second), and stop when a page comes back empty.&lt;/p&gt;

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

&lt;p&gt;I packaged it as an Actor: multi-country sweep (&lt;code&gt;"all"&lt;/code&gt;), star filters, since-date, keyword filter, and an incremental mode that returns only new reviews each scheduled run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/northgrid-data/app-store-reviews-multi-country" rel="noopener noreferrer"&gt;https://apify.com/northgrid-data/app-store-reviews-multi-country&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Input: &lt;code&gt;{ "apps": ["389801252"], "countries": ["us","gb"], "maxRating": 2 }&lt;/code&gt;. Output fields: appId, country, rating, title, text, version, date, url.&lt;/p&gt;

&lt;p&gt;Feedback or missing fields welcome in the Actor's issues.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>api</category>
      <category>datascience</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
