Apify Store Scraper: Honest Ratings, Weak Leaders avatar

Apify Store Scraper: Honest Ratings, Weak Leaders

Pricing

from $2.70 / 1,000 listing analyses

Go to Apify Store
Apify Store Scraper: Honest Ratings, Weak Leaders

Apify Store Scraper: Honest Ratings, Weak Leaders

Read the Apify Store with honest ratings: listings nobody has reviewed show as unrated, never as badly rated, and a weak leader comes with its reason in plain words. Search, or filter by category, developer and pricing model, for users, runs, success rate and price on every plan.

Pricing

from $2.70 / 1,000 listing analyses

Rating

0.0

(0)

Developer

Pradio Actors

Pradio Actors

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Categories

Share

What does Apify Store Scraper do?

This Apify Store scraper shows listings nobody has reviewed as unrated, never as badly rated, and says in plain words why a popular listing is weak. Search any niche, or read a whole category, one developer's catalogue or the whole Store, and get each Actor's users, runs, success rate, rating and price on every plan.

It reads one unauthenticated public endpoint, in one run. Built for Actor developers deciding what to build next, and for anyone who wants to know who actually dominates a category.

Features

  • Unrated is kept apart from badly rated. Listings nobody has reviewed are shown as unrated, never as badly rated, so a new Actor never looks like a failing one.
  • The reason in plain words. A weak listing says why it is weak, such as "rating 3.41 over 88 reviews", a high failure rate, or a maintenance notice.
  • Only listings that match. The Store's search also returns popular listings that have nothing to do with your words; each one is checked and set aside before anything is saved or billed. Turn the check off when you want the Store's own matches.
  • The Store's own filters. Narrow a run to one category, one developer or one pricing model, or leave the search empty to read a whole category or the whole Store.
  • Five orders. Most used, best match, newest, last updated or most users of all time, and a starting position to continue a long read in the next run.
  • A usage floor. Keep only listings with at least as many users in the last 30 days as you set; the rest are never saved and never billed.
  • Usage over three windows and all time. Users over the last 7, 30 and 90 days and since launch, plus runs, builds, bookmarks and when it last ran, so you can see whether a listing is growing or fading.
  • Every run outcome. Succeeded, failed, stopped and timed-out runs over the last 30 days, and a success rate that counts timeouts against the Actor, as the platform does.
  • Price on every plan. How each Actor charges, every event it charges for, the main event's price on each Store plan from Free to Diamond, its start price, a rental's monthly price and trial, the lowest charge limit it allows, when the price last changed and whether AI agents can pay for it directly.
  • Where it ranks. Each listing's position in the Store results for your search, and the categories it is filed under.
  • One listing, one row, one charge. The Store sometimes returns the same listing twice while paging; the repeat is dropped before anything is saved or charged.
  • The denominator on every row. How many listings were examined, how many matched and whether your limit cut the search short.
  • An empty run is an answer. A run that saves nothing returns a row that says why (no listing matched, the Store had nothing for the filters, or your own filter set every match aside), and it is not charged.

How do I use Apify Store Scraper?

Setting up a run takes ten seconds, and you need nothing beyond your Apify account. Every field is ready to go, so you can press Start as it is.

Scan a niche. Every Actor matching "instagram", with its usage, rating and price:

{
"search": "instagram",
"limit": 100,
"minReviewsForRating": 3,
"onlyWeak": false
}

Find the weak leaders only. Just the listings with a real weakness signal, for "amazon reviews":

{
"search": "amazon reviews",
"limit": 100,
"onlyWeak": true
}

Read a whole category. No search, just the most used Actors filed under Lead generation that have real users:

{
"category": "LEAD_GENERATION",
"sortBy": "popularity",
"limit": 200,
"minUsers30d": 50
}

Read a competitor's whole catalogue. Every Actor one developer publishes, newest first:

{
"developer": "apify",
"sortBy": "newest",
"limit": 500
}

You get one row per relevant Actor. Here is one from a run on 28 September 2026, for "instagram" (the icon link is left out here):

