How to check an app idea against real App Store data before you build it
AI made building an app cheap. It didn't make picking the right app cheap. A week spent on an idea the market already owns is still a week gone. So before building, I now r
The idea I tested
</h2> <blockquote> <p>A habit tracker for people with ADHD that uses tiny 2-minute habits and a pet that grows when you keep a streak. Free with a $4.99/month premium plan.</p> </blockquote> <p>It sounds like a solid indie project. Let's see what the stores say.</p> <h2>Step 1: List the competitors and their numbers
</h2> <p>Apple's iTunes Search API is free and needs no key. It returns ratings count, average rating, price and the last update date for each app:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight python"><code><span class="kn">import</span> <span class="n">requests</span> <span class="kn">from</span> <span class="n">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timezone</span><span class="k">def</span> <span class="nf">competitors</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">country</span><span class="o">=</span><span class="sh">"</span><span class="s">us</span><span class="sh">"</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">25</span><span class="p">):</span> <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">https://itunes.apple.com/search</span><span class="sh">"</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="p">{</span> <span class="sh">"</span><span class="s">term</span><span class="sh">"</span><span class="p">:</span> <span class="n">term</span><span class="p">,</span> <span class="sh">"</span><span class="s">country</span><span class="sh">"</span><span class="p">:</span> <span class="n">country</span><span class="p">,</span> <span class="sh">"</span><span class="s">entity</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">software</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">limit</span><span class="sh">"</span><span class="p">:</span> <span class="n">limit</span><span class="p">,</span> <span class="p">},</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span> <span class="n">rows</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">r</span><span class="p">.</span><span class="nf">json</span><span class="p">()[</span><span class="sh">"</span><span class="s">results</span><span class="sh">"</span><span class="p">]:</span> <span class="n">updated</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">.</span><span class="nf">fromisoformat</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="sh">"</span><span class="s">currentVersionReleaseDate</span><span class="sh">"</span><span class="p">].</span><span class="nf">replace</span><span class="p">(</span><span class="sh">"</span><span class="s">Z</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">+00:00</span><span class="sh">"</span><span class="p">))</span> <span class="n">rows</span><span class="p">.</span><span class="nf">append</span><span class="p">({</span> <span class="sh">"</span><span class="s">name</span><span class="sh">"</span><span class="p">:</span> <span class="n">a</span><span class="p">[</span><span class="sh">"</span><span class="s">trackName</span><span class="sh">"</span><span class="p">],</span> <span class="sh">"</span><span class="s">rating</span><span class="sh">"</span><span class="p">:</span> <span class="nf">round</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">averageUserRating</span><span class="sh">"</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="mi">2</span><span class="p">),</span> <span class="sh">"</span><span class="s">ratings</span><span class="sh">"</span><span class="p">:</span> <span class="n">a</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">userRatingCount</span><span class="sh">"</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="sh">"</span><span class="s">price</span><span class="sh">"</span><span class="p">:</span> <span class="n">a</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">price</span><span class="sh">"</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="sh">"</span><span class="s">days_since_update</span><span class="sh">"</span><span class="p">:</span> <span class="p">(</span><span class="n">datetime</span><span class="p">.</span><span class="nf">now</span><span class="p">(</span><span class="n">timezone</span><span class="p">.</span><span class="n">utc</span><span class="p">)</span> <span class="o">-</span> <span class="n">updated</span><span class="p">).</span><span class="n">days</span><span class="p">,</span> <span class="p">})</span> <span class="k">return</span> <span class="nf">sorted</span><span class="p">(</span><span class="n">rows</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="sh">"</span><span class="s">ratings</span><span class="sh">"</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nf">competitors</span><span class="p">(</span><span class="sh">"</span><span class="s">adhd habit tracker</span><span class="sh">"</span><span class="p">)[:</span><span class="mi">10</span><span class="p">]:</span> <span class="nf">print</span><span class="p">(</span><span class="n">row</span><span class="p">)</span> </code></pre>
</div> <p>Apple doesn't publish installs, so <strong>ratings count is the best public demand signal</strong> on iOS.</p> <h2>Step 2: Turn the numbers into three questions
</h2> <p>I score every idea 0–10 on three things:</p> <div class="table-wrapper-paragraph"><table> <thead> <tr> <th>Score</th> <th>Question</th> <th>Signals from the data</th> </tr> </thead> <tbody> <tr> <td>Demand</td> <td>Do people want this?</td> <td>Ratings on the top apps, number of apps</td> </tr> <tr> <td>Competition</td> <td>Is there room to enter? (high = easy)</td> <td>Strong apps, stale leaders, unhappy users, a free option</td> </tr> <tr> <td>Revenue</td> <td>Will people pay?</td> <td>Share of paid apps or in-app purchases, price level</td> </tr> </tbody> </table></div> <p>My rule of thumb: an average of <strong>7.5 or more</strong> means build. Below 6 means skip or change the idea. Competition usually decides it: consumer apps rarely score above 5 there.</p> <p>Two quick checks catch most bad ideas:</p> <ol> <li> <strong>Is there a giant?</strong> One app with hundreds of thousands of ratings and a 4.9 rating owns the category.</li> <li> <strong>Is the giant free?</strong> Then your $4.99/month plan competes with $0.</li> </ol> <h2>Step 3: Read the critical reviews
</h2> <p>The numbers say <em>whether</em> to enter. The 1–3 star reviews of the top apps say <em>how</em>. Pull them from the public review feed (I covered the code in my previous post on <a href="https://dev.tolink%20to%20your%20first%20post">finding what users hate in competitor apps</a>) and look for complaints that repeat across apps.</p> <h2>The result: 5.0 / 10, Skip
</h2> <p>Here's what the data said for the ADHD habit tracker idea (US App Store):</p> <ul> <li> <strong>15 competitors</strong> for the main keywords.</li> <li>The top direct competitor, <strong>Finch: Self-Care Pet</strong>, has <strong>768k ratings at 4.95★</strong>, and it's free. It's essentially the same idea.</li> <li>Other big apps in the space: Me+ Lifestyle Routine (249k ratings), Structured (168k), Habit Tracker (148k).</li> <li><strong>All the top direct competitors are free.</strong></li> <li>Critical reviews keep coming back to the same complaint: <strong>pay-forever subscriptions feel extractive</strong>.</li> </ul> <p>Scores: <strong>Demand 7, Competition 3, Revenue 5 → 5.0 / 10. Verdict: Skip</strong>, unless it's repositioned.</p> <p>The useful part wasn't the "no". It was the angle the data pointed to:</p> <ul> <li>Drop the pet (Finch owns it). Focus on <strong>time-blindness and decision fatigue</strong>.</li> <li>Sell a <strong>one-time $9.99 unlock</strong> instead of a subscription, because that's exactly what reviewers ask for.</li> <li>Watch the legal side: App Store guideline <strong>2.3</strong> (no "treats ADHD" claims in your metadata) and <strong>GDPR</strong> for habit data.</li> </ul> <h2>Doing it in one step
</h2> <p>Doing this by hand for every idea took me an evening each time, so I built it as an Apify Actor: <strong><a href="https://apify.com/jaclfruit_296/app-idea-validator-actor" rel="noopener noreferrer">App Idea Validator</a></strong>.</p> <p>You describe the idea in a sentence. It:</p> <ol> <li>picks search keywords and searches the App Store and Google Play</li> <li>lets AI mark the <strong>direct</strong> competitors (not just keyword matches)</li> <li>computes the market numbers with fixed rules (not by the AI)</li> <li>reads the critical reviews of the biggest competitors</li> <li>scores Demand / Competition / Revenue and gives a <strong>Build / Reposition / Skip</strong> verdict</li> <li>writes a one-page <strong>Lean Canvas</strong> and a <strong>legal & store-policy check</strong> </li> </ol> <p>To keep the AI honest, the Competition score can't move more than 2 points away from a hint computed from the raw numbers. A category with a 768k-rating leader can't be called "easy".</p> <p>From Python:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight python"><code><span class="kn">from</span> <span class="n">apify_client</span> <span class="kn">import</span> <span class="n">ApifyClient</span><span class="n">client</span> <span class="o">=</span> <span class="nc">ApifyClient</span><span class="p">(</span><span class="sh">"</span><span class="s"><YOUR_APIFY_TOKEN></span><span class="sh">"</span><span class="p">)</span> <span class="n">run</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="nf">actor</span><span class="p">(</span><span class="sh">"</span><span class="s">jaclfruit_296/app-idea-validator-actor</span><span class="sh">"</span><span class="p">).</span><span class="nf">call</span><span class="p">(</span><span class="n">run_input</span><span class="o">=</span><span class="p">{</span> <span class="sh">"</span><span class="s">idea</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">A habit tracker for people with ADHD that uses tiny 2-minute habits </span><span class="sh">"</span> <span class="sh">"</span><span class="s">and a pet that grows when you keep a streak.</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">stores</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span><span class="sh">"</span><span class="s">app_store</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">google_play</span><span class="sh">"</span><span class="p">],</span> <span class="sh">"</span><span class="s">country</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">us</span><span class="sh">"</span><span class="p">,</span> <span class="p">})</span>
<span class="n">summary</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="nf">key_value_store</span><span class="p">(</span><span class="n">run</span><span class="p">[</span><span class="sh">"</span><span class="s">defaultKeyValueStoreId</span><span class="sh">"</span><span class="p">]).</span><span class="nf">get_record</span><span class="p">(</span><span class="sh">"</span><span class="s">OUTPUT</span><span class="sh">"</span><span class="p">)[</span><span class="sh">"</span><span class="s">value</span><span class="sh">"</span><span class="p">]</span> <span class="n">v</span> <span class="o">=</span> <span class="n">summary</span><span class="p">[</span><span class="sh">"</span><span class="s">verdict</span><span class="sh">"</span><span class="p">]</span> <span class="nf">print</span><span class="p">(</span><span class="n">v</span><span class="p">[</span><span class="sh">"</span><span class="s">verdict</span><span class="sh">"</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="sh">"</span><span class="s">average</span><span class="sh">"</span><span class="p">],</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">s</span><span class="p">[</span><span class="sh">"</span><span class="s">score</span><span class="sh">"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">v</span><span class="p">[</span><span class="sh">"</span><span class="s">scores</span><span class="sh">"</span><span class="p">].</span><span class="nf">items</span><span class="p">()})</span> </code></pre>
</div> <p>The full report is saved as <code>REPORT.html</code>, and the competitor table can be exported as CSV or Excel. It costs under $0.50 per idea.</p> <h2>Takeaways
</h2> <ul> <li>Check the stores <strong>before</strong> you write code. It takes minutes.</li> <li>One free giant with a 4.9 rating is usually a "no", whatever your feature list says.</li> <li>Read the 1-star reviews of the leader. Your positioning is hiding in there.</li> <li>A "Skip" verdict is a good result. It just saved you a week.</li> </ul> <p>What's an idea you'd like to see scored? Drop it in the comments and I'll run it and post the verdict.</p>Original source
Tags
Related Articles
Continue reading with these similar posts

