API Reference

Complete documentation for integrating with NativeProof. Access reviews, submit data, and connect with your storefront using our App Proxy endpoints.

Introduction

The NativeProof API allows you to interact with product reviews on your Shopify storefront. All API access is provided through Shopify's App Proxy, which means requests are authenticated automatically using Shopify's OAuth infrastructure.

No Separate API Key Required

NativeProof uses Shopify's built-in App Proxy authentication. All requests through your store's /apps/reviews endpoint are automatically authenticated with your shop's session.

What You Can Do

  • Submit new product reviews from your storefront
  • Retrieve reviews for any product by handle
  • Get aggregate rating statistics
  • Access the Google Shopping XML feed

Authentication

NativeProof uses Shopify's App Proxy for all storefront API calls. This means:

  • Automatic authentication: Requests through your store's proxy URL include Shopify's HMAC signature
  • Shop context: The shop domain is automatically determined from the proxy request
  • No API keys to manage: Authentication is handled by Shopify's infrastructure
Important

App Proxy endpoints are only accessible through your Shopify store's domain. Direct API calls to the app server will be rejected. Always use your store's /apps/reviews path.

Base URL

All API requests are made through Shopify's App Proxy at your store's domain:

Base URL
https://your-store.myshopify.com/apps/reviews

Replace your-store.myshopify.com with your actual Shopify store domain. If you have a custom domain, that will work too:

Custom Domain
https://www.yourstore.com/apps/reviews

App Proxy Endpoints

POST /apps/reviews/submit

Submit a new review for a product from your storefront. Reviews are stored in your database and synced to Shopify Metaobjects for server-side rendering.

Request Parameters

Parameter Type Description
product_handlerequired string The product's URL handle (e.g., "classic-leather-jacket")
ratingrequired integer Star rating from 1 to 5
titlerequired string Review title (max 200 characters)
bodyrequired string Review content (max 5000 characters)
author_namerequired string Display name of the reviewer
author_emailrequired string Email address (hashed and stored securely)
photos[]optional file[] Array of image files (max 5, each up to 10MB)
videooptional file Video file (max 100MB, uploaded to Cloudflare Stream)

Code Examples

curl -X POST https://your-store.myshopify.com/apps/reviews/submit \
  -H "Content-Type: application/json" \
  -d '{
    "product_handle": "classic-leather-jacket",
    "rating": 5,
    "title": "Amazing quality!",
    "body": "This jacket exceeded my expectations. The leather is soft and the fit is perfect.",
    "author_name": "John D.",
    "author_email": "john@example.com"
  }'
const response = await fetch('/apps/reviews/submit', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    product_handle: 'classic-leather-jacket',
    rating: 5,
    title: 'Amazing quality!',
    body: 'This jacket exceeded my expectations.',
    author_name: 'John D.',
    author_email: 'john@example.com'
  })
});

const data = await response.json();
console.log(data);
// { success: true, review_id: "rv_abc123..." }
Response
JSON
{
  "success": true,
  "review_id": "rv_abc123def456",
  "message": "Review submitted successfully",
  "status": "pending"
}
GET /apps/reviews/product/{handle}

Retrieve all reviews for a specific product. Returns paginated results with optional filtering and sorting.

Path Parameters

Parameter Type Description
handlerequired string The product's URL handle

Query Parameters

Parameter Type Description
pageoptional integer Page number (default: 1)
per_pageoptional integer Results per page (default: 10, max: 50)
sortoptional string Sort order: "newest", "oldest", "highest", "lowest" (default: "newest")
min_ratingoptional integer Filter reviews with rating >= this value (1-5)

Code Examples

curl "https://your-store.myshopify.com/apps/reviews/product/classic-leather-jacket?page=1&per_page=10&sort=newest"
const productHandle = 'classic-leather-jacket';
const params = new URLSearchParams({
  page: '1',
  per_page: '10',
  sort: 'newest'
});

const response = await fetch(
  `/apps/reviews/product/${productHandle}?${params}`
);

const data = await response.json();
console.log(data.reviews);
// Array of review objects
Response
JSON
{
  "reviews": [
    {
      "id": "rv_abc123def456",
      "product_handle": "classic-leather-jacket",
      "rating": 5,
      "title": "Amazing quality!",
      "body": "This jacket exceeded my expectations.",
      "author_name": "John D.",
      "verified": true,
      "photos": ["https://cdn.shopify.com/..."],
      "video_url": null,
      "created_at": "2025-01-07T10:30:00Z"
    }
  ],
  "total": 47,
  "page": 1,
  "per_page": 10,
  "total_pages": 5
}
GET /apps/reviews/aggregate/{handle}