{
"name": "apify/instagram-scraper",
"title": "Instagram Scraper",
"url": "https://apify.com/apify/instagram-scraper",
"users30d": 44668,
"runs30d": 17164438,
"failureRate": 0.00004783145244837029,
"rating": 4.705390594096097,
"reviewCount": 599,
"ratingState": "value",
"pricingModel": "PAY_PER_EVENT",
"notice": "NONE",
"weak": false,
"weakReasons": [],
"users7d": 24171,
"users90d": 76426,
"bookmarks": 4451,
"categories": [
"SOCIAL_MEDIA"
],
"primaryEvent": "result",
"pricePerEvent": 0.0027,
"startPrice": null,
"actorId": "shu8hvrXbJbY3Eb9W",
"developer": "apify",
"usersTotal": 408692,
"runsTotal": 201849112,
"buildsTotal": 3661,
"lastRunAt": "2026-09-28T10:24:01.660Z",
"runs30dSucceeded": 17118654,
"runs30dFailed": 821,
"runs30dAborted": 5617,
"runs30dTimedOut": 39346,
"successRate30d": 0.9973326245811253,
"priceTiers": {
"FREE": 0.0027,
"BRONZE": 0.0023,
"SILVER": 0.0019,
"GOLD": 0.0015,
"PLATINUM": 0.0009,
"DIAMOND": 0.0005
},
"chargeEvents": [
{
"event": "result",
"price": 0.0027,
"primary": true,
"oneTime": false
}
],
"pricePerUnit": null,
"trialMinutes": null,
"minChargeLimit": 0.0027,
"apifyMargin": 0.2,
"pricingSince": "2026-02-20T12:24:59.754Z",
"agentPayable": true,
"badge": null,
"rank": 2,
"searchTerm": "instagram",
"filters": {
"category": null,
"pricingModel": null,
"developer": null,
"sortBy": "popularity",
"offset": 0,
"minUsers30d": null
},
"examined": 99,
"relevant": 47,
"discarded": 52,
"capped": true,
"retrievedAt": "2026-09-28T13:53:23.072Z"
}

That is the market leader. Its rank is the Store's own search position, counted over every distinct listing the Store returned, including the ones this Actor then set aside because they do not match every word of your search. The listing the Store placed first for "instagram" did not match, so no row carries the top rank.

Its failure rate is close to zero, and its success rate is a little lower: most of its unsuccessful runs timed out rather than failed. Only the run-outcome columns show that, and the platform counts a timeout against an Actor as it counts a failure.

This is what a weakness signal looks like, from the same run:

{
"name": "apify/instagram-hashtag-scraper",
"url": "https://apify.com/apify/instagram-hashtag-scraper",
"users30d": 10052,
"rating": 3.406389274716537,
"reviewCount": 88,
"ratingState": "value",
"weak": true,
"weakReasons": ["rating 3.41 over 88 reviews"]
}

More than ten thousand people a month use it, and it is rated 3.41 across eighty-eight reviews. That is a real audience being served badly, which is the only kind of gap worth building into.

And this is what an Actor nobody has reviewed looks like, from a larger "instagram" run the same day:

{
"name": "datavoyantlab/instagram-following-scraper",
"users30d": 89,
"rating": null,
"reviewCount": 0,
"ratingState": "unrated",
"weak": false,
"weakReasons": []
}

Questions it answers before you build

"Is this niche taken?" Sort the output by users30d. If one Actor holds most of the usage and is rated above 4.5, the niche has a leader and you are picking a fight. If the usage is spread across many mid-rated listings, nobody has won it yet. Compare users7d with users90d to see whether the niche is growing.

"Is the leader actually good?" weak and weakReasons answer this. A leader with a 3.8 rating over a hundred reviews is a leader by inertia.

"Am I about to build something nobody wants?" A search that returns almost nothing is not automatically an opening. Read examined on the empty-search row: if fifty listings were read and none matched every word of your search, that is evidence nobody serves the target only when your words are the ones a buyer would type. Try a buyer's wording before concluding anything.

"What should I charge?" Read priceTiers and chargeEvents across the niche: what the main event costs on each plan, which Actors add a start fee, and pricingSince for who changed their price lately. The Pricing view in the Output tab puts them side by side.

The unrated trap

The Store API returns actorReviewRating = 0 for Actors that have never been reviewed, and a large share of the catalogue has no reviews at all. A naive rating < 4.2 filter flags every one of them as a weak incumbent. Reading the field correctly leaves them out, so only listings with real reviews can be called weak.

So this Actor reports ratingState explicitly: value, unrated, too_few_reviews or missing. An Actor nobody has reviewed is reported as unrated, never as a bad one.

Input

The form groups the fields the same way: what to read, what to keep, and how a weak listing is judged.

