Review Campaigns API

How to run review campaigns through the API

A review campaign asks recent customers to leave a review over email and SMS, then tracks who opened, rated, and replied. This guide walks the full loop on the Synup API: create a campaign with its templates, add customers as they come in, schedule follow-ups, and read the results back. One API key, plain JSON.

// Create a review campaign and send the first ask
const res = await fetch(
  'https://api.synup.com/api/v4/locations/review-campaigns',
  {
    method: 'POST',
    headers: {
      'Authorization': 'API your_api_key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      input: {
        locationId: 'TG9jYXRpb246MTQwMjQ=',
        name: 'Post-visit feedback',
        locationCustomers: [
          { name: 'John', email: 'john@example.com', phone: '3863443131' }
        ],
        smsTemplate: {
          content: 'Thanks for visiting. Leave a review? {{short_url}}'
        }
      }
    })
  }
);
// 200 OK returns an empty body: {}
The short answer

What a review campaign request actually does

A review campaign is a sequence tied to one location. You hand it a list of customers and a set of message templates, and it reaches out over email and SMS asking each person to review their visit. When they tap through, they land on a page that points them to the review sites you chose, like Google and Facebook. The campaign then records what came back: a rating, a written response, and the delivery and open timestamps for each message.

For a developer, that turns into four calls. You create a campaign, you add more customers to it as they transact, you list the campaigns on a location, and you read a campaign's customers back to see who responded. There are no other moving parts. The send itself, the landing page, and the follow-up timing are all handled by the fields you pass at creation.

This maps cleanly onto the common pattern: a customer finishes a transaction in your POS or CRM, a webhook fires in your system, and you drop them into a campaign for that location. From there Synup owns the asking and the chasing, and you poll the campaign for results when you want them.

Auth

Authenticate with one header

Every call uses the same two headers. Generate a key in Settings, then send it as Authorization: API your_api_key with Content-Type: application/json. There's no OAuth flow and no token exchange for the API itself, and no request signing to set up. Here's how to find and generate your key.

Every campaign is scoped to a location, so you'll need that location's id. It's the opaque base64 string the locations endpoints return, something like TG9jYXRpb246MTQwMjQ=, not the numeric account id. Pull it once and reuse it across the campaign calls.

Step 1

Create a campaign with its customers and templates

The whole campaign is one POST to /api/v4/locations/review-campaigns. Everything goes inside an input object: the location, a name, the first batch of customers, and the templates that get sent. A customer is just a name with an email, a phone, or both, which decides whether they're reachable by email, SMS, or either.

Three template objects cover the opening touch: openingEmailTemplate carries a subject, heading, body, and a reply-to; smsTemplate carries the SMS body with a {{short_url}} token that expands to the campaign link; and landingPageTemplate sets the heading and copy on the page customers land on. That landing page carries reviewSiteHash, an array of the review sites to route people to, each a name and a URL. Point it wherever you collect reviews, like Google and Facebook.

One field worth calling out is screening, a boolean. When it's on, the campaign routes feedback through a screening step before sending someone on to a public review site. How you use it is your call, and it should line up with each review platform's own policies. A successful create returns 200 with an empty {} body, so treat the status code as your signal, not the payload.

The create request body

{
  "input": {
    "locationId": "TG9jYXRpb246MTQwMjQ=",
    "name": "Post-visit feedback",
    "locationCustomers": [
      { "name": "John", "email": "john@example.com", "phone": "3863443131" }
    ],
    "screening": true,
    "landingPageTemplate": {
      "heading": "Thanks for visiting. How did we do?",
      "content": "Take a moment to share your experience.",
      "reviewSiteHash": [
        { "name": "Google", "url": "maps.google.com" },
        { "name": "Facebook", "url": "facebook.com/yourpage" }
      ]
    },
    "openingEmailTemplate": {
      "replyTo": "hello@yourbusiness.com",
      "subject": "Tell us how we did",
      "heading": "We'd love your feedback",
      "content": "Please take a minute to review your visit."
    },
    "smsTemplate": {
      "content": "Thanks for visiting. Leave a review? {{short_url}}"
    }
  }
}
Step 2

Schedule the follow-ups and a thank-you

Most people don't act on the first ask. The campaign handles that with two optional follow-ups and a thank-you, each its own template plus a schedule. You pass firstFollowUpTemplate and secondFollowUpTemplate in the same email shape as the opener, and a thankYouTemplate that fires once someone responds. Each one takes a schedule value from a fixed set, so the timing is a choice from an enum, not a raw hour count.

firstFollowUpScheduleNEVER, DAYS_2, DAYS_4, DAYS_7
secondFollowUpScheduleNEVER, DAYS_5, DAYS_10, DAYS_15
thankYouScheduleNEVER, HOURS_12, DAY_1, DAYS_3

