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.
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
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:
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:
https://www.yourstore.com/apps/reviews
App Proxy Endpoints
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..." }
{
"success": true,
"review_id": "rv_abc123def456",
"message": "Review submitted successfully",
"status": "pending"
}
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
{
"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 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)`);
{
"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.
You don't need to configure webhooks manually. NativeProof automatically registers and handles all required webhooks during installation.
Webhook Events
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
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.
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
ZZcountry code per Google guidelines - Caching: 15-minute edge cache for performance
Example Feed URL
https://your-store.myshopify.com/apps/reviews/feed.xml
Sample XML Structure
<?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 |
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
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"fields": {
"rating": "Rating must be between 1 and 5",
"author_email": "Invalid email format"
}
}
}