FieldDefaultMeaning
searchinstagram in the form, none through the APIFree-text query; leave it empty to read by the filters alone
categorynoneOnly listings filed under this Store category
pricingModelnoneOnly listings that charge this way: pay per event, free, monthly rental or pay per result
developernoneOnly listings by this developer, as written in their Store URLs
sortBypopularityThe order: most used, best match, newest, last updated, or most users of all time
limit100Listings to read before relevance filtering, up to the whole Store
offset0Skip this many listings first, to continue a long read
matchEveryWordtrueKeep only listings that contain every word of the search
minUsers30dnoneKeep only listings with at least this many users in the last 30 days
onlyWeakfalseReturn only listings with a genuine weakness signal
minReviewsForRating3Below this many reviews, rating is reported as null
weakRatingBelow4.2A rating under this counts as a weakness signal
minRunsForHealth100Below this many runs, the failure rate is still shown but cannot mark a listing weak
weakFailureRateAbove0.167A failure rate above this counts as a weakness signal

Every field is optional, so a run with no input succeeds: through the API, an empty input reads the most used listings in the whole Store.

Output

Two row shapes share the dataset. Check result to tell them apart.

A listing row, one per relevant Actor found:

FieldMeaning
nameusername/actor-name
titledisplay title
urlStore page
users30ddistinct users in the last 30 days
runs30dtotal runs in the last 30 days, or null
failureRatefailed ÷ total, or null when the total is zero
ratingonly when backed by enough reviews, else null
reviewCountnumber of reviews, or null
ratingStatevalue · unrated · too_few_reviews · missing
pricingModele.g. PAY_PER_EVENT or FREE
noticee.g. UNDER_MAINTENANCE
weakwhether any weakness signal fired
weakReasonswhich ones, in words
users7ddistinct users in the last 7 days, or null
users90ddistinct users in the last 90 days, or null
bookmarkshow many Apify users bookmarked it, or null
categoriesthe Store categories it is filed under, or null
primaryEventon a pay-per-event Actor, the event it mainly charges for, or null
pricePerEventthat event's price in USD on the free plan, or null
startPricewhat a run costs to start, in USD, or null when it lists none
actorIdthe Actor's permanent id, which survives a rename: the key to join runs from different days
developerthe developer's handle, as in the Store URL
usersTotaldistinct users since launch, or null
runsTotalruns since launch, or null
buildsTotalhow many times the developer has built it, a rough sign of upkeep, or null
lastRunAtwhen anybody last started a run of it, or null
runs30dSucceededruns in the last 30 days that succeeded, or null with no runs
runs30dFailedruns in the last 30 days that failed, or null with no runs
runs30dAbortedruns in the last 30 days that were stopped before they finished, or null with no runs
runs30dTimedOutruns in the last 30 days that ran out of time, or null with no runs
successRate30dsucceeded ÷ total, counting timed-out and stopped runs against it, or null with no runs
priceTiersthe main event's price in USD on each Store plan, from FREE to DIAMOND, or null
chargeEventsevery event it charges for: name, free-plan price, whether it is the main one, whether it is once per run
pricePerUnita monthly rental's price per month, or a pay-per-result price per result, in USD, or null
trialMinutesa monthly rental's free trial in minutes, or null
minChargeLimitthe lowest total charge limit in USD a buyer may set for one run, or null
apifyMarginthe share of the price the platform keeps, from 0 to 1, or null
pricingSincewhen the current price took effect, or null
agentPayablewhether AI agents can pay for its runs directly, or null
badgea badge the Store shows on the listing, such as risingStar, or null
pictureUrlthe link to the listing's icon, or null
rankits position in the Store results in the order you chose (most used first by default), counted before irrelevant listings are dropped; with a starting position, ranks carry on from it
searchTermthe query that produced this row, or null on a run with no search
filtersthe rest of the input that shaped the run: category, pricingModel, developer, sortBy, offset, minUsers30d
examinedhow many distinct listings were fetched before relevance filtering
relevanthow many were kept: those that matched every word, or all of them with no search or the check off
discardedexamined minus relevant
cappedtrue if the fetch stopped at your limit, so more may exist
retrievedAtwhen these numbers were read; Store figures change daily

pricePerEvent is the first price the Store page shows. Buyers on paid plans often pay less, and a free Actor has no event, so all three price columns are null there.

An empty-search row, when a run saves no listing: you get a row that says why instead of an empty dataset that could mean anything.

