Marketplace / Docs / Reviews

Reviews & Ratings

How reviews and ratings work in the Singularity Marketplace.

Jump to section

How reviews and ratings work in the Singularity Marketplace — the data model, the API surface, and what's planned for the web UI.


Overview

Reviews let any authenticated publisher rate and write about a package they've installed. Each review carries a 1-5 star rating, an optional title and body, and a created/updated timestamp. Publishers can respond to reviews on their own packages; readers can vote a review helpful or unhelpful; the community can flag reviews for moderation.

The review system is fully implemented in the registry backend (packages/registry/src/singularity_registry/api/reviews.py). Today it is reachable via the REST API; a web UI surface is in development.


UI Status

Note: The marketplace web UI does not yet render reviews on package detail pages. The API documented below is live and writable today — a web surface for reading and writing reviews is planned. Once it ships, this section will be replaced with click-through instructions.

If you're a publisher who wants to gather feedback in the meantime, point users at the API endpoints below or wait for the UI release.


Star Ratings

Reviews use a 1-to-5 integer star rating. The registry enforces this at the schema level (rating: int = Field(..., ge=1, le=5)), so values outside that range are rejected with a 400. There is no half-star rating today.

Aggregate ratings (the average that surfaces on the publisher's analytics dashboard as Avg Rating) are computed across all visible reviews on the publisher's packages.


Writing a Review

To create a review, send an authenticated POST to the package's reviews endpoint:

POST /api/v1/packages/{publisher_name}/{package_name}/reviews
Authorization: Bearer <token-or-api-key>
Content-Type: application/json

{
  "rating": 4,
  "title": "Solid tool — saved me hours",
  "body": "Used this in production for two weeks; only nit is the verbose default logging."
}

Field rules:

  • rating — required integer, 1-5.
  • title — optional, max 256 characters.
  • body — optional, max 5000 characters.

Each publisher can have one review per package — POSTing again from the same publisher updates the existing review rather than creating a duplicate.


Listing Reviews

GET /api/v1/packages/{publisher_name}/{package_name}/reviews?page=1&per_page=20

The response is a paginated list with a rating_distribution summary:

{
  "reviews": [{ "id": "...", "rating": 4, "title": "...", "body": "...", "reviewer_name": "...", "helpful_count": 3, ... }],
  "total": 42,
  "page": 1,
  "per_page": 20,
  "total_pages": 3,
  "rating_distribution": { "5": 18, "4": 12, "3": 8, "2": 3, "1": 1 }
}

Each review object includes the rating, title, body, reviewer name/display name, helpful/unhelpful counts, the publisher's response (if any), and timestamps. No authentication is required to list reviews.


Updating or Deleting Your Review

PATCH /api/v1/reviews/{review_id}
DELETE /api/v1/reviews/{review_id}

PATCH accepts any subset of rating, title, body. The review is flagged with is_edited: true once changed. DELETE removes it permanently. Both require you to be the original author (or an admin).


Voting on Reviews

Readers can mark a review helpful or unhelpful:

POST /api/v1/reviews/{review_id}/vote
{ "helpful": true }

Vote tallies appear on the review object as helpful_count and unhelpful_count. The API records one vote per publisher per review; re-voting changes your existing vote rather than stacking.


Publisher Responses

If you're the publisher of the package being reviewed, you can attach a single response:

POST /api/v1/reviews/{review_id}/respond
{ "body": "Thanks for the feedback — the verbose logging is fixed in 1.3.0." }

The response body has a minimum of 1 character and maximum of 5000. Posting again updates the same response (one per review). Responses are visible inline with the review and surface response_body + response_at fields in the listing endpoint.

Publisher responses are a powerful trust signal — use them to acknowledge bugs, point at fixes, and answer follow-up questions.


Flagging Inappropriate Reviews

If a review violates the marketplace's content policy (spam, harassment, off-topic), flag it for moderator review:

POST /api/v1/reviews/{review_id}/flag
{ "reason": "This review contains personal attacks against the author." }

The reason field is required (5-1000 characters). Flagged reviews enter the moderation queue at GET /api/v1/admin/reviews/flagged; moderators can hide (with a public reason) or unflag (dismiss the report).

Don't flag a review because it's negative — flag it because it's abusive, fraudulent, or off-topic.


Aggregate Ratings

Average ratings flow into two places today:

  • Publisher analytics — the Avg Rating stat card on /dashboard/analytics shows your portfolio-wide average. See the Analytics Dashboard guide.
  • Package metadata — packages carry their own rolling average, computed across visible reviews. This is what other surfaces will display when they're rolled out.

Once the package-page UI lands, expect to see the average plus a rating_distribution histogram on every package detail page.


Tips for Good Reviews

  • Be specific. "Great tool!" is less useful than "Worked for me on macOS 14 with the default profile; documentation could be clearer about the --strict flag."
  • Mention the version. Bugs and quirks are version-bound — 1.2.0 may behave very differently from 1.0.0. A version reference helps both the publisher and future readers.
  • Edit, don't pile on. If a maintainer fixes the thing you complained about, edit your review instead of leaving a stale negative one. The is_edited flag makes your update visible.
  • Respect the response. Publisher responses count — give them a chance to react before re-rating downward.
  • Don't review packages you haven't used. It's enforced socially, not technically; bad-faith reviews can be flagged.