Documentation

Technical guides for your integration – multi-channel, widgets, API and Shopware.

Multi-channel / Locations

With the locations feature you can collect and analyse reviews separately by branch, sales channel or region. Each location has its own name, slug, an optional domain and a default language.

Plan limits: FREE = 1 location, STARTER = 2, PRO = 10, ENTERPRISE = 100

When should you use locations?

Locations are ideal if you:

  • run several branches or offices
  • have different online shops or domains
  • want to separate reviews by region or department
  • want to embed a separate widget per location on the respective website

Managing locations

Under Settings → Locations you can create, edit and delete locations.

  • Name: Display name (e.g. “London Soho branch”)
  • Slug: Unique identifier, generated automatically from the name
  • Domain: Optional – the website URL of the location
  • Language: Default language for this location
  • Default location: The location marked as default is used for new reviews without an explicit assignment

When you delete a location, all assigned reviews are kept – they only lose their location assignment.

How are reviews assigned to a location?

There are three ways:

  1. Automatically via the review form: If your company has several locations, a dropdown “Which location would you like to review?” appears on the profile page – the customer selects the location.
  2. Via review invitations: When sending an invitation you can specify the location. The review is then assigned automatically.
  3. Via API: Pass the locationId when creating a review.

Widgets per location

In the widget builder under Settings → Location filter you can restrict a widget to a specific location. The widget then only shows reviews of that location.

For example, the website of your London branch can show only the London reviews and the Manchester page only the Manchester ones.

API reference

Create a location:

POST /api/locations
{
  "name": "Online Shop UK",
  "slug": "shop-uk",
  "domain": "https://www.my-shop.co.uk",
  "language": "en"
}

Create a review assigned to a location:

POST /api/reviews
{
  "companyId": "...",
  "locationId": "clx...",
  "rating": 5,
  "content": "Great service!",
  "reviewerName": "John Smith"
}

Filter reviews by location:

GET /api/reviews?companyId=...&locationId=...
// Returns only reviews of the given location
// Without locationId all reviews are returned

Create a widget with a location filter:

POST /api/widget
{
  "companyId": "...",
  "locationId": "clx...",
  "name": "Widget London branch",
  "type": "CAROUSEL",
  "config": { "maxReviews": 5 }
}

Multilingual widgets

The embedded widget supports 5 languages: Deutsch, English, Français, Español and Italiano. All UI texts (buttons, time labels, form fields) are shown automatically in the detected language.

Language detection (priority)

  1. data-lang attribute on the widget container (explicit)
  2. locale field in the widget configuration (dashboard)
  3. document.documentElement.lang (HTML language of the page)
  4. Fallback: de

Option 1: Explicitly via HTML attribute

Ideal for multilingual shops where the language of each page is known:

HTML
<!-- German widget -->
<div data-zoom-widget="WIDGET_ID" data-lang="de"></div>

<!-- English widget -->
<div data-zoom-widget="WIDGET_ID" data-lang="en"></div>

<!-- French widget -->
<div data-zoom-widget="WIDGET_ID" data-lang="fr"></div>

<script src="https://zoom.reviews/widget.js" async></script>

Option 2: Automatically via the shop language

If your shop template sets the lang attribute on the <html> tag correctly, the widget detects the language automatically:

HTML
<html lang="fr">
  ...
  <div data-zoom-widget="WIDGET_ID"></div>
  <script src="https://zoom.reviews/widget.js" async></script>
</html>

Option 3: Via dashboard configuration

Under Widgets → Edit → Settings you can set a fixed language per widget. This is useful if you create a separate widget for each shop or language channel.

Shopware / Twig example

