---
description: Public reference for the SyncMyReviews Zapier API: authentication, REST-hook triggers, searches, write actions, error codes, and delivery guarantees.
title: Zapier API Reference | SyncMyReviews
image: https://res.cloudinary.com/de3yzjwhk/image/upload/v1774523070/seo/og_image.jpg
---

Developer reference

# SyncMyReviews Zapier API

This is the complete REST surface the SyncMyReviews app on Zapier calls. It covers authentication, the seven REST-hook triggers, two searches, four write actions, and the dropdowns that populate the Zap editor. Everything here is read-only reference material — no account is required to view it.

## Overview

All Zapier endpoints live under the `/api/zapier` prefix on the production API host. There is no sandbox tier: the integration talks to production only.

| Base URL     | https://api.syncmyreviews.com                                                                                                                                     |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Transport    | HTTPS only. Plain HTTP is not served.                                                                                                                             |
| Content type | application/json for request and response bodies.                                                                                                                 |
| Timestamps   | ISO 8601, UTC.                                                                                                                                                    |
| Tenancy      | Every query is scoped to the account that owns the token. An id belonging to another account is indistinguishable from one that does not exist — both return 404. |

Google and Facebook are connected on the SyncMyReviews side. The Zapier app never talks to those platforms directly; it only calls the endpoints on this page.

## Authentication

The integration uses a SyncMyReviews-issued API token sent as a bearer credential. Account owners mint the token from **Connections → Zapier** in the dashboard; the plaintext value is shown exactly once and is stored only as a hash. Members cannot generate tokens.

```
Authorization: Bearer <syncmyreviews-token>
Accept: application/json
```

A token carries two abilities. Read endpoints (including subscribe and unsubscribe) require `zapier:read`; the four write actions additionally require `zapier:write`.

### GET `/api/zapier/auth/test`

Called immediately after the user pastes a token. A `200` confirms the credential, and `connection_label` is what Zapier shows as the connection name.

```
{
  "account_id": 1234,
  "account_name": "Acme Coffee Group",
  "connection_label": "Acme Coffee Group",
  "token_last_four": "k9Xz",
  "abilities": ["zapier:read", "zapier:write"]
}
```

Revoking or rotating the token from the dashboard invalidates it immediately; subsequent calls return `401` and Zapier prompts the user to reconnect.

## Error format

Every error uses one envelope: a stable machine `error` code, a message safe to show to the Zap builder, and an optional `context` object. The `context` key is omitted when empty.

```
{
  "error": "subscription_inactive",
  "message": "This business does not have an active subscription.",
  "context": { "business_id": 521 }
}
```

| Code                          | HTTP | When it happens                                                              |
| ----------------------------- | ---- | ---------------------------------------------------------------------------- |
| missing\_token                | 401  | No bearer token was sent.                                                    |
| invalid\_token                | 401  | The token does not resolve to an account.                                    |
| token\_revoked                | 401  | The token was revoked or has expired.                                        |
| ability\_missing              | 403  | The token lacks the ability the route requires.                              |
| validation\_failed            | 422  | The payload failed validation. Field errors are nested under context.errors. |
| subscription\_inactive        | 402  | The target business has no active or trialing subscription.                  |
| business\_not\_found          | 404  | The business id is unknown or belongs to another account.                    |
| review\_not\_found            | 404  | The review id is unknown or belongs to another account.                      |
| subscription\_not\_found      | 404  | The hook subscription id is unknown or belongs to another account.           |
| missing\_google\_connection   | 409  | The business has no connected Google location.                               |
| missing\_facebook\_connection | 409  | The business has no connected Facebook page.                                 |
| rate\_limit\_exceeded         | 429  | The per-token action rate limit was exhausted.                               |
| payload\_too\_large           | 413  | The request body exceeded the size cap.                                      |
| internal\_error               | 500  | An unexpected server error. No stack trace is ever returned.                 |

Validation failures nest Laravel's field-level messages under `context.errors`, keyed by field name, so Zapier can surface them verbatim.

## Endpoint index

