API Reference

Last updated: October 2, 2026

The BetterReviews API lets you manage reviews, send review request links to customers, and configure collection settings. All endpoints use JSON and authenticate with a store API key.

For AI agents: Install the BetterReviews skill for Claude Code, or use this reference directly.

Authentication

Create an API key in the BetterReviews app: Settings → Developer → Create token.

Pass it in every request:

curl https://api.betterreviews.app/api/v1/reviews/stats \
  -H "X-API-Key: YOUR_API_KEY"

Send the key in the header only, never in the query string. Keys are Read-only or Read & Write. Every write endpoint — any POST, PUT, PATCH or DELETE, including creating or revoking API keys — needs a Read & Write key, and a Read-only key gets 403 with {"detail": "Insufficient scope. This endpoint requires 'write' scope."}. The exceptions are POSTs that only read, which a Read-only key can call: /reviews/search, /reviews/metrics, /reviews/nl-search, /reviews/ask, /reviews/summary and /store/email-preview. nl-search, ask and summary use AI, so a Read-only key can spend the store's AI usage. A key created by an expiring key never outlives it: its expires_at is capped at the creating key's.

Base URL

https://api.betterreviews.app/api/v1

Quick Start

Send a review link to a customer (no automated email):

curl -X POST https://api.betterreviews.app/api/v1/review-requests/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "customer@example.com",
    "customer_name": "Jane Doe",
    "product_ids": ["shopify-7125386199075"],
    "skip_email": true
  }'

Response:

{
  "ok": true,
  "request_id": 123,
  "status": "manual",
  "hub_url": "https://api.betterreviews.app/review/hub?token=..."
}

Share the hub_url with your customer. They click it, see their products, and leave reviews via AI-guided chat.


Endpoints

Review Requests

Create, list, and manage review request links.

MethodPathDescription
POST/review-requests/sendCreate review request, get hub URL
GET/review-requestsList recent review requests
DELETE/review-requests/:idCancel a review request
GET/email-requests/statsEmail funnel stats: sent, opened, clicked, bounced, conversion

Permission Requests ENTITLEMENT

Ask a reviewer for permission to feature their review in marketing, preview who will be asked (masked email only), and list every request. Requires the rights_management entitlement. Better and Studio include it; the Free plan does not, and neither does a cancelled store (cancelling returns the store to Free). On legacy plans (no longer sold), it is available on Growth and above, and on legacy Pro and Enterprise; stores on the legacy Starter plan do not have it.

MethodPathDescription
GET/reviews/:id/permission-previewIs the reviewer reachable? Masked email only
POST/reviews/:id/request-permissionEmail the reviewer asking to feature their review
GET/reviews/permission-requestsList permission requests and their answers

Conversations

Aggregate funnel stats for AI review-chat conversations: engagement buckets and origin breakdown.

MethodPathDescription
GET/conversations/statsEngagement buckets (no_show / one_and_done / mid_flow / completed / long / failed) + origin counts and rates

Reviews

List, moderate, and analyze reviews.

MethodPathDescription
GET/reviewsList reviews (filterable by status, rating, product)
GET/reviews/:idGet single review
PATCH/reviews/:id/approveApprove a pending or rejected review
PATCH/reviews/:id/rejectReject a review
DELETE/reviews/:idDelete a review
GET/reviews/statsAggregate review statistics
GET/reviews/topBest reviews for one product, ranked for marketing use or by helpfulness — SQL only, no AI cost
POST/reviews/searchHybrid (vector + keyword) search over reviews — supports date / product / category filters

Claims ENTITLEMENT

Record the marketing claims you want your reviews to support, link supporting reviews with a quoted sentence, and reserve the topic for chat collection (rolling out). Requires the claim_collection entitlement. Better and Studio include it; the Free plan does not, and neither does a cancelled store (cancelling returns the store to Free). On legacy plans (no longer sold), it is available on Growth and above, and on legacy Pro and Enterprise; stores on the legacy Starter plan do not have it.

MethodPathDescription
GET/claimsList claims (filter by product, status, collection state)
POST/claimsCreate a claim for a product
GET/claims/:idClaim with stats and linked reviews
PATCH/claims/:idEdit text, status, or toggle collection
DELETE/claims/:idArchive a claim
POST/claims/:id/reviewsLink reviews with evidence quotes
GET/claims/:id/reviewsList linked reviews
DELETE/claims/:id/reviews/:review_idUnlink a review

