API Reference

Agency Plan

The RatingsRise REST API gives you programmatic access to your businesses, reviews, customers, review requests, and analytics. Build custom integrations, automate workflows, and embed review data directly into your own applications.

Base URL

https://app.ratingsrise.com/api/v1/

All endpoints return JSON. All request bodies must be JSON with a Content-Type: application/json header.

Authentication

All API requests require a Bearer token in the Authorization header. API keys are scoped to your organization and can be created from Settings > API Keys in the RatingsRise dashboard.

Authorization: Bearer sk_live_your_api_key_here

Security tip: Keep your API keys secret. Never expose them in client-side code, public repositories, or frontend bundles. Use environment variables on your server.

Keys prefixed with sk_live_ access production data. sk_test_ keys access the sandbox environment and will not trigger real SMS or email sends.

Rate Limits

The API enforces a rate limit of 100 requests per minute per API key. When you exceed the limit, the API returns a 429 Too Many Requests response. Use the response headers to track your usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute (100)
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp when the rate limit window resets
Retry-AfterSeconds to wait before retrying (only present on 429 responses)
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1700000060
Retry-After: 23

{
  "error": "Rate limit exceeded. Please retry after 23 seconds.",
  "code": "RATE_LIMIT_EXCEEDED"
}

Error Format

All errors return a consistent JSON body with an error message, a machine-readable code, and an optional details object for validation errors.

{
  "error": "Validation failed",
  "code": "VALIDATION_ERROR",
  "details": {
    "customerEmail": "Must be a valid email address",
    "method": "Must be one of: sms, email, whatsapp"
  }
}

Common Status Codes

StatusCodeDescription
400VALIDATION_ERRORRequest body or query parameters are invalid
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key does not have permission for this resource
404NOT_FOUNDThe requested resource does not exist
429RATE_LIMIT_EXCEEDEDToo many requests — slow down and retry
500INTERNAL_ERRORAn unexpected server error occurred — contact support

Pagination

List endpoints support cursor-based pagination with these query parameters:

NameTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
perPageintegerOptionalItems per page (default: 25, max: 100)

Paginated responses include a pagination object alongside the data array:

{
  "data": [ ... ],
  "pagination": {
    "page": 1,
    "perPage": 25,
    "total": 142,
    "totalPages": 6
  }
}

Code Examples

Quick-start examples showing authentication and fetching reviews in JavaScript and Python.

JavaScript (fetch)

const API_KEY = process.env.RATINGSRISE_API_KEY;
const BASE_URL = "https://app.ratingsrise.com/api/v1";

