Use code AFTERPARTY for 25% off your first 12 months. Limited to the first 25 sign-ups.
For developers

Show your Zenvents360 reviews on your own website

Zenvents360 publishes a read-only feed of the client reviews a business has chosen to publish. Your website reads it on a schedule and adds new reviews as drafts the owner approves. It suits static sites (Astro, Next.js, Hugo, Eleventy) that rebuild through GitHub and CI, and nothing on the website needs to accept incoming requests.

Using an AI coding tool? In Zenvents360, go to Admin > Integrations > Reviews on your website and press Copy AI setup prompt. Paste it into Claude Code, Cursor or a similar tool working on your site: it carries the feed address and points the tool at this page.

1. Get the feed address

The business owner (or an admin) turns on Publish my reviews feed under Admin > Integrations > Reviews on your website, and copies the address. The last part of the address is the feed key. It is read-only, and the owner can replace it at any time with New address, which stops the old one at once.

Treat the key like a password: store it as a secret (for example a GitHub Actions secret named ZENVENTS_REVIEWS_FEED_KEY), never in the repository.

2. The JSON feed

GET https://app.zenvents360.com/api/public/reviews/{FEED_KEY}.json?since={ISO8601}&limit={1-100}
  • since (optional): returns only reviews created, edited or withdrawn after this time, oldest first. Leave it out on the first run to get every published review.
  • limit (optional): 1 to 100, default 50.
  • Rate limit: about 60 requests an hour per address. Checking hourly is plenty.
  • Errors: 401 means the key is wrong, was replaced, or the feed was turned off. 429 means you are checking too often: wait and retry.
{
  "business": { "name": "Harbor Light Photography", "url": "https://harborlight.example" },
  "generated_at": "2026-11-05T14:00:00Z",
  "next_since": "2026-11-05T13:58:12.481920Z",
  "has_more": false,
  "reviews": [
    {
      "id": "8f1c2d7e-…",
      "status": "published",
      "updated_at": "2026-11-05T13:58:12.481920Z",
      "title": "Every photo felt like us",
      "excerpt": "We were nervous about posed shots, and there were barely any. Somehow every…",
      "content": "Full review text.\n\nParagraphs are separated by blank lines.",
      "rating": 5,
      "reviewer": { "name": "Jordan & Sam R.", "role": "Couple" },
      "event": { "name": "Rivera wedding", "date": "2026-10-03", "type": "Wedding" },
      "venue": {
        "name": "Grand Hall", "city": "Kingston", "region": "NY",
        "slug": "grand-hall", "city_slug": "kingston", "region_slug": "ny",
        "url": "https://…"
      },
      "photo": { "url": "https://…/review-8f1c.jpg", "alt": null },
      "source": { "name": "The Knot", "url": "https://…" }
    },
    { "id": "2a90b4c1-…", "status": "withdrawn", "updated_at": "2026-11-05T12:00:00.000000Z" }
  ]
}

Fields

idStable for the life of the review. Key everything on it.
statuspublished, or withdrawn (the business unpublished it, or the reviewer withdrew consent). A withdrawn review must come off the site. A withdrawn id you have never seen can be ignored.
updated_atChanges whenever the review is edited or withdrawn.
title, contentPlain text. content uses blank lines between paragraphs.
excerptThe opening of the review, up to about 220 characters, cut at a word. Can be null.
rating1 to 5.
reviewerName and role (Couple, Parent, Planner, Corporate client…) exactly as the reviewer agreed to be shown.
eventName, date (YYYY-MM-DD) and type.
venueCan be null. Slugs are provided for venue, city and region pages.
photoCan be null. alt is null for now: write your own. Download it; don’t hotlink.
sourceSet only when the review came from another site (Google, The Knot, WeddingWire). Otherwise null.
next_sincePass this as since on your next call. Keep it exactly as given: it carries microseconds.
has_moretrue means call again right away with next_since.

Never included: the reviewer's email, phone or any other contact or private detail. Reviews imported from a business's old WordPress site are left out, since that site already has them.

3. The RSS version

GET https://app.zenvents360.com/api/public/reviews/{FEED_KEY}.rss

The same live reviews as RSS 2.0, newest first (up to 50), for tools that read RSS: Zapier, Make, IFTTT, or a reviews widget in a site builder. Each item carries the review id as its guid, a title, the text with the star rating and reviewer's name, a publish date, the event type as a category, and the photo as an enclosure when there is one.

RSS has no way to say "take this one down": a withdrawn review simply drops out of the list. If your site copies reviews into its own pages, use the JSON feed, which reports withdrawals.

4. What the website builds

A scheduled job

For a site built through GitHub, a scheduled GitHub Action works well. Run it hourly, and on workflow_dispatch so it can be run by hand.

  1. Read a cursor file, for example .zenvents/reviews-cursor.json holding { "since": "…" }. If it doesn't exist, call without since.
  2. Call the feed with since. While has_more is true, call again with next_since.
  3. For each published review, write or update one content file named by its id (frontmatter below, draft: true for a new review), and download the photo next to your other images.
  4. For each withdrawn review, delete its file and image.
  5. If anything changed, save the last next_since to the cursor file, commit to a fixed branch, and open one pull request ("New reviews from Zenvents360"), or update it if it is already open.
  6. If nothing changed, do nothing: no commit, no pull request.
---
id: 8f1c2d7e-…
title: Every photo felt like us
excerpt: We were nervous about posed shots…
rating: 5
reviewer_name: Jordan & Sam R.
reviewer_role: Couple
event_name: Rivera wedding
event_date: 2026-10-03
event_type: Wedding
venue_name: Grand Hall
venue_city: Kingston
venue_region: NY
venue_slug: grand-hall
photo: /images/reviews/8f1c2d7e.jpg
photo_alt: First look on the Grand Hall terrace
source_name: The Knot
source_url: https://…
zenvents_updated_at: 2026-11-05T13:58:12.481920Z
draft: true
---
Full review text.

Paragraphs are separated by blank lines.

Drafts stay drafts

The site's pages skip any review with draft: true. The owner approves a review by setting draft: false and merging the pull request, and the site's existing build publishes it.

Never overwrite the owner's edits

Once a review is approved, the owner may have edited it. After that, an update from the feed:

  • may change the rating, photo, photo alt text and zenvents_updated_at;
  • must not change the text, title or excerpt, and must not set it back to a draft;
  • must still delete the review if it comes through as withdrawn.

If an approved review's text changes in Zenvents360, mention it in the pull request so the owner can decide.

Optional: star ratings in search

On pages that show reviews, add Review and AggregateRating structured data (JSON-LD) built from the approved reviews only.

Questions

Something missing for your site? Tell us. The business owner can also find these steps from the Reviews on your website card in Zenvents360.