Twig (Shopware 6)
{# In your theme template #}
<div data-zoom-widget="WIDGET_ID" 
     data-lang="{{ app.request.locale[:2] }}"></div>
<script src="https://zoom.reviews/widget.js" async></script>

Integrity check (SRI)

If your security policies require it, you can embed a fixed version with Subresource Integrity instead of the self-updating widget.js. Before executing it, the browser then checks via hash that the script exactly matches the published version, and blocks it otherwise.

HTML
<div data-zoom-widget="WIDGET_ID"></div>
<script src="https://zoom.reviews/widget/v1.js"
        integrity="sha384-b+jQQNJZZso+gHv6OrEFQWf3CnUlnPR95LwStglzZ9EDIhLlhwIEMunoVr+X1GKT"
        crossorigin="anonymous" async></script>

Fixed versions do not receive automatic updates or bug fixes. When we release a new version, you need to replace the snippet yourself. We notify you by email about changes so that you can replace the snippet in time. You can always find the current snippet under Widgets → Embed code.

Available from Pro

Review invitations (post-purchase)

Automatically send review invitations to your customers after a purchase. The emails are multilingual (DE/EN/FR/ES/IT) and contain a personalised link.

Available from: Pro plan (100 invitations/day) · Enterprise (1,000 invitations/day)

Create a single invitation

POST /api/review-invitations
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{
  "email": "customer@example.com",
  "customerName": "John Smith",
  "orderId": "ORD-10042",
  "orderDate": "2026-07-28T14:30:00Z",
  "locale": "en",
  "locationId": "clx...",
  "delayDays": 7
}
ParameterRequiredDescription
emailYesCustomer's email address
customerNameYesCustomer's name
orderIdNoOrder number (for matching)
localeNoLanguage of the email (de/en/fr/es/it)
locationIdNoLocation ID for the assignment
delayDaysNoDelay in days (0 = immediately, default: 7)

Batch invitations (up to 100 at once)

POST /api/review-invitations
{
  "invitations": [
    { "email": "a@example.com", "customerName": "Anna", "locale": "de" },
    { "email": "b@example.com", "customerName": "Bob", "locale": "en" },
    { "email": "c@example.com", "customerName": "Claire", "locale": "fr" }
  ]
}

What the customer experiences

  1. The customer receives a personalised email with a review link
  2. The link opens your review page with the name pre-filled
  3. The review is automatically marked as verified (no captcha)
  4. The token can only be used once

List invitations

GET /api/review-invitations?status=SENT&page=1
// Status: PENDING, SENT, OPENED, COMPLETED, EXPIRED
Available from Enterprise

Outgoing webhooks

Receive real-time notifications about new reviews and invitations. Webhooks are signed with HMAC-SHA256.

Enterprise plan only. Up to 10 webhook endpoints per company.

Available events

EventDescription
review.createdNew review submitted
review.approvedReview approved
review.rejectedReview rejected
invitation.sentInvitation sent
invitation.completedInvitation completed (review submitted)

Create a webhook

POST /api/webhooks/outgoing
{
  "url": "https://your-server.com/webhooks/zoom-reviews",
  "events": ["review.created", "review.approved"]
}

The response contains a secret (shown only once!) used to verify the signature.

Payload format

POST to your URL
// Headers:
// X-Webhook-Signature: <HMAC-SHA256 of body>
// X-Webhook-Event: review.created
// X-Webhook-Timestamp: 2026-07-29T18:30:00.000Z

{
  "event": "review.created",
  "data": {
    "id": "clx...",
    "rating": 5,
    "reviewerName": "John Smith",
    "source": "WIDGET",
    "locationId": "clx..."
  },
  "timestamp": "2026-07-29T18:30:00.000Z"
}

Verify the signature

Node.js
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Management

Under Settings → Webhooks (coming soon) or via API:

  • GET /api/webhooks/outgoing — List all endpoints
  • PATCH /api/webhooks/outgoing — Change URL/events/status
  • DELETE /api/webhooks/outgoing?id=... — Delete an endpoint
Available from Pro

Shopware 6 integration

Automatic review invitations after order completion in your Shopware 6 shop. The integration automatically detects the order language and the sales channel.

Overview

Step 1

Configure the webhook URL in Shopware

Step 2

Choose a Flow Builder event

Step 3

Set delay & language

Method A: Shopware Flow Builder (recommended)

  1. In your Shopware admin, go to Settings → Flow Builder
  2. Create a new flow with the trigger Order placed or Order status changed → Completed
  3. Add a Send HTTP request action
  4. Method: POST
  5. URL: your webhook URL (see integration settings)
  6. Content-Type: application/json

Method B: Call the REST API directly

Alternatively, you can call the review invitation API directly from a custom plugin or app:

POST /api/review-invitations
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

{
  "email": "{{ order.orderCustomer.email }}",
  "customerName": "{{ order.orderCustomer.firstName }} {{ order.orderCustomer.lastName }}",
  "orderId": "{{ order.orderNumber }}",
  "locale": "en",
  "delayDays": 7
}

Multi-shop / multi-channel

If you run several Shopware sales channels:

  • Create one location per sales channel in Zoom.Reviews
  • Pass the locationId in the API request
  • Reviews are then collected separately and shown per channel

Language detection

The Shopware integration automatically detects the order language from the order's locale field. Supported: de, en, fr, es, it. Falls back to the configured default language.

Embed the widget in your Shopware theme

Twig template (e.g. footer.html.twig)
{# Widget with automatic language detection #}
<div data-zoom-widget="WIDGET_ID" 
     data-lang="{{ app.request.locale[:2] }}">
</div>
<script src="https://zoom.reviews/widget.js" async></script>

Tip: Create a separate widget with the corresponding locationId for each sales channel. That way each shop only shows its own reviews.

Ready to integrate?

Start for free and embed your first reviews in just a few minutes.

Start for free