Review Groups ENTITLEMENT

Pool reviews across related products (variants, packs, bundles) so every member shows one combined rating. Base path /api/v1/review-groups. One group per product, 500 members per group, and a soft cap of 1,000 groups per store. Writes need a Read & Write key. Requires the review_groups entitlement. Current plans (Unlimited, Studio) include it. On legacy plans (no longer sold), it is available on Growth and above, and on legacy Pro and Enterprise; stores on the legacy Starter plan do not have it.

MethodPathDescription
GET/review-groupsList groups with member counts
GET/review-groups/memberships?product_ids=…Which group each product is in (up to 250 IDs)
GET/review-groups/:idGroup with members and each member's product_status
POST/review-groupsCreate a group (20/minute)
PATCH/review-groups/:idRename a group
DELETE/review-groups/:idDelete a group
POST/review-groups/:id/membersAdd one product (no-op if already a member)
POST/review-groups/:id/members/batchAdd up to 200 products, all-or-nothing (30/minute)
DELETE/review-groups/:id/members/:external_product_idRemove one product
POST/review-groups/:id/members/batch-removeRemove up to 200 products (30/minute)
POST/review-groups/moveMove a product to another group

MCP Server

The same review, claim, permission and product-page optimization operations as MCP tools for Claude Code, Claude Desktop and claude.ai custom connectors, plus read-only access to saved Studio creatives. Header-authenticated at /api/v1/mcp (full tool set) or via a read-only connector URL for clients that cannot send headers.

MethodPathDescription
POST/mcpMCP endpoint (Streamable HTTP, X-API-Key header)
POST/mcp/c/:tokenMCP endpoint via connector URL (read-only tools)
POST/mcp/connector-tokensMint a connector URL (shown once, 90-day expiry, max 2 active)
GET/mcp/connector-tokensList active connector tokens (prefix, last used, expiry)
DELETE/mcp/connector-tokens/:idRevoke a connector token

Product Optimizations ENTITLEMENT

Generate, edit, and publish AI-optimized product descriptions to Shopify. Requires the product_pages entitlement. Without it, write calls return 403 entitlement_required and reads return 200 with content: null. Better and Studio include it; the Free plan does not, and neither does a cancelled store (cancelling returns the store to Free). On legacy plans (no longer sold), it is available on Growth and above, and on legacy Pro and Enterprise; stores on the legacy Starter plan do not have it.

MethodPathDescription
POST/products/:id/optimizeStart AI optimization (async)
GET/products/:id/optimizationGet current optimization
PATCH/products/:id/optimizationEdit optimization content
POST/products/:id/optimization/approveApprove optimization
POST/products/:id/optimization/publishPublish to Shopify
POST/products/:id/optimization/regenerateGenerate new version
DELETE/products/:id/optimizationDiscard optimization

Brand & Content

AI-powered brand analysis and content generation from reviews.

MethodPathDescription
POST/brand/analyze-brandAnalyze brand positioning from store URL
POST/content/featuresExtract product features from reviews
POST/content/seo-descriptionGenerate SEO product description
POST/questions/generateGenerate FAQ from reviews
POST/reviews/askNatural language Q&A over reviews
POST/reviews/summaryAI summary of review themes

Products

Product catalog, metrics, and Shopify ID lookup.

MethodPathDescription
GET/productsList products with metrics
GET/products/:idGet single product
GET/products/lookup/:platform_idLook up by Shopify product ID
GET/products/status-countsOptimization status summary

Integrations

Connect Okendo, Judge.me, or Yotpo to import existing reviews, or connect the Reactiv and PDQ partner integrations.

MethodPathDescription
POST/reviews/connectConnect platform + start import
POST/reviews/disconnectDisconnect platform
GET/reviews/platforms/credentialsList active connections
POST/reviews/webhooks/subscribeRegister webhook with platform
GET/integrations/:partnerReactiv / PDQ connection state (reactiv or pdq)
POST/integrations/:partner/connectCreate the partner key, shown once ({"rotate": true} to replace)
POST/integrations/:partner/disconnectRevoke the partner key