FieldMeaning
resultNO_RELEVANT_LISTINGS, or STOPPED_EARLY if the charge limit cut the run short
searchTermthe query that was run, or null with no search
filtersthe rest of the input, as on a listing row
examinedhow many listings were read before concluding none matched
relevant0, unless listings matched and your weak-only or usage filter set every one aside
whywhy nothing was saved: no listing matched every word, the Store had nothing for the filters, or your own filter set every match aside
interpretationhow to read a zero result
chargedfalse: no listing-analysed events. The apify-actor-start event still applies; see Pricing.
pushedon a STOPPED_EARLY row, how many listings were already analysed and saved before the limit was reached
{
"result": "NO_RELEVANT_LISTINGS",
"searchTerm": "quantum ferret grooming",
"filters": {
"category": null,
"pricingModel": null,
"developer": null,
"sortBy": "popularity",
"offset": 0,
"minUsers30d": null
},
"examined": 50,
"relevant": 0,
"why": "50 listing(s) were examined and none matched every token of \"quantum ferret grooming\". The Apify Store search parameter narrows but does not rank by relevance, so relevance is verified here against title, name and description.",
"interpretation": "No listing examined matched every word of your search. That is evidence nobody serves the target only when the words are the ones a buyer would type. An unusual phrasing can miss listings that do serve it, so try the words a buyer would use before concluding anything.",
"charged": false
}

Absent data is reported as absent (null), never disguised as a zero. That rule governs rating, runs30d, failureRate, reviewCount and every price and usage column.

Honest limits

  • Relevance is verified here, not by the API. The Store search parameter also returns listings that match only in text you cannot see: under the default order github and goodreads both return Instagram Scraper as the top result. Every word of the search must appear in the listing's title, name or description, and on most searches the greater part of the returned listings is set aside. Turn matchEveryWord off to keep them.
  • The Store's paging repeats itself. On a long read for a common word, the Store returns some listings more than once. Each repeat is dropped, so examined counts distinct listings and you pay once per listing.
  • The default order is usage, not relevance. A small listing for a common word can sit beyond your limit. Raise it, search a narrower phrase, or set sortBy to relevance.
  • There is no last-modified date on a listing in the Store API. lastRunAt measures use, not maintenance, and buildsTotal is only a rough sign of upkeep, so weakness is judged from run statistics instead. The lastUpdate order does sort by the latest change.
  • The Store sometimes returns a short page. A page can hold fewer listings than it counts, so every page is asked for in full and advanced by what actually arrived; capped says whether your limit, not the end of the Store, stopped the read.
  • No proxy required. One unauthenticated request to a documented public endpoint.
  • No personal data is collected.

Pricing

Pay per event. There are exactly two, and these are the prices the platform charges:

EventPriceWhen
listing-analysed$0.005once per listing row, and only after that row is saved in your dataset
apify-actor-start$0.00005once per gigabyte of memory, when the run starts

So a run that analyses 100 listings costs about $0.50: 100 x $0.005, plus a single start event at $0.00005. A listing the Store returns twice is still one row and one charge.

You pay for the listings that match your search, not for your limit. The limit is how many listings are read; only the rows kept are billed. A listing your usage floor or the weak-only switch sets aside is never saved and never billed either. The "instagram" run above had a limit of 100 and kept 47 matching listings, so it billed 47 rows.

$0.005 is the free-plan price. On paid plans a listing costs $0.0042 (Bronze), $0.0034 (Silver) or $0.0027 (Gold, Platinum and Diamond).

A run that finds nothing relevant charges no listing-analysed events at all. You pay the start event and nothing else.

A read of a whole category or the whole Store bills every listing it keeps, so for a wide read set a usage floor to keep only the listings people use, and set a charge limit (below).

You can cap what a run may spend. Apify has a per-run Limit total charge setting (maxTotalChargeUsd) in the run options. This Actor does not define it, the platform does, and it applies to any pay-per-event Actor. Set it and the run stops when it is reached.

When that happens you do not silently get a short dataset. The run writes a STOPPED_EARLY row naming how many listings it had already saved and how many relevant ones it had found, so a run that was cut short can never be mistaken for a market that was small. Raise the limit and re-run to see the rest.

apify-actor-start is Apify's own platform event, charged on every pay-per-event Actor rather than added by this one. It buys your run five free seconds of compute, so it usually saves more than it costs. Memory is capped at 1,024 MB in actor.json, and the start event is priced per gigabyte allocated, so the cap holds it to a single event.