| Method | URI                                                              | Ability      | Purpose                                             |
| ------ | ---------------------------------------------------------------- | ------------ | --------------------------------------------------- |
| GET    | /api/zapier/auth/test                                            | zapier:read  | Verify a token and return the connection label.     |
| GET    | /api/zapier/businesses                                           | zapier:read  | Business dropdown, including subscription state.    |
| GET    | /api/zapier/tags                                                 | zapier:read  | Tag dropdown for the account.                       |
| GET    | /api/zapier/sources                                              | zapier:read  | Review-source dropdown (server-side constant list). |
| POST   | /api/zapier/triggers/{triggerKey}/subscriptions                  | zapier:read  | Subscribe a Zap to a trigger (REST hook).           |
| DELETE | /api/zapier/triggers/{triggerKey}/subscriptions/{subscriptionId} | zapier:read  | Unsubscribe a Zap from a trigger.                   |
| GET    | /api/zapier/triggers/{triggerKey}/sample                         | zapier:read  | Single sample event for Zapier's test step.         |
| GET    | /api/zapier/searches/businesses                                  | zapier:read  | Find a business by name or exact slug.              |
| GET    | /api/zapier/searches/reviews                                     | zapier:read  | Find a review by source and external id.            |
| POST   | /api/zapier/actions/manual-reviews                               | zapier:write | Create a manual review.                             |
| PATCH  | /api/zapier/actions/reviews/{reviewId}/visibility                | zapier:write | Hide or show a review.                              |
| POST   | /api/zapier/actions/google-posts                                 | zapier:write | Schedule a Google Business Profile post.            |
| POST   | /api/zapier/actions/facebook-posts                               | zapier:write | Schedule a Facebook Page post.                      |

## Dropdowns

These three endpoints populate the pickers in the Zap editor. All of them return a `data` envelope.

### GET `/api/zapier/businesses`

Every business under the account, including those whose subscription has lapsed, so a user can see that a Zap is wired up even when it will not fire yet. `display_label` is the string Zapier renders.

```
{
  "data": [
    {
      "id": 521,
      "name": "Acme Coffee — Downtown",
      "has_active_subscription": true,
      "display_label": "Acme Coffee — Downtown"
    },
    {
      "id": 522,
      "name": "Acme Coffee — Suburb",
      "has_active_subscription": false,
      "display_label": "Acme Coffee — Suburb (— Subscription inactive)"
    }
  ]
}
```

### GET `/api/zapier/tags` and GET `/api/zapier/sources`

Both return generic `{ id, label }` items. Tags are the account's own review tags. Sources are a fixed list served from the API so a new source never requires a new app version.

```
{
  "data": [
    { "id": "google",            "label": "Google" },
    { "id": "facebook",          "label": "Facebook" },
    { "id": "manual",            "label": "Manual" },
    { "id": "pipeline_negative", "label": "Negative Pipeline Feedback" }
  ]
}
```

## Triggers (REST hooks)

Triggers are push-based REST hooks, not polling. A Zap subscribes once, and SyncMyReviews POSTs to the Zap's hook URL whenever the event occurs. Seven trigger keys are available.

| Trigger key                       | Name                           | Fires when                                                                         |
| --------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
| new\_review                       | New review                     | Any new Google, Facebook, or manual review on the selected business.               |
| new\_low\_rating\_review          | New low-rating review          | A new review whose numeric rating is 3 or lower.                                   |
| new\_five\_star\_review           | New five-star review           | A new review whose numeric rating is exactly 5.                                    |
| new\_negative\_pipeline\_feedback | New negative pipeline feedback | A review-pipeline visitor submits a low rating into the private feedback branch.   |
| review\_modified\_upstream        | Review modified upstream       | A previously synced Google or Facebook review changes its text or rating upstream. |
| qr\_code\_scanned                 | QR code scanned                | One of the business's review QR codes is scanned.                                  |
| scheduled\_post\_outcome          | Scheduled post outcome         | A scheduled Google or Facebook post publishes or fails.                            |

A single new review can resolve to more than one trigger: a 1-star review fires both `new_review` and `new_low_rating_review`. A Facebook recommendation with no numeric rating fires only `new_review`, because a missing rating is never coerced into a rating band.

### POST `/api/zapier/triggers/{triggerKey}/subscriptions`

Request body:

```
{
  "business_id": 521,
  "target_url": "https://hooks.zapier.com/hooks/catch/123/abc"
}
```

`target_url` must be HTTPS and its host must sit under an allow-listed Zapier domain (`zapier.com` or `zapierusercontent.com`); anything else is rejected as a field-level validation error. The optional `filters` key is reserved for a future version and must be absent or empty. Responds `201`:

```
{
  "id": 9001,
  "trigger_key": "new_review",
  "business_id": 521,
  "expires_at": null
}
```

Subscribing is idempotent: repeating the same trigger key and target URL returns the existing subscription rather than creating a duplicate. Subscribing to a business whose subscription has lapsed is allowed on purpose — the Zap registers and simply stays quiet until billing is active again.

### DELETE `/api/zapier/triggers/{triggerKey}/subscriptions/{subscriptionId}`

Soft-revokes the subscription and responds `204` with an empty body. An unknown id, or one owned by another account, returns `404 subscription_not_found`.

### GET `/api/zapier/triggers/{triggerKey}/sample`