Get aggregate rating statistics for a product, including average rating, total count, and star distribution.

Path Parameters

Parameter Type Description
handlerequired string The product's URL handle

Code Examples

curl "https://your-store.myshopify.com/apps/reviews/aggregate/classic-leather-jacket"
const response = await fetch(
  '/apps/reviews/aggregate/classic-leather-jacket'
);

const stats = await response.json();
console.log(`Average: ${stats.average} (${stats.count} reviews)`);
Response
JSON
{
  "average": 4.7,
  "count": 47,
  "distribution": {
    "5": 32,
    "4": 10,
    "3": 3,
    "2": 1,
    "1": 1
  }
}

Webhooks

NativeProof listens to Shopify webhooks to provide features like verified buyer detection and GDPR compliance. These webhooks are automatically registered when you install the app.

Automatic Registration

You don't need to configure webhooks manually. NativeProof automatically registers and handles all required webhooks during installation.

Webhook Events

orders/create
Triggered when a new order is placed. Used to detect verified buyers by matching customer emails against review submissions.
app/uninstalled
Triggered when the app is uninstalled. Performs cleanup operations and preserves review data for potential reinstallation.
customers/data_request
GDPR compliance webhook. Returns all stored data associated with a customer's email address.
customers/redact
GDPR compliance webhook. Anonymizes or deletes customer data upon request. Review content is preserved but personal information is removed.
shop/redact
GDPR compliance webhook. Triggered 48 hours after app uninstall to completely remove all shop data from our systems.
Webhook Security

All webhooks are verified using HMAC-SHA256 signatures with your app's secret key. Invalid signatures are rejected, preventing unauthorized data access.

Metaobject Schema

Reviews are stored in Shopify Metaobjects for zero-latency server-side rendering. This schema is automatically created when you install the app.

Review Metaobject Fields

product_handle
single_line_text_field
rating
number_integer
title
single_line_text_field
content
multi_line_text_field
author_name
single_line_text_field
verified
boolean
source
single_line_text_field
video_url
url
review_date
date_time
Automatic Sync

When reviews are approved in the NativeProof admin, they're automatically synced to Shopify Metaobjects. This enables theme-native rendering without JavaScript hydration.

Google Shopping Feed

NativeProof automatically generates a Google Product Review XML feed that conforms to Google Merchant Center specifications.

GET /apps/reviews/feed.xml

Access your Google Product Review XML feed. This feed is updated in real-time as reviews are approved.

Feed Specifications

  • Format: Google Product Review XML
  • Update Frequency: Real-time (generated on request)
  • Syndicated Reviews: Marked with ZZ country code per Google guidelines
  • Caching: 15-minute edge cache for performance

Example Feed URL

URL
https://your-store.myshopify.com/apps/reviews/feed.xml

Sample XML Structure

XML
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <version>2.3</version>
  <publisher>
    <name>Your Store Name</name>
  </publisher>
  <reviews>
    <review>
      <review_id>rv_abc123</review_id>
      <reviewer>
        <name>John D.</name>
      </reviewer>
      <review_timestamp>2025-01-07T10:30:00Z</review_timestamp>
      <title>Amazing quality!</title>
      <content>This jacket exceeded my expectations.</content>
      <ratings>
        <overall min="1" max="5">5</overall>
      </ratings>
      <products>
        <product>
          <product_ids>
            <gtins>
              <gtin>1234567890123</gtin>
            </gtins>
          </product_ids>
          <product_name>Classic Leather Jacket</product_name>
        </product>
      </products>
      <is_spam>false</is_spam>
    </review>
  </reviews>
</feed>

Rate Limits

To ensure fair usage and maintain service quality, the following rate limits apply:

Endpoint Type Limit Window
App Proxy (GET requests) 100 requests Per minute, per shop
Review Submission 10 requests Per minute, per IP address
Google Feed 60 requests Per hour, per shop
Rate Limit Headers

When you exceed rate limits, the API returns a 429 Too Many Requests response. Check the Retry-After header to know when you can retry.

Error Codes

The API uses standard HTTP status codes to indicate success or failure of requests.

Code Status Description
400 Bad Request Validation error. Check the response body for specific field errors. Common causes: missing required fields, invalid rating value, email format.
401 Unauthorized Request is not coming through the Shopify App Proxy or has an invalid HMAC signature.
404 Not Found The requested product handle does not exist or has no reviews.
429 Too Many Requests Rate limit exceeded. Wait for the time specified in the Retry-After header.
500 Internal Server Error An unexpected error occurred. If this persists, contact support.

Error Response Format

JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "fields": {
      "rating": "Rating must be between 1 and 5",
      "author_email": "Invalid email format"
    }
  }
}