# Changelog of G2 Latest Reviews Monitor (`huggable_quote/g2-reviews-monitor`) Actor

- **URL**: https://apify.com/huggable\_quote/g2-reviews-monitor/changelog.md
- **Full Actor documentation**: https://apify.com/huggable\_quote/g2-reviews-monitor.md

## Changelog

All notable changes to this actor are recorded here. This project follows
[semantic versioning](https://semver.org/).

### 0.1.0 — unreleased

First working version. Not yet published to Apify Store.

#### Added

- Collects the latest G2 reviews from the public product RSS feed
  (`/products/{slug}/reviews.rss`), with no login, browser or proxy.
- Accepts product slugs or G2 product URLs, up to 100 products per run. A
  product listed twice is collected once; only the validated slug is kept.
- Flat output of 15 fields per review, suitable for JSON, CSV and Excel export.
- Star rating filter on the rating each review actually displays, in steps of
  0.5. G2's coarser feed bands are used only to fetch candidates; every review is
  re-checked against its displayed rating.
- Incremental collection through `publishedAfter` (strictly after the given
  instant, compared in UTC) and `knownReviewIds` (up to 10,000 IDs).
- Deduplication across feeds by review ID and by normalised review URL. Where
  copies of one review name exactly one ID, a copy that lacks it adopts that
  verified ID; conflicting identities are counted and never merged.
- Per-product limit, a run-wide review ceiling and a maximum price worked out
  and logged before the first request.
- Pay-per-event billing: `actor-start` and `review-saved`. A review is charged
  only after the dataset has accepted it. Duplicates, filtered-out reviews, empty
  results, unknown products and failed stores are not charged.
- Run summary written to the `OUTPUT` key of the key-value store, with
  per-product status and the counts from every filtering stage. The dataset holds
  review rows only.
- Per-product error classification: `succeeded`, `partial`, `no_reviews`,
  `invalid_product`, `blocked`, `rate_limited`, `temporary_error`, `parse_error`.
  One failing product does not stop the rest of the run.
- Retries with exponential backoff for temporary failures, honouring
  `Retry-After` on rate limits, capped at 60 seconds.
- Run-wide request concurrency limit (1–5, default 3) shared by all products.
- Reviewer display names excluded by default.

#### Known limitations

- The public feed is a snapshot with no paging. The default feed carries roughly
  the 25 most recent reviews; merging the per-rating feeds adds more recent
  candidates, but they overlap, so the number of distinct reviews varies by
  product. `maxReviewsPerProduct` accepts up to 125 as a ceiling, not a promise.
  Full review history is out of scope.
- Products are processed sequentially, so run time grows with the number of
  products.
- Duplicate storage and duplicate charging are prevented within a single
  process, but not across a platform restart or a request whose outcome is
  unknown. Use `knownReviewIds` or `publishedAfter` to control this.
- `knownReviewIds` is capped at 10,000 entries; automatic state between runs is a
  candidate for a later version.
- Parsing depends on the structure of G2's public feed and may need updating if
  that structure changes.