How to read the numbers

You seeIt meansIt does not mean
rating: null, ratingState: "unrated"nobody has reviewed itit is bad
rating: null, ratingState: "too_few_reviews"fewer than minReviewsForRating reviewsit is bad
failureRate: nullno runs in the window, so the ratio has no denominatorit never fails
runs30d: null with users30d > 0the Store gave a user count but no run count for the window; they are two separate Store figuresnobody ran it
pricePerEvent: null on a FREE listingit has no event to priceit costs nothing to run
successRate30d well under 1 while failureRate is near 0its unsuccessful runs mostly timed out or were stoppedit works
priceTiers: null on a pay-per-event listingits main event has one price for every plan, or no main event is markedit has no price
agentPayable: falseAI agents cannot pay for it without an Apify accountagents cannot use it
weak: falseno signal fired on the data availableit is good

weak: false is the one worth dwelling on. It means nothing tripped a threshold, not that the Actor is well made. The signals are what the Store publishes; a well-marketed Actor with a bad output has no field that says so.

Questions

How current is this? Live at the moment you run it. The Store API is queried directly; nothing is cached between runs.

Why does the count change between runs? The catalogue changes, and the Store's own ordering is not stable across pages. Two runs minutes apart can return the same listings in a different order and occasionally a different count.

Can I get every Actor in the Store? Yes. Leave the search empty and raise limit to cover the whole Store, or split the read between runs with offset. Every listing kept is billed, so a usage floor (minUsers30d) keeps a wide read to the listings people use.

How do I track a competitor over time? Set developer to their handle and run it on a schedule. Join the runs on actorId, which survives a rename, and compare users30d, successRate30d, pricePerEvent and pricingSince from one run to the next.

Can I schedule it? Yes. Save your input as a task, then add a schedule from the Actor's Actions menu. A weekly schedule suits most markets; every row is stamped with retrievedAt.

Does it need a proxy or an account? Neither. One unauthenticated request to a documented public endpoint.

What if my search returns nothing? You get an empty-search row rather than an empty dataset, and it costs you no listing-analysed events. You pay only the start event, as every run does. See the shape above.

Is it legal to use? It reads the public Apify Store catalogue through Apify's own documented endpoint, the same figures any visitor sees on the Store pages, and it collects no personal data. You are responsible for having the right to read what you give it and for how you use the rows.

Where this fits with other Actors

It reads the Store; it does not read the web. When you know which listings matter, Website Content Crawler reads the pages behind them.

Integrations

This is an ordinary Apify Actor, so everything the platform offers works with it: schedule it, call it from the Apify API or the JavaScript and Python clients, wire it into Zapier, Make, n8n, Slack or a webhook, or reach it from an AI agent over MCP. Output goes to a dataset you can export as JSON, CSV or Excel.

A weekly schedule is the shape most people want: markets move slowly, and every row is stamped with retrievedAt so two runs can be compared honestly.

From code, with the JavaScript client:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('pradio/store-intel').call({ category: 'SEO_TOOLS', minUsers30d: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Found a problem?

Report it on the Issues tab. A bug report with the search term you used and the row that looked wrong is enough. The run id helps and is not required.

Two things worth reporting that people usually do not: a listing this scored weak that you know is good, and a listing it scored fine that you know is not. Both are threshold problems rather than bugs, and thresholds only move when somebody says so.

If this Actor saved you time, a review on the Store helps other buyers find it; problems go to the Issues tab.

Unofficial

Not affiliated with or endorsed by Apify. It reads the same public catalogue endpoint any visitor can.

Release notes

  • 2026-09-28: new inputs to read by category, developer and pricing model, in five orders, from a starting position, with a usage floor and the word check as a switch; the search is now optional, so a run can read a whole category or the whole Store. New columns: every 30-day run outcome and a success rate, all-time users, runs and builds, the last run, the main event's price on every plan, every charge event, rental price and trial, the lowest charge limit, when the price last changed, whether agents can pay, the badge, the icon and the Actor's id. A busy moment at the Store is retried rather than failing the run, and a short page from the Store no longer reads as the end of the market. A listing the Store returns twice in one long read is returned and billed once. Earlier columns added the same day: rank, users7d, users90d, bookmarks, categories, primaryEvent, pricePerEvent and startPrice.
  • 2026-08-19: first release. One row per Store listing for a search term, with users, rating, reviews and price, and a score for how the listing is doing.