Settings

Configure review collection and moderation rules.

MethodPathDescription
GET/store/review-settingsGet current settings
PUT/store/review-settingsUpdate settings

Product IDs

Product IDs use the format shopify-{NUMERIC_ID}. Find the numeric ID from your Shopify admin URL: admin.shopify.com/products/7125386199075 becomes shopify-7125386199075.

Plan availability

Every store is on Free ($0), Better ($149/mo, plan key unlimited) or Studio ($399/mo); there is no trial, and cancelling returns a store to Free. API access is on every plan, Free included, as are the review, import, moderation, settings, groups, review-request, metafield and stats endpoints. LLM-backed endpoints return 402 subscription_required on Free.

Error Responses

All errors return JSON with an error field:

{"error": "invalid_email"}
StatusMeaning
401Invalid or missing API key
402Active subscription required. Body: {"error": "subscription_required"}. Returned by LLM-backed endpoints (review search/ask/summary, embeddings, keyword extraction, product prepare, chatbot, conversation test/message/media, and every entitlement-gated AI endpoint) when the store is on the Free plan, or its subscription is pending, cancelled, or frozen. POST /store/send-test-email is no longer in this set — it works on any plan and does not require review collection to be switched on (only an installed, unfrozen store). Distinct from 402 credit_limit_reached on optimization publish — key on the error field, not the status.
403Entitlement required. Body: {"error": "entitlement_required", "feature": "product_pages"}. The store lacks the entitlement that endpoint requires. Better and Studio include all gated entitlements; the Free plan holds none of them except :review_groups and :api_access. On legacy plans (no longer sold), most are available on Growth and above, and on legacy Pro and Enterprise; API access itself on the older ladder is legacy Enterprise only. See each section for its legacy availability. GET /reviews/top also returns 403 with a different body — {"detail": "Store-scoped API key required"} — when the key is not bound to a single store.
403Insufficient scope. Body: {"detail": "Insufficient scope. This endpoint requires 'write' scope."} — this one uses detail, not error. A Read-only API key called a write endpoint (any POST/PUT/PATCH/DELETE except the read-only POSTs listed under Authentication); use a Read & Write key.
404Resource not found
405Method not allowed (read-only stats endpoints reject non-GET, returning Allow: GET)
409Duplicate or conflict. Review request already exists; review approve / reject return {"error": "already_actioned"} when the review is already in that state, or changed concurrently. Review groups: {"error": "name_taken", "existing_group_id": 42} when another active group already has that name, and membership_conflict (with a conflicting list) when a product is already in another group.
422Validation error. Stats endpoints return shapes like {"error": "window_too_large", "max_days": 90} and {"error": "invalid_window"}. Permission requests return already_requested, recipient_recently_asked, no_reachable_email, consent_blocked, or suppressed. Review groups return {"error": "invalid_product_id", "invalid": [...]} for product IDs that are neither numeric nor a gid://shopify/Product/ GID, too_many_groups at the 1,000-group store cap, too_many_members past 500 distinct product IDs, too_many_product_ids when a batch carries more than 200 raw IDs (duplicates count), /memberships more than 250, or create more than 1,000, and invalid_product_ids_param when product_ids is missing, not a list, or the /memberships query has another shape. At most 20 values are echoed in invalid.
429Rate limited. Every authenticated endpoint is capped at 600/minute per store; some add tighter buckets (e.g. POST /reviews/:id/request-permission: 10/minute and 200/day; its preview 120/minute; POST /review-groups: 20/minute; the two review-group batch member routes: 30/minute shared). Body: {"detail": "Rate limit exceeded"} — this status uses detail, not error.

For AI Agents

BetterReviews publishes a Claude Code skill that AI agents can install to interact with this API. The skill includes authentication setup, common workflows, and endpoint reference files.

Install in Claude Code (run in your project root):

curl -fSL https://betterreviews.app/downloads/betterreviews-api-skill.tar.gz | tar -xz -C "$(mkdir -p .claude/skills && echo .claude/skills)" && echo "Installed to .claude/skills/betterreviews-api/"

Or download the package directly and see the skill page for setup instructions.