Set a schedule to NEVER to skip that step. A common setup is a nudge at DAYS_2, a last reminder at DAYS_7, and a thank-you at HOURS_12 once a rating lands. Leave the follow-up templates out entirely and the campaign just sends the opening ask.

Step 3

Add customers to a campaign that's already running

You rarely have everyone up front. Customers transact one at a time, so the usual pattern is to create the campaign once, then keep adding people to it. That's a POST to /api/v4/locations/review-campaigns/customers with the campaign id and a batch of customers in the same shape you used at creation.

You can send one customer or many in a single call, and the campaign won't re-add anyone who's already in it, so a retry after a timeout is safe. Like the create call, a success comes back as 200 with an empty body. The newly added people enter the same opening-then-follow-up sequence the campaign was built with.

The add-customers request body

{
  "input": {
    "reviewCampaignId": "126dc120-acea-4bcb-8a83-74c80f6f807d",
    "locationCustomers": [
      { "name": "Maria", "email": "maria@example.com", "phone": "5125550148" }
    ]
  }
}
Step 4

Track responses by reading the campaign back

Results come from reading, not from a push. Review campaigns don't emit webhooks, so the way you learn who responded is to poll the campaign. Two GET calls cover it. List the campaigns on a location with /api/v4/locations/{locationId}/review-campaigns to get each campaign's id, name, screening flag, and created date. Then read one campaign's customers with /api/v4/locations/review-campaigns/{reviewCampaignId}/customers.

The customers call is the one with the signal in it. Each customer comes back with where they are in the funnel: whether a rating landed, the review text, how many follow-ups have gone out, and a row of delivery and open timestamps for both channels.

ratingIntegerThe star rating the customer left.
responseStringThe written review text, if any.
followUpSentIntegerHow many follow-ups went out: 0, 1, or 2.
smsDeliveredAtStringWhen the SMS was delivered.
emailLastOpenedAtStringWhen the email was last opened.

A reasonable cadence is to poll a campaign daily while it's active and stop once everyone has either rated or exhausted their follow-ups. The followUpSent count plus a non-null rating tell you when a customer is done. The list-campaigns call also takes optional startDate and endDate query params if you only want campaigns from a window.

A campaign-customers response

{
  "data": {
    "reviewCampaignInfo": {
      "campaignName": "Post-visit feedback",
      "reviewCampaignCustomers": [
        {
          "name": "Maria",
          "email": "maria@example.com",
          "rating": 5,
          "response": "Great service.",
          "followUpSent": 1,
          "smsDeliveredAt": "2026-06-01 01:00:12",
          "emailLastOpenedAt": "2026-06-01 01:00:57"
        }
      ]
    }
  }
}
Endpoints

The review campaign endpoints

Four calls cover the whole loop. The full reference lives in the docs.

POST/api/v4/locations/review-campaignsCreate a campaign with customers and templates
POST/api/v4/locations/review-campaigns/customersAdd customers to an existing campaign
GET/api/v4/locations/{locationId}/review-campaignsList the campaigns on a location
GET/api/v4/locations/review-campaigns/{reviewCampaignId}/customersRead a campaign's customers and their responses
Limits and testing

Rate limits, channels, and a sandbox

The general rate limit is 75 requests per minute, and it can be raised for a specific use case. For campaigns that mostly matters on the read side, since a fleet of daily polls across many locations adds up faster than the occasional create. API access is included in every Synup plan, so there's no separate metering on campaign calls.

Campaigns reach customers over email and SMS, the two channels the templates map to. Before you wire this into production, ask for a sandbox: send a request and we'll set up credentials so you can create campaigns and read them back against test data without messaging real customers.

FAQ

Review Campaigns API FAQs

Common questions on channels, tracking responses, and how the four calls fit together. The developer docs cover every field in full.

What channels does a review campaign use?

Email and SMS. Each customer is reachable by whichever you supply, an email, a phone, or both, and the matching templates decide what gets sent on each channel.

Are there webhooks for review responses?

No. Review campaigns don't emit webhooks, so you track responses by polling the list-customers endpoint, which returns each customer's rating, response text, follow-up count, and delivery timestamps.

How do I keep adding customers to a campaign over time?

Create the campaign once, then POST new customers to the add-customers endpoint with the campaign id as they transact. Batches are supported, and anyone already in the campaign won't be added twice.

What does a successful create or add call return?

An HTTP 200 with an empty JSON body. There's no campaign object in the response, so use the status code as your success signal and read the campaign back with the list calls.

Which review sites can the landing page point to?

Whichever you put in the reviewSiteHash array, each as a name and a URL, for example Google and Facebook. Point it at the sites where you actually collect reviews for that location.

Is the Review Campaigns API metered separately?

No. It's included in all Synup plans with no per-message billing on the API. The general limit is 75 requests per minute, and we can raise it for your use case.

Build review campaigns into your product

Request an API key and we'll provision a sandbox, so you can create campaigns and read responses against test data before any sales call.