Updated Oct 2026
Klaviyo Reviews API in Python: private key, revision header, published reviews
Klaviyo Reviews lives inside Klaviyo’s main API: JSON:API responses, a private key with scopes, a mandatory revision header and cursor paging. Reading is straightforward; the only write is moderation, not replies. This guide reads reviews with requests, following developers.klaviyo.com, which is also how Prisma’s Klaviyo connector works (in beta, built from the spec). The store-platform picture is on e-commerce reviews API.
pip install requestsCredentials: a private API key (Settings → API keys → Create private key, custom scope with Reviews read and Accounts read).
1. List reviews, newest update first
import os, requests
API = "https://a.klaviyo.com/api"
H = {"Authorization": f"Klaviyo-API-Key {os.environ['KLAVIYO_PRIVATE_KEY']}", "revision": "2025-10-15", "Accept": "application/vnd.api+json"}
def reviews():
url = f"{API}/reviews?sort=-updated&page[size]=100"
while url:
r = requests.get(url, headers=H, timeout=30)
r.raise_for_status()
body = r.json()
yield from body.get("data", [])
url = (body.get("links") or {}).get("next")
for rev in reviews():
a = rev["attributes"]
status = ((a.get("status") or {}).get("value") or "").lower()
if a.get("review_type") == "question" or status not in ("published", "featured"):
continue # what shoppers see: published or featured reviews, not questions
reply = (a.get("public_reply") or {}).get("content")
print(rev["id"], a.get("rating"), a.get("author"), a.get("title"), (a.get("content") or "")[:80], a["updated"], (a.get("product") or {}).get("url"), "| replied" if reply else "")Attributes: rating (1 to 5), title, content, author, created, updated, status.value (published, featured, pending, rejected…), review_type (review or question), product.url and public_reply with content and updated when the merchant answered. The revision header pins the API version; use a current date from Klaviyo’s changelog.
2. Incremental sync
Because the list is sorted by -updated, stop paging the moment you see an updated older than your last sync; edits and new public replies bump updated, so they come back.
3. What the API won’t do
No reply endpoint: PATCH /api/reviews/{id} only changes moderation status. Replies are written in Klaviyo and arrive in public_reply.
4. The same job through Prisma
Prisma connects a Klaviyo account with the private key (checked before storing, encrypted), syncs published and featured reviews, skips questions, returns the public reply in the same shape as every other platform and sends a webhook per new review. One key covers Klaviyo plus Judge.me, Yotpo, Loox, Google and 50+ more.
H = {"Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}"}
r = requests.get("https://api.prismareviews.com/v1/reviews", headers=H, params={"platform": "klaviyo", "has_reply": "false", "limit": 100}, timeout=30)
for rev in r.json()["data"]:
print(rev["rating"], rev["author"], rev["title"], rev["text"], rev["url"])Klaviyo is read-only in Prisma, like on Klaviyo, and in beta. Connection fields: Platforms. A test key returns sample reviews so the code runs now.
FAQ
Which Klaviyo API key do I need for reviews?
A private API key (Settings → API keys → Create private key) with a custom scope that includes Reviews read and Accounts read. It’s sent as Authorization: Klaviyo-API-Key <key>, and every request needs the revision header with an API version date.
Can I reply to Klaviyo reviews by API?
No. The only write on a review is its moderation status (PATCH /api/reviews/{id}). The merchant’s public reply is written in Klaviyo and returned in the public_reply attribute.
How do I page through Klaviyo reviews?
Cursor pagination: request page[size]=100 and follow links.next until it’s null. Sorting by -updated lets you stop as soon as you reach a review older than your last sync.
Klaviyo, Judge.me, Yotpo and Google, one key.
2 locations free. Test keys return sample reviews from every platform.