Send a review request to a customer
Overview
Send one customer a review request by email, text, or both, using a campaign's templates.
Use this for point-of-service requests, for example right after a job is finished, or to send from your own system one customer at a time.
You'll need the campaign_id, the customer's name, and their email and/or phone.
The message is queued and sent within minutes. Delivery and clicks show in Campaign reporting. Counts against your plan's email and SMS allowances; when an allowance is used up the call returns 402.
If one channel is usable and the other isn't, the call still returns 200 and sends only the usable channel; data.message tells you which went out, and the other channel's problem isn't reported.
Prerequisites
- A bearer token. See Authentication.
- A campaign (
campaign_id) in your account whose Email and/or SMS channel is enabled and has a template. - An active plan on the campaign's location.
Base URL
| Environment | URL |
|---|---|
| Production | https://production-api.shoutaboutus.com |
| Development | https://development-api.shoutaboutus.com |
Endpoint
POST /api/v1/campaign/review-request
Authentication
Account token
- The campaign must belong to your own account; otherwise
403(You are not authorized to send a review request for this campaign). - The campaign's location must have an active plan; otherwise
400.
Rate limit
60 requests per minute, counted per user (the token’s user). See Rate limits.
Request parameters
None.
Request body
Send email, phone, or both.
| Field | Type | Required | Description |
|---|---|---|---|
campaign_id | integer | Yes | The campaign to send from. Must exist (otherwise 422) and belong to your own account (otherwise 403). |
customer_name | string | Yes | The customer's name, up to 255 characters. |
email | string | Without phone | The customer's email address, up to 255 characters. Sends by email. Checked with an RFC and DNS lookup, so the domain must accept mail: addresses like @example.com are rejected with 422. |
phone | string | Without email | The customer's phone number, 7–20 characters. Sends by text. |
is_test | boolean | No | true marks the send as a test: it isn't added to the campaign's recipient count and schedules no follow-up email. Default false. |
keywords | object | No | Values for your template's placeholders, as key/value pairs, e.g. {"paragraph_1": "Thanks for visiting!"}. Each key up to 100 characters; values are strings. Empty values are skipped. |
This route picks its channels from the contact details you send: an email engages the Email channel, a phone engages the SMS channel. Each channel is only validated if you use it, so an SMS-only send needs no email template, and vice versa. Each channel you engage must exist, be enabled, and have a template. You get 400 only when no channel is usable, and then the causes are joined with ; :
| Response | Cause |
|---|---|
Campaign does not have an active Email channel | You sent an email, but there is no enabled email channel. |
Email channel does not have a valid template. Please add a template to the Email channel. | The Email channel exists but has no usable template. |
Campaign does not have an active SMS channel | You sent a phone, but there is no enabled sms channel. |
SMS channel does not have a valid template. Please add a template to the SMS channel. | The SMS channel exists but has no usable template. |
A campaign built with Create or edit a campaign has no template on its channels until you attach one, so every send fails until you do. Get each channel's id from
data.data.channels[].idin the step 2 or step 3 response, then attach a template to it:
- Email:
POST /api/v1/campaign/template/email/updatewithchannel_id,email_template_id(thevalueof an entry fromGET /api/v1/campaign/template/email/list, which returns{value, label}pairs),subject,html_content(orhtml_content_b64) andjson_content("{}"is fine). This sets the channel'stemplate_id, orfollow_up_template_idwhen the template'stemplate_typeisfollow_up.- SMS:
POST /api/v1/campaign/template/sms/updatewithchannel_id,sms_template_idandcontent.{ "channel_id": 812, "email_template_id": 34, "subject": "How did we do?", "html_content": "<p>Hi [customerName], tell us how we did.</p>", "json_content": "{}" }
Request payload
{
"campaign_id": 4823,
"customer_name": "Jane Smith",
"email": "<customer-email>",
"phone": "+15555550100",
"is_test": false,
"keywords": {
"paragraph_1": "Thanks for visiting our store today!"
}
}Response body
The payload is inside data.
| Field | Type | Description |
|---|---|---|
status | string | success. |
message | string | Which channels went out: Email and SMS review requests sent successfully, Email review request sent successfully or SMS review request sent successfully. |
Response payload
{
"data": {
"status": "success",
"message": "Email and SMS review requests sent successfully"
}
}Examples
Success payload
Both channels sent: see Response payload. When only one channel is usable, only that one is sent:
{
"data": {
"status": "success",
"message": "Email review request sent successfully"
}
}Error payload
400 No usable channel
{
"message": "Bad Request",
"status": "error",
"errors": "Campaign does not have an active SMS channel"
}400 No active plan
{
"message": "Store does not have an active plan",
"status": "error",
"errors": []
}400 Review site links missing
The landing page or email template links to a review site the location has no URL for. errors lists the sites, under review_site_not_found (no URL saved for the site) or landing_page_url_not_found (no landing page URL).
{
"message": "One or more review site URLs are missing in the landing page or email template.",
"status": "error",
"errors": {
"review_site_not_found": [
{
"review_site_id": 1,
"review_site_name": "Yelp"
}
]
}
}402 Plan allowance used up
{
"status": "error",
"message": "Limit reached for 'Email Solicitations': 500 of 500 units consumed this period.",
"feature": "review_solicitation_email",
"remaining": 0,
"hard_stop": true
}403 Campaign outside your account
{
"message": "You are not authorized to send a review request for this campaign",
"status": "error",
"errors": []
}422 Fields missing
{
"message": "The campaign id field is required. (and 3 more errors)",
"errors": {
"campaign_id": [
"The campaign id field is required."
],
"customer_name": [
"The customer name field is required."
],
"email": [
"The email field is required when phone is not present."
],
"phone": [
"The phone field is required when email is not present."
]
}
}422 Email rejected
{
"message": "The email field must be a valid email address.",
"errors": {
"email": [
"The email field must be a valid email address."
]
}
}429 Too many requests
{
"message": "Too Many Attempts."
}| Status | Meaning |
|---|---|
200 | The request is queued on at least one channel. |
400 | No channel is usable, the location has no active plan, or the template links to a review site the location has no URL for. |
401 | The token is missing, expired or invalid. |
402 | The plan's email or SMS allowance for the period is used up, or the feature isn't on the plan. |
403 | The campaign belongs to another account. |
422 | A field is missing or invalid, or campaign_id doesn't exist. |
429 | More than 60 requests in a minute from this user. |
500 | Unexpected server error. |
Example request
curl --request POST \
--url "https://production-api.shoutaboutus.com/api/v1/campaign/review-request" \
--header 'Authorization: Bearer <bearer-token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"campaign_id": 4823, "customer_name": "Jane Smith", "email": "<customer-email>", "phone": "+15555550100", "is_test": false, "keywords": {"paragraph_1": "Thanks for visiting our store today!"}}'Updated 17 days ago
