G2 Latest Reviews Monitor
Pricing
from $1.50 / 1,000 reviews
G2 Latest Reviews Monitor
Collects the latest G2 product reviews from public RSS feeds. No login, no browser, no residential proxy. Built for incremental monitoring, not full review history.
Pricing
from $1.50 / 1,000 reviews
Rating
0.0
(0)
Developer
OrbitData Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Collects the latest reviews G2 publishes on each product's public RSS feed and returns them as flat rows, ready for JSON, CSV or Excel.
It is built for monitoring: run it on a schedule, keep an eye on what people are saying about your product and your competitors', and pull only what is new since last time.
How it works
The actor reads the public RSS feed G2 serves for a product:
https://www.g2.com/products/{product}/reviews.rss
That feed is open. In the checks run for this actor it answered without a login, without cookies, without a browser and without a proxy — including from a datacenter IP. Nothing is bypassed and no private page is touched: the actor asks for the same feed a feed reader would.
What it is not
This is a monitor, not an archive. G2's public feed is a snapshot of recent reviews with no way to page back through older ones, so:
- the default feed carries roughly the 25 most recent reviews of a product
- asking for more also reads the per-rating feeds and merges them, which brings in more recent reviews — but they overlap, so the number of distinct reviews you actually get depends on the product
maxReviewsPerProductaccepts up to 125. That is a ceiling, not a promise: a quiet product may return a handful of reviews, and a busy one will not return its older history either- if you need every review a product has ever received, this actor is the wrong tool
Input
One product
{ "products": ["slack"] }
A product URL works just as well; only the slug is kept.
{ "products": ["https://www.g2.com/products/slack/reviews"] }
Several products, filtered and incremental
{"products": ["slack", "asana", "https://www.g2.com/products/notion/reviews"],"maxReviewsPerProduct": 50,"ratings": [1, 1.5, 2],"publishedAfter": "2026-08-01T00:00:00Z","knownReviewIds": ["13357798", "13357612"],"includeReviewerName": false,"maxTotalReviews": 500,"requestConcurrency": 3}
Input fields
| Field | Type | Default | Description |
|---|---|---|---|
products | array of strings | — (required) | Product slugs or G2 product URLs, 1–100 entries. A product listed twice is collected once. The URL you type is never stored or logged; only the slug is kept. |
maxReviewsPerProduct | integer | 25 | Reviews to keep per product, newest first. 1–125. Up to 25 reads the default feed only; above 25 also reads the per-rating feeds. |
ratings | array of numbers | not set | Keep only these displayed star ratings: 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5. Omit to keep every rating. An empty array is rejected. |
publishedAfter | string | not set | ISO 8601 with a time zone, e.g. 2026-08-01T00:00:00Z. Keeps reviews published strictly after this moment. |
knownReviewIds | array of strings | [] | Review IDs you already have; matching reviews are skipped and never charged. Up to 10,000 entries. |
includeReviewerName | boolean | false | Off by default. Turn on only if you need the public display name and may store it. |
maxTotalReviews | integer | 1000 | Ceiling on stored reviews for the whole run, so a run's price stays predictable. 1–10,000. |
requestConcurrency | integer | 3 | Feed requests in flight at once across the whole run. 1–5. |
Bad input is rejected before the run charges anything or fetches anything.
Star ratings are the stars on the review
You pick real star values. G2's own feed filter works in coarser bands, so the
actor uses those bands only to fetch candidates and then re-checks every review
against the rating it actually displays. Asking for 5 gives you 5-star
reviews, not 4.5-star ones. A review whose rating cannot be read is left out when
a rating filter is set — it is never rounded or guessed.
Incremental runs
Two fields let a scheduled run pick up where the last one stopped:
publishedAfter— strictly greater than. Pass the newestpublishedAtyour last run returned and you continue from exactly there, with no repeat of the boundary review. A review with no publication date is skipped while this filter is set.knownReviewIds— pass thereviewIdvalues you already stored. Send the most recent ones; the list is capped at 10,000.
Either one on its own works. Using both is fine.
Output
One flat row per review in the default dataset. The run summary — per-product
status and the counts from every filtering stage — is stored separately under
the OUTPUT key of the key-value store, so the dataset stays pure review rows.
| Field | Type | Description |
|---|---|---|
productSlug | string | Product the review belongs to. |
productName | string | null | Product name from the feed. |
productUrl | string | Canonical G2 reviews page. |
reviewId | string | null | Numeric ID taken from the review URL. Pass these back as knownReviewIds. |
reviewUrl | string | Canonical URL of the review. |
title | string | null | Review headline. |
rating | number | null | Stars shown on the review: 0–5 in steps of 0.5. |
pros | string | null | What the reviewer likes best. |
cons | string | null | What the reviewer dislikes. |
problemsSolved | string | null | What problems the product solves for them. |
publishedAt | string | null | ISO 8601 timestamp in UTC. |
reviewerRole | string | null | Public role label, e.g. G2 User. |
companySize | string | null | Public band, e.g. 2-10 employees. |
reviewerName | string | null | Public display name. null unless includeReviewerName is on. |
source | string | Always g2-rss. |
About the nulls
A field is null when the feed did not publish it. The actor never fills a gap
with a guess: an unreadable date stays null rather than becoming the collection
time, a missing rating stays null rather than being inferred, and a review ID
appears only when it can be read from the review URL. reviewerRole is usually
present; companySize is published for most reviews but not all.
Every row is flat, so CSV and Excel exports are plain columns with no nested objects to unpack.
Pricing
Pay per event:
| Event | Price |
|---|---|
actor-start | $0.01 per run |
review-saved | $0.002 per successfully stored review |
The most a run can cost:
$0.01 + (reviews stored x $0.002)
| Reviews stored | Maximum cost | Shown as |
|---|---|---|
| 1 | $0.012 | $0.02 |
| 25 | $0.06 | $0.06 |
| 1,000 | $2.01 | $2.01 |
The actor rounds the ceiling it prints up to the whole cent, so the figure you
see is never lower than what you pay. You are billed on the exact arithmetic,
not on the rounded figure. The actor prints its own ceiling at the start of every run,
worked out from maxReviewsPerProduct, the number of products and
maxTotalReviews, before it fetches anything.
What you are not charged for
A review is charged only after the dataset has accepted it. You pay nothing for:
- reviews that arrived from more than one feed (duplicates)
- reviews excluded by your rating filter
- reviews excluded by
publishedAfter - reviews excluded by
knownReviewIds - products that returned no reviews
- products that could not be found
- reviews that failed to store
- any failed request or failed product
The start event is the exception: it is charged once per run, including a run
that ends up storing no reviews at all. Keep maxTotalReviews in line with
what you actually want so the ceiling stays where you expect it.
If storing succeeds but the charge does not go through, the reviews stay in your dataset and the run reports them as uncharged. The reverse — charging for something that was not stored — cannot happen.
Scheduling
A monitoring setup usually looks like this:
- Run once with
publishedAfterset to where you want to start. - Store the newest
publishedAtyou received. - Schedule the actor (Apify Console → Schedules, e.g. daily at 07:00) with
that value in
publishedAfter. - After each run, move
publishedAfterforward to the newestpublishedAtin the results.
If you prefer to track IDs, keep the reviewId values instead and pass the most
recent of them as knownReviewIds. Either way, reviews you already have are
skipped and not charged.
Run status
Each product ends in one of these states, reported in the run summary:
| Status | Meaning |
|---|---|
succeeded | Every planned feed answered and reviews were kept. |
partial | Some feeds answered, others failed. What was collected is kept. |
no_reviews | Feeds answered fine, but nothing survived your filters — or the product has no reviews. Not an error. |
invalid_product | G2 has no such product. |
blocked | The request was refused. |
rate_limited | Too many requests; the actor waited and retried. |
temporary_error | A server or network problem, or the product ran out of time. |
parse_error | The feed came back but could not be read as RSS. |
One failing product does not stop the others. The run as a whole succeeds if every product succeeded or had no reviews, is partial if some worked, and fails only if every product failed.
Exporting
Results export straight to JSON, CSV, Excel, XML or HTML table from the Apify Console, or through the API. Every field is a plain column.
Limitations
Worth knowing before you rely on it:
- The feed is a snapshot. There is no paging back through older reviews.
- The default feed carries roughly the 25 most recent reviews. Merging the per-rating feeds adds more recent candidates, but they overlap heavily, so the number of distinct reviews varies by product.
- 125 per product is a ceiling, not an amount you should expect.
- Products are processed one at a time, in the order you list them, so run time grows with the number of products.
- A restarted run may repeat work. Within a single process the actor never
stores or charges for the same review twice, but if the platform restarts the
run, or a request's outcome is unknown, duplicates are possible. Use
knownReviewIdsorpublishedAfterto control this yourself. Automatic state between runs is a candidate for a later version. knownReviewIdsholds at most 10,000 entries. Send the most recent ones.- The actor depends on G2's public feed. If its structure changes, parsing
may need an update; watch for
parse_errorin the run summary. includeReviewerNameputs personal data in your dataset. Turning it on makes you responsible for handling that data lawfully.- You are responsible for your own compliance with G2's terms and any laws that apply to you.
Privacy
Reviewer display names are left out unless you ask for them. The run summary and the logs hold counts, HTTP statuses and response hashes only — never review text, review URLs, review IDs, reviewer names or the product URLs you typed.
Troubleshooting
A product returns invalid_product. Check the slug in the G2 URL:
https://www.g2.com/products/<slug>/reviews. The actor takes only the slug, so a
typo in it is the usual cause.
Fewer reviews than maxReviewsPerProduct. Expected. The feed only carries
recent reviews, and the per-rating feeds overlap. Check collected and the
per-stage counts in the run summary to see where reviews went.
Everything filtered out. Look at filteredOutByRating, filteredOutByDate
and filteredOutByKnownId in the summary. A publishedAfter in the future, or a
rating filter no recent review matches, empties the result.
rating is null. The feed did not show a rating for that review. The actor
leaves it empty rather than guessing, and a rating filter excludes such reviews.
blocked or rate_limited. Lower requestConcurrency and try again later.
Duplicates across runs. Pass the reviewId values you already have as
knownReviewIds, or move publishedAfter forward.
Support
Questions and issues: open an issue on the actor's page in Apify Console.
This actor is an independent tool. It is not affiliated with, endorsed by or connected to G2, and it does not use any G2 API.