async function listReviews(businessId) {
  const response = await fetch(
    `${BASE_URL}/reviews?businessId=${businessId}&perPage=10`,
    {
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API error: ${error.code} — ${error.error}`);
  }

  return response.json();
}

// Usage
const { data: reviews, pagination } = await listReviews("biz_abc123");
console.log(`Found ${pagination.total} reviews`);
reviews.forEach((r) => console.log(`${r.rating}★ — ${r.content}`));

Python (requests)

import os
import requests

API_KEY = os.environ["RATINGSRISE_API_KEY"]
BASE_URL = "https://app.ratingsrise.com/api/v1"

def list_reviews(business_id: str, per_page: int = 10) -> dict:
    response = requests.get(
        f"{BASE_URL}/reviews",
        params={"businessId": business_id, "perPage": per_page},
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
    )
    response.raise_for_status()
    return response.json()

# Usage
result = list_reviews("biz_abc123")
print(f"Found {result['pagination']['total']} reviews")
for review in result["data"]:
    print(f"{review['rating']}★ — {review['content']}")

Businesses

GET/api/v1/businesses

Returns a paginated list of all business locations in your organization.

NameTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
perPageintegerOptionalItems per page (default: 25, max: 100)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/businesses?perPage=2" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "data": [
    {
      "id": "biz_abc123",
      "name": "Joe's Coffee Shop",
      "address": "123 Main St, Austin, TX 78701",
      "phone": "+15125551234",
      "googlePlaceId": "ChIJrTLr-GyuEmsRBfy61i59si0",
      "averageRating": 4.6,
      "totalReviews": 142,
      "platforms": ["google", "yelp"],
      "createdAt": "2024-01-15T08:30:00Z",
      "updatedAt": "2024-11-20T14:22:00Z"
    },
    {
      "id": "biz_def456",
      "name": "Joe's Coffee — Downtown",
      "address": "456 Congress Ave, Austin, TX 78701",
      "phone": "+15125555678",
      "googlePlaceId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
      "averageRating": 4.8,
      "totalReviews": 89,
      "platforms": ["google"],
      "createdAt": "2024-03-01T10:00:00Z",
      "updatedAt": "2024-11-19T09:15:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "perPage": 2,
    "total": 5,
    "totalPages": 3
  }
}
GET/api/v1/businesses/:id

Retrieves detailed information for a single business location.

NameTypeRequiredDescription
idstringRequiredThe business ID (e.g. biz_abc123)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/businesses/biz_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "id": "biz_abc123",
  "name": "Joe's Coffee Shop",
  "address": "123 Main St, Austin, TX 78701",
  "phone": "+15125551234",
  "website": "https://joescoffee.com",
  "googlePlaceId": "ChIJrTLr-GyuEmsRBfy61i59si0",
  "averageRating": 4.6,
  "totalReviews": 142,
  "platforms": ["google", "yelp"],
  "reviewBreakdown": {
    "5": 89,
    "4": 31,
    "3": 12,
    "2": 6,
    "1": 4
  },
  "sentimentBreakdown": {
    "positive": 112,
    "neutral": 20,
    "negative": 10
  },
  "createdAt": "2024-01-15T08:30:00Z",
  "updatedAt": "2024-11-20T14:22:00Z"
}

Reviews

GET/api/v1/reviews

Returns a paginated list of reviews across all or a specific business. Supports filtering by platform, rating, sentiment, and date range.

NameTypeRequiredDescription
businessIdstringOptionalFilter by business ID
platformstringOptionalFilter by platform: google, yelp, facebook, tripadvisor
ratingintegerOptionalFilter by star rating (1-5)
sentimentstringOptionalFilter by AI sentiment: positive, neutral, negative
dateFromstringOptionalStart date (ISO 8601, e.g. 2024-01-01)
dateTostringOptionalEnd date (ISO 8601, e.g. 2024-12-31)
pageintegerOptionalPage number (default: 1)
perPageintegerOptionalItems per page (default: 25, max: 100)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/reviews?businessId=biz_abc123&rating=5&perPage=2" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "data": [
    {
      "id": "rev_xyz789",
      "businessId": "biz_abc123",
      "platform": "google",
      "rating": 5,
      "content": "Best coffee in Austin! The pour-over is incredible and the staff is super friendly. Will definitely be back.",
      "authorName": "Sarah M.",
      "authorAvatar": "https://lh3.googleusercontent.com/a/example",
      "sentiment": "positive",
      "sentimentScore": 0.94,
      "reply": null,
      "repliedAt": null,
      "publishedAt": "2024-11-18T09:30:00Z",
      "importedAt": "2024-11-18T10:00:00Z"
    },
    {
      "id": "rev_uvw456",
      "businessId": "biz_abc123",
      "platform": "google",
      "rating": 5,
      "content": "Amazing latte art and the pastries are always fresh. This is my go-to spot every morning.",
      "authorName": "Michael R.",
      "authorAvatar": "https://lh3.googleusercontent.com/a/example2",
      "sentiment": "positive",
      "sentimentScore": 0.91,
      "reply": "Thank you, Michael! We're thrilled you enjoy our lattes and pastries. See you tomorrow morning!",
      "repliedAt": "2024-11-17T15:45:00Z",
      "publishedAt": "2024-11-17T12:00:00Z",
      "importedAt": "2024-11-17T12:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "perPage": 2,
    "total": 89,
    "totalPages": 45
  }
}
GET/api/v1/reviews/:id

Retrieves a single review by its ID, including full content and reply status.

NameTypeRequiredDescription
idstringRequiredThe review ID (e.g. rev_xyz789)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/reviews/rev_xyz789" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "id": "rev_xyz789",
  "businessId": "biz_abc123",
  "platform": "google",
  "rating": 5,
  "content": "Best coffee in Austin! The pour-over is incredible and the staff is super friendly. Will definitely be back.",
  "authorName": "Sarah M.",
  "authorAvatar": "https://lh3.googleusercontent.com/a/example",
  "sentiment": "positive",
  "sentimentScore": 0.94,
  "keywords": ["coffee", "pour-over", "staff", "friendly"],
  "reply": null,
  "repliedAt": null,
  "publishedAt": "2024-11-18T09:30:00Z",
  "importedAt": "2024-11-18T10:00:00Z"
}
POST/api/v1/reviews/:id/reply

Publishes a reply to a review. The reply is posted directly to the review platform (e.g., Google) on behalf of the business.

NameTypeRequiredDescription
idstringRequiredThe review ID to reply to (path parameter)
contentstringRequiredThe reply text (max 4096 characters)

Example Request

curl -X POST "https://app.ratingsrise.com/api/v1/reviews/rev_xyz789/reply" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Thank you so much, Sarah! We are glad you loved the pour-over. Our baristas take great pride in every cup. See you again soon!"
  }'

Example Response

{
  "id": "rev_xyz789",
  "businessId": "biz_abc123",
  "platform": "google",
  "rating": 5,
  "content": "Best coffee in Austin! The pour-over is incredible and the staff is super friendly. Will definitely be back.",
  "authorName": "Sarah M.",
  "reply": "Thank you so much, Sarah! We are glad you loved the pour-over. Our baristas take great pride in every cup. See you again soon!",
  "repliedAt": "2024-11-20T16:30:00Z",
  "publishedAt": "2024-11-18T09:30:00Z"
}

Customers

GET/api/v1/customers

Returns a paginated list of customers. Filter by business, search by name or email, or filter by tags.

NameTypeRequiredDescription
businessIdstringOptionalFilter by business ID
searchstringOptionalSearch by customer name or email (case-insensitive partial match)
tagsstringOptionalComma-separated list of tags to filter by (e.g. vip,loyal)
pageintegerOptionalPage number (default: 1)
perPageintegerOptionalItems per page (default: 25, max: 100)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/customers?businessId=biz_abc123&tags=vip&perPage=2" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "data": [
    {
      "id": "cust_001",
      "businessId": "biz_abc123",
      "name": "Emily Johnson",
      "email": "emily@example.com",
      "phone": "+15125559876",
      "tags": ["vip", "loyal"],
      "notes": "Regular customer — comes in every weekday morning.",
      "reviewRequestsSent": 3,
      "reviewsLeft": 1,
      "lastVisit": "2024-11-19T08:15:00Z",
      "createdAt": "2024-02-10T14:00:00Z",
      "updatedAt": "2024-11-19T08:15:00Z"
    },
    {
      "id": "cust_002",
      "businessId": "biz_abc123",
      "name": "David Chen",
      "email": "david.chen@example.com",
      "phone": "+15125554321",
      "tags": ["vip"],
      "notes": null,
      "reviewRequestsSent": 1,
      "reviewsLeft": 1,
      "lastVisit": "2024-11-15T12:30:00Z",
      "createdAt": "2024-06-05T09:00:00Z",
      "updatedAt": "2024-11-15T12:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "perPage": 2,
    "total": 18,
    "totalPages": 9
  }
}
POST/api/v1/customers

Creates a new customer record. At minimum, a name is required. Email or phone is recommended for sending review requests.

NameTypeRequiredDescription
namestringRequiredCustomer full name
emailstringOptionalCustomer email address
phonestringOptionalCustomer phone in E.164 format (e.g. +15125551234)
tagsstring[]OptionalArray of tags (e.g. ["vip", "new"])
notesstringOptionalInternal notes about the customer

Example Request

curl -X POST "https://app.ratingsrise.com/api/v1/customers" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jessica Williams",
    "email": "jessica@example.com",
    "phone": "+15125557890",
    "tags": ["new", "walk-in"],
    "notes": "Referred by Emily Johnson."
  }'

Example Response

{
  "id": "cust_003",
  "businessId": "biz_abc123",
  "name": "Jessica Williams",
  "email": "jessica@example.com",
  "phone": "+15125557890",
  "tags": ["new", "walk-in"],
  "notes": "Referred by Emily Johnson.",
  "reviewRequestsSent": 0,
  "reviewsLeft": 0,
  "lastVisit": null,
  "createdAt": "2024-11-20T17:00:00Z",
  "updatedAt": "2024-11-20T17:00:00Z"
}
PUT/api/v1/customers/:id

Updates an existing customer. Only include the fields you want to change; omitted fields remain unchanged.

NameTypeRequiredDescription
idstringRequiredThe customer ID (path parameter)
namestringOptionalUpdated customer name
emailstringOptionalUpdated email address
phonestringOptionalUpdated phone in E.164 format
tagsstring[]OptionalReplaces all tags with the provided array
notesstringOptionalUpdated internal notes

Example Request

curl -X PUT "https://app.ratingsrise.com/api/v1/customers/cust_003" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "tags": ["vip", "walk-in"],
    "notes": "Upgraded to VIP after third visit. Referred by Emily Johnson."
  }'

Example Response

{
  "id": "cust_003",
  "businessId": "biz_abc123",
  "name": "Jessica Williams",
  "email": "jessica@example.com",
  "phone": "+15125557890",
  "tags": ["vip", "walk-in"],
  "notes": "Upgraded to VIP after third visit. Referred by Emily Johnson.",
  "reviewRequestsSent": 0,
  "reviewsLeft": 0,
  "lastVisit": null,
  "createdAt": "2024-11-20T17:00:00Z",
  "updatedAt": "2024-11-20T17:45:00Z"
}

Review Requests

POST/api/v1/review-requests

Sends a review request to a customer via SMS, email, or WhatsApp. The message includes a personalized link to leave a review.

NameTypeRequiredDescription
customerNamestringRequiredThe recipient's name (used for personalization)
customerEmailstringOptionalEmail address (required if method is email)
customerPhonestringOptionalPhone number in E.164 format (required if method is sms or whatsapp)
methodstringRequiredDelivery method: sms, email, or whatsapp
businessIdstringOptionalTarget business ID (defaults to primary business)
templateIdstringOptionalCustom template ID (uses default template if omitted)

Example Request

curl -X POST "https://app.ratingsrise.com/api/v1/review-requests" \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "customerName": "Jessica Williams",
    "customerEmail": "jessica@example.com",
    "customerPhone": "+15125557890",
    "method": "sms",
    "businessId": "biz_abc123"
  }'

Example Response

{
  "id": "rr_98765",
  "businessId": "biz_abc123",
  "customerId": "cust_003",
  "customerName": "Jessica Williams",
  "method": "sms",
  "status": "sent",
  "reviewLink": "https://app.ratingsrise.com/r/abc123xyz",
  "sentAt": "2024-11-20T18:00:00Z",
  "openedAt": null,
  "completedAt": null,
  "createdAt": "2024-11-20T18:00:00Z"
}
GET/api/v1/review-requests

Returns a paginated list of review requests with status tracking. Filter by delivery method or current status.

NameTypeRequiredDescription
statusstringOptionalFilter by status: pending, sent, opened, completed, failed
methodstringOptionalFilter by method: sms, email, whatsapp
businessIdstringOptionalFilter by business ID
pageintegerOptionalPage number (default: 1)
perPageintegerOptionalItems per page (default: 25, max: 100)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/review-requests?status=completed&method=sms&perPage=2" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "data": [
    {
      "id": "rr_98760",
      "businessId": "biz_abc123",
      "customerId": "cust_001",
      "customerName": "Emily Johnson",
      "method": "sms",
      "status": "completed",
      "reviewLink": "https://app.ratingsrise.com/r/def456uvw",
      "sentAt": "2024-11-15T10:00:00Z",
      "openedAt": "2024-11-15T10:05:00Z",
      "completedAt": "2024-11-15T10:12:00Z",
      "createdAt": "2024-11-15T10:00:00Z"
    },
    {
      "id": "rr_98755",
      "businessId": "biz_abc123",
      "customerId": "cust_002",
      "customerName": "David Chen",
      "method": "sms",
      "status": "completed",
      "reviewLink": "https://app.ratingsrise.com/r/ghi789rst",
      "sentAt": "2024-11-10T14:30:00Z",
      "openedAt": "2024-11-10T14:45:00Z",
      "completedAt": "2024-11-10T15:00:00Z",
      "createdAt": "2024-11-10T14:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "perPage": 2,
    "total": 34,
    "totalPages": 17
  }
}

Analytics

GET/api/v1/analytics/overview

Returns high-level dashboard metrics for your organization, including total reviews, average rating, response rate, and request conversion.

NameTypeRequiredDescription
businessIdstringOptionalScope metrics to a specific business (omit for org-wide)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/analytics/overview?businessId=biz_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "businessId": "biz_abc123",
  "period": "all_time",
  "metrics": {
    "totalReviews": 142,
    "averageRating": 4.6,
    "responseRate": 0.87,
    "averageResponseTime": "2h 15m",
    "totalRequestsSent": 210,
    "requestConversionRate": 0.42,
    "sentimentBreakdown": {
      "positive": 112,
      "neutral": 20,
      "negative": 10
    },
    "platformBreakdown": {
      "google": 128,
      "yelp": 14
    },
    "reviewsThisMonth": 18,
    "ratingChangeThisMonth": 0.1
  }
}
GET/api/v1/analytics/ratings

Returns monthly average rating data for charting trends over time. Useful for building dashboards and reports.

NameTypeRequiredDescription
monthsintegerOptionalNumber of months to look back (default: 6, max: 24)
businessIdstringOptionalScope to a specific business (omit for org-wide)

Example Request

curl -X GET "https://app.ratingsrise.com/api/v1/analytics/ratings?months=6&businessId=biz_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key_here"

Example Response

{
  "businessId": "biz_abc123",
  "months": 6,
  "data": [
    { "month": "2024-06", "averageRating": 4.3, "reviewCount": 12 },
    { "month": "2024-07", "averageRating": 4.4, "reviewCount": 15 },
    { "month": "2024-08", "averageRating": 4.5, "reviewCount": 19 },
    { "month": "2024-09", "averageRating": 4.5, "reviewCount": 22 },
    { "month": "2024-10", "averageRating": 4.7, "reviewCount": 25 },
    { "month": "2024-11", "averageRating": 4.6, "reviewCount": 18 }
  ]
}

Webhooks

Webhooks let you receive real-time HTTP POST notifications when events happen in your RatingsRise account. Configure webhook endpoints from Settings > Webhooks in the dashboard.

Events

EventDescription
review.createdA new review is imported from any connected platform
review.updatedAn existing review is modified (rating change, content edit, or reply added)
request.completedA customer completes a review request by submitting a review
payment.receivedA subscription payment is successfully processed

Payload Format

Every webhook delivery sends a JSON POST body with the following structure:

{
  "id": "wh_evt_abc123",
  "event": "review.created",
  "data": {
    "id": "rev_xyz789",
    "businessId": "biz_abc123",
    "platform": "google",
    "rating": 5,
    "content": "Best coffee in Austin!",
    "authorName": "Sarah M.",
    "sentiment": "positive",
    "publishedAt": "2024-11-18T09:30:00Z"
  },
  "timestamp": "2024-11-18T10:00:05Z"
}

Signature Verification

Every webhook request includes an X-RatingsRise-Signature header containing an HMAC-SHA256 signature of the raw request body. Verify this signature using your webhook secret (found in Settings > Webhooks) to ensure the request originated from RatingsRise.

Node.js Verification

import crypto from "crypto";

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload, "utf-8")
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler (e.g. Express / Next.js API route):
app.post("/webhooks/ratingsrise", (req, res) => {
  const signature = req.headers["x-ratingsrise-signature"] as string;
  const rawBody = JSON.stringify(req.body);

  if (!verifyWebhookSignature(rawBody, signature, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = req.body;
  console.log(`Received event: ${event.event}`, event.data);

  // Process the event...
  res.status(200).json({ received: true });
});

Python Verification

import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode("utf-8"),
        payload,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

@app.route("/webhooks/ratingsrise", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-RatingsRise-Signature", "")
    raw_body = request.get_data()

    if not verify_signature(raw_body, signature, WEBHOOK_SECRET):
        return jsonify({"error": "Invalid signature"}), 401

    event = request.get_json()
    print(f"Received event: {event['event']}", event["data"])

    # Process the event...
    return jsonify({"received": True}), 200

Retry Behavior

If your endpoint returns a non-2xx status code or times out (30 seconds), RatingsRise retries the delivery up to 3 times with exponential backoff:

AttemptDelay After Failure
1st retry1 minute
2nd retry5 minutes
3rd retry25 minutes

After all retries are exhausted, the event is marked as failed. You can view failed deliveries and manually retry them from the Webhooks settings page.

Ready to integrate?

Create your RatingsRise account and generate an API key to start building. The API is available on the Agency plan.