Respond to reviews, then edit or archive a reply

Find reviews that accept an owner reply, post one, confirm it reached the publisher, then fix its wording or archive it.

An owner reply is posted to the publisher on your behalf. The API accepts it at once and delivers it asynchronously, so the work is: pick a review that can be answered, post, then confirm on a re-read.

1. Pick reviews that can be answered

List the location's reviews and keep the ones where canRespond is true and responded is false. The responseStatus=["PENDING"] filter does the second check server-side; the JSON value has to be URL-encoded, which --data-urlencode handles.

Answerable reviews
curl -G "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/reviews" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'responseStatus=["PENDING"]' \--data-urlencode 'first=25'
JSON
{  "node": {    "id": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",    "source": "maps.google.com",    "rating": 5,    "content": "nice place for family together",    "responded": false,    "responseCount": 0,    "canRespond": true  }}

canRespond is false for sources that do not take owner replies through the API. Skip those; a reply attempt will not reach the publisher. For drafting, List review phrases tells you what customers mention most, so a reply can address it.

2. Post a reply

POST /locations/reviews/respond takes the fields directly in the body, not wrapped in input. interactionId is the review's id. respondedWith is optional and names a response template if you used one.

Respond
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "interactionId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",  "responseContent": "Thank you for visiting Jenny Home: we are glad you enjoyed your experience!"}'
JSON
{  "data": {    "respondToInteraction": {      "interaction": {        "id": "2090753a-ece6-4837-8336-8494ad308523",        "interactionId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",        "content": "Thank you for visiting Jenny Home: we are glad you enjoyed your experience!",        "interactionStatus": "CREATED",        "editedResponse": false      },      "errors": null    }  }}

Keep interaction.id: it is the responseId you need to edit or archive the reply later. A rejected reply comes back as 200 with errors populated inside data.respondToInteraction, so read the body. The SDKs raise ValidationError in that case.

3. Confirm it reached the publisher

interactionStatus is CREATED at first and moves on its own. Re-read the review by id after a short wait and check responded, responseCount and the reply's status inside responses[].

StatusMeaning
CREATEDAccepted and queued for the publisher.
COMPLETEDPosted to the publisher. Some platforms stop here.
CONFIRMEDPosted and confirmed by the publisher.
FAILEDThe publisher rejected it. remarks on the response says why.
Re-read
curl -G "https://listingsapi.com/api/v4/reviewDetails" \-H "Authorization: API $LISTINGSAPI_KEY" \--data-urlencode 'interactionIds=["9e26d2a8-a6ed-42ea-8454-47d1c92ea841"]'
JSON
{  "id": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",  "responded": true,  "responseCount": 1,  "responses": [    {      "id": "2090753a-ece6-4837-8336-8494ad308523",      "content": "Thank you for visiting Jenny Home: we are glad you enjoyed your experience!",      "interactionStatus": "CONFIRMED",      "editedResponse": false    }  ]}

responded: true with a CONFIRMED or COMPLETED reply means the customer can see it. If you see FAILED, read remarks on the response for the publisher's reason before trying again.

4. Edit a reply

POST /locations/reviews/respond/edit needs both ids: reviewId is the review, responseId is the reply from step 2. The edit is re-submitted, so the reply's interactionStatus returns to CREATED and editedResponse becomes true once it lands.

Edit reply
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond/edit \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "reviewId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",  "responseId": "2090753a-ece6-4837-8336-8494ad308523",  "responseContent": "Thank you again: we have updated our reply to include our new store hours."}'
JSON
{  "data": {    "editResponse": {      "status": "true",      "reviewId": "9e26d2a8-a6ed-42ea-8454-47d1c92ea841",      "responseId": "2090753a-ece6-4837-8336-8494ad308523"    }  }}

status is the string "true" when the edit is accepted. Confirm the new wording the same way as step 3.

5. Archive a reply

POST /locations/reviews/respond/archive takes only responseId. Archiving removes the reply from the interaction's responses on our side. It does not retract a reply that is already live on Google or Facebook, so use it to clear a draft that failed or was superseded, and use edit for anything published.

Archive reply
curl -X POST https://listingsapi.com/api/v4/locations/reviews/respond/archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "responseId": "2090753a-ece6-4837-8336-8494ad308523" }'
JSON
{  "data": {    "archiveResponse": {      "status": "true"    }  }}

After archiving, the review's responseCount drops and responded reflects the remaining replies.

6. Hear about replies by webhook

An interaction.response event fires when a reply is posted, edited or archived. The payload sits under data.interaction with type: "Response" and parent_id set to the review's id, so you can match it to your own record without another call. Like interaction.review, its location_id is not normalized and can be null. Setup is in React to events with webhooks.

Next steps