Returns a single-element array holding one representative event for the trigger, so Zapier's test step always has data to map even on a brand-new account. Each item carries a top-level `id` for deduplication. An unrecognised trigger key returns `422 validation_failed`.

## Outbound payloads

Every outbound event shares one envelope. The `data` block is the only part that varies by trigger.

```
{
  "_schema_version": 1,
  "event": "new_review",
  "event_id": "evt_01HXY9...",
  "occurred_at": "2026-05-14T18:42:11Z",
  "business": {
    "id": 521,
    "name": "Acme Coffee — Downtown",
    "slug": "acme-coffee-downtown",
    "timezone": "Europe/Belgrade"
  },
  "data": {
    "source": "google",
    "external_id": "AbF...xyz",
    "rating": 5,
    "rating_normalised_1_5": 5,
    "review_text": "Best coffee in town.",
    "author_name": "Jane Doe",
    "posted_at": "2026-05-14T18:40:02Z",
    "review_url": null,
    "is_hidden": false,
    "tags": []
  }
}
```

`event_id` is generated server-side and is stable, so a Zap can deduplicate on it. A few field-level details matter when you build downstream steps:

* **`review_url` is optional.** Facebook reviews carry a permalink; Google, manual, and pipeline reviews send `null`. Treat it as nullable, never as always present.
* **`rating` can be null on Facebook.** Recommendation-only reviews have no star rating, but `rating_normalised_1_5` is always populated (recommended maps to 5, not recommended maps to 1).
* **QR scan IPs are truncated.** The full visitor IP never leaves the platform — it is reduced to a /24 prefix for IPv4 or a /48 prefix for IPv6.
* **Pipeline submitter emails are never sent.** They exist in SyncMyReviews but are excluded from every outbound payload.
* **Post failures use a stable reason code.** `failure_reason` is an enum rather than raw upstream error text, so provider error strings can never leak through.
* **Payloads are size-capped.** Oversized events have their long text fields trimmed and flagged rather than being sent oversized.

## Searches

Searches follow Zapier's conventions: results are a bare top-level array, and no match is an empty array with `200` — never a `404`.

### GET `/api/zapier/searches/businesses?query=`

Matches up to 25 businesses by case-insensitive partial name or by exact slug. Wildcard characters typed by the user are matched literally.

```
[
  { "id": 521, "name": "Acme Coffee — Downtown", "slug": "acme-coffee-downtown" }
]
```

### GET `/api/zapier/searches/reviews?source=&external_id=`

Returns zero or one match. `source` accepts `google`, `facebook`, or `manual`. Manual reviews have no upstream id, so that source always returns an empty array; `pipeline_negative` is not searchable and is rejected with `422`.

```
[
  {
    "id": 88421,
    "source": "google",
    "external_id": "AbF...xyz",
    "business_id": 521,
    "rating": 5,
    "review_text": "Best coffee in town.",
    "author_name": "Jane Doe",
    "is_hidden": false,
    "posted_at": "2026-05-14T18:40:02Z"
  }
]
```

## Actions

All four actions require the `zapier:write` ability, are rate-limited per token, and re-check the target business's subscription inside the same transaction as the write. An inactive business returns `402 subscription_inactive`.

### POST `/api/zapier/actions/manual-reviews`

Records an external survey result as a manual review alongside Google and Facebook reviews.

| Field         | Rules                                 |
| ------------- | ------------------------------------- |
| business\_id  | Required integer.                     |
| author\_name  | Required string, max 200 characters.  |
| author\_email | Optional email, max 200 characters.   |
| rating        | Required integer between 1 and 5.     |
| review\_text  | Required string, max 5000 characters. |

Responds `201`:

```
{
  "review_id": 88421,
  "source": "manual",
  "business_id": 521,
  "author_name": "Jane Doe",
  "rating": 4,
  "review_text": "Survey response imported from Typeform.",
  "created_at": "2026-05-14T18:50:00+00:00"
}
```

### PATCH `/api/zapier/actions/reviews/{reviewId}/visibility`

Hides or shows a review across the public widgets, badges, and trust card. Requires `source` (`google`, `facebook`, or `manual`) and a boolean `hidden`. An unknown or cross-account review id returns `404 review_not_found`.

```
{
  "review_id": 88421,
  "source": "google",
  "business_id": 521,
  "hidden": true,
  "updated_at": "2026-05-14T18:52:10+00:00"
}
```

### POST `/api/zapier/actions/google-posts`

Queues a Google Business Profile post. The business must have a connected Google location, otherwise the call returns `409 missing_google_connection`. Accepts `business_id`, an optional `title` (max 200), a required `body` (max 1500), optional `image_url` and `cta_url`, and a `scheduled_for` timestamp that must be in the future and within 90 days.

