import Shoply from "@shoplygg/node";
const shoply = new Shoply({ apiKey: process.env.SHOPLY_API_KEY });
const result = await shoply.reviews.reply("REVIEW_ID", {
message: "...",
});<?php
require 'vendor/autoload.php';
$shoply = new Shoply\Client(['apiKey' => getenv('SHOPLY_API_KEY')]);
$result = $shoply->reviews->reply('REVIEW_ID', [
'message' => '...',
]);
import shoply
client = shoply.Client() # reads SHOPLY_API_KEY
result = client.reviews.reply("REVIEW_ID", message="...")
curl --request PUT \
--url https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"message": "<string>"
}
'package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply"
payload := strings.NewReader("{\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"message\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"message\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": null,
"code": null,
"data": {
"review": {
"id": "f9fab83f-7dfc-43bf-9e17-e2e25da1a491",
"rating": 2,
"message": "The key took an hour to arrive.",
"automatic": false,
"imported": false,
"dateCreated": "2026-10-28T10:47:39Z",
"reply": {
"message": "Sorry about the wait. A payment provider was slow that afternoon, and we have added a second one since.",
"dateReplied": "2026-10-28T10:47:39Z"
},
"items": [
{
"productId": "1ca55f9c-07c6-4ef0-9857-f53b28980e86",
"productName": "Northwind Pro",
"variantName": "1 month"
}
],
"orderId": "0bc856cf-ab60-4545-81fa-296427554704",
"customerId": "e769833c-bc29-4074-b692-33d505674dac",
"email": "ada@example.com",
"orderAmount": 9.99,
"currencyCode": "USD",
"flag": {
"id": "989dd588-cc55-4627-92c2-3fe3df1f6330",
"status": "open",
"reason": "unrelated",
"reasonLabel": "Not about this order",
"note": "This is about another shop's delivery, not ours.",
"answer": "",
"dateCreated": "2026-10-28T10:47:39Z",
"dateDecided": null
}
}
}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}Reply to a review
Writes the store’s reply to a review, shown under it on the store, to its buyer on their order’s page, and on the dashboard. A review has one reply: sent again, it takes the place of the one there. Plain words, line breaks kept.
Refused for an automatic review, which has no words to reply to (automatic_review). The buyer is not emailed. Answers the review as List reviews has it, with reply.
Needs the reviews.write permission (Reply to Reviews).
import Shoply from "@shoplygg/node";
const shoply = new Shoply({ apiKey: process.env.SHOPLY_API_KEY });
const result = await shoply.reviews.reply("REVIEW_ID", {
message: "...",
});<?php
require 'vendor/autoload.php';
$shoply = new Shoply\Client(['apiKey' => getenv('SHOPLY_API_KEY')]);
$result = $shoply->reviews->reply('REVIEW_ID', [
'message' => '...',
]);
import shoply
client = shoply.Client() # reads SHOPLY_API_KEY
result = client.reviews.reply("REVIEW_ID", message="...")
curl --request PUT \
--url https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"message": "<string>"
}
'package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply"
payload := strings.NewReader("{\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"message\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.shoply.gg/v1/stores/{storeId}/reviews/{reviewId}/reply")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"message\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": null,
"code": null,
"data": {
"review": {
"id": "f9fab83f-7dfc-43bf-9e17-e2e25da1a491",
"rating": 2,
"message": "The key took an hour to arrive.",
"automatic": false,
"imported": false,
"dateCreated": "2026-10-28T10:47:39Z",
"reply": {
"message": "Sorry about the wait. A payment provider was slow that afternoon, and we have added a second one since.",
"dateReplied": "2026-10-28T10:47:39Z"
},
"items": [
{
"productId": "1ca55f9c-07c6-4ef0-9857-f53b28980e86",
"productName": "Northwind Pro",
"variantName": "1 month"
}
],
"orderId": "0bc856cf-ab60-4545-81fa-296427554704",
"customerId": "e769833c-bc29-4074-b692-33d505674dac",
"email": "ada@example.com",
"orderAmount": 9.99,
"currencyCode": "USD",
"flag": {
"id": "989dd588-cc55-4627-92c2-3fe3df1f6330",
"status": "open",
"reason": "unrelated",
"reasonLabel": "Not about this order",
"note": "This is about another shop's delivery, not ours.",
"answer": "",
"dateCreated": "2026-10-28T10:47:39Z",
"dateDecided": null
}
}
}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}{
"success": false,
"message": "<string>",
"code": "<string>",
"data": null,
"errors": {}
}Authorizations
A secret API key, made under Developers in the dashboard: Authorization: Bearer shoply_sk_...
Headers
A word of your own for this one change, up to 180 letters, digits, dots, dashes, underscores and colons. Sent again with the same key, the request is not carried out twice: the first answer comes back, with Idempotent-Replay: true.
Path Parameters
The store's ID. A key reaches the store it was made in: GET /key answers which.
The review, by its id.
Body
The reply, up to 1,000 characters.