Sources: Missouri RB Hardy, shot in offseason, to return vs. Arkansas
Missouri All-America tailback Ahmad Hardy is set to make his season debut for the Tigers this weekend at Arkansas, sources told ESPN.

Red Wings suspend Larkin as team explores trade options; players keen to move on
The Red Wings announced Thursday that star forward Dylan Larkin has been suspended without pay after informing the team he no longer wanted to play for Detroit.

Packers' Jacobs says TD celebration was ode to gospel song, not mocking arrest
The Packers' Josh Jacobs said he was surprised his first-half TD celebration was perceived by some as mocking his May arrest, saying it was an ode to a gospel song.

Israel faces weeks of coalition haggling as Netanyahu’s party claims election 'stolen'
Israel's election leaves the country facing weeks of coalition bargaining and an uphill battle for the opposition party to form a majority government.
Herdr has released native app
Comments

Satellite vs Fiber Internet: ഇന്ത്യയുടെ ഇന്റർനെറ്റ് വിപ്ലവത്തിന് ആര് മികച്ചത്?
ഇന്ന് ഇന്റർനെറ്റ് ഒഴിച്ചുകൂടാനാവാത്ത ഭാഗമായി മാറിക്കഴിഞ്ഞു. ഇപ്പോൾ ഇന്ത്യയിൽ നിലവിൽ ഏറ്റവും ജനപ്രിയമായ ഇന്റർനെറ്റ് മാധ്യമം ഒപ്റ്റിക്കൽ ഫൈബർ (Fiber Internet) ആണ്. എന്നാൽ രാജ്യത്ത് സജീവ ചർച്ചയായി മാറിക്