```
{
  "scheduled_post_id": 412,
  "platform": "google",
  "business_id": 521,
  "status": "scheduled",
  "title": "Spring promotion",
  "body": "Get 20% off all espresso drinks this week.",
  "image_url": null,
  "scheduled_for": "2026-05-20T15:00:00+00:00",
  "created_at": "2026-05-14T18:55:00+00:00"
}
```

### POST `/api/zapier/actions/facebook-posts`

Same contract without `title` or `cta_url`. The business must have a connected Facebook page, otherwise the call returns `409 missing_facebook_connection`. The response mirrors the Google shape with `"platform": "facebook"` and no title.

## Limits and delivery

* **Rate limiting.** Write actions are limited per token, so one busy connection can never throttle another account. Exhausting the bucket returns `429 rate_limit_exceeded`.
* **Signed deliveries.** Every outbound POST carries an `X-Sync-Signature` header of the form `t=<unix-timestamp>,v1=<hex>`, an HMAC-SHA256 over `<timestamp>.<raw-body>`. Signing keys rotate with a dual-key grace window.
* **Disabled Zaps clean themselves up.** A `410 Gone` from the hook URL automatically unsubscribes that hook.
* **Transient failures retry.** A timeout, `429`, or `5xx` from the hook URL is queued and retried with exponential backoff. After the retries are exhausted the subscription is flagged for review rather than deleted.
* **Subscription gate at delivery time.** Billing is re-checked when the event is dispatched, not only when it was raised. If the business's subscription has lapsed the event is skipped silently and no webhook is sent.
* **Duplicate suppression.** Identical events raised within a short window for the same subscription are coalesced into a single delivery.

## Get started

Account owners generate a Zapier token from Connections → Zapier in the SyncMyReviews dashboard (sign-in required). Members cannot mint tokens. Use the workflow builder below to connect SyncMyReviews to the rest of your stack without leaving this page.

Zapier workflows could not be loaded. Refresh the page or open Zapier from Connections.

[Generate a token](https://www.syncmyreviews.com/connections/zapier)[How the integration works](https://www.syncmyreviews.com/features/zapier-integration)[Ask about the API](mailto:contact@syncmyreviews.com)

## Language

* ![](https://www.syncmyreviews.com/assets/us.png)English
* ![](https://www.syncmyreviews.com/assets/fr.png)French
* ![](https://www.syncmyreviews.com/assets/de.png)German
* ![](https://www.syncmyreviews.com/assets/nl.png)Dutch
* ![](https://www.syncmyreviews.com/assets/es.png)Spanish

---

[LinkedIn](https://www.linkedin.com/company/syncmyreviews)

```json
{
        "@context": "https://schema.org",
        "@id": "https://www.syncmyreviews.com/#organization",
        "@type": "Organization",
        "name": "SyncMyReviews",
        "url": "https://www.syncmyreviews.com",
        "logo": "https://res.cloudinary.com/lkrs/image/upload/v1760611787/SyncMyReviews/global/syncmyreviews-logo.jpg",
        "description": "SyncMyReviews helps businesses collect, manage, and display customer reviews to enhance credibility and trust.",
        "sameAs": [
          "https://twitter.com/SyncMyReviews",
          "https://www.linkedin.com/company/syncmyreviews",
          "https://www.facebook.com/syncmyreviews"
        ]
      }
{
        "@context": "https://schema.org",
        "@graph": [
          {
            "@id": "https://www.syncmyreviews.com/#website",
            "@type": "WebSite",
            "name": "SyncMyReviews",
            "url": "https://www.syncmyreviews.com/",
            "publisher": { "@id": "https://www.syncmyreviews.com/#organization" }
          },
          {
            "@id": "https://www.syncmyreviews.com/#software",
            "@type": "SoftwareApplication",
            "name": "SyncMyReviews",
            "description": "Platform that automatically syncs, manages, and displays customer reviews from Google Business Profile and Facebook Pages on your website in real time for SEO and trust building.",
            "applicationCategory": "BusinessApplication",
            "operatingSystem": "Web",
            "slogan": "Every review. One place. In real time.",
            "image": "https://www.syncmyreviews.com/assets/SyncMyReviewsBigLogo.svg",
            "url": "https://www.syncmyreviews.com/",
            "offers": {
              "@type": "Offer",
              "availability": "https://schema.org/InStock",
              "description": "Start with a 14-day free trial, no credit card required."
            }
          }
        ]
      }
{"@context":"https://schema.org","@type":"WebPage","name":"Zapier API Reference | SyncMyReviews"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://www.syncmyreviews.com/"},{"@type":"ListItem","position":2,"name":"Zapier API Reference","item":"https://www.syncmyreviews.com/docs/zapier-api"}]}
```