<!-- Reply to Reviews by API: Create, Replace, Delete · Prisma · https://prismareviews.com/docs/api-reference/replies -->
> POST and DELETE /v1/reviews/{id}/reply: publish your reply to Google, App Store, Google Play, Judge.me and Trustpilot reviews through their official APIs.

# Replies

A reply is the business's public answer to a review. You write the text, or your software does; Prisma publishes it through the platform's official API. Each review has at most one reply in Prisma: `POST /v1/reviews/{id}/reply` creates it or replaces it, and `DELETE /v1/reviews/{id}/reply` removes it. What happens next depends on the platform:

- **API platforms** (Google Business Profile, App Store, Google Play, Judge.me, Trustpilot): Prisma publishes the reply through the platform's official API. The request returns `202` with `reply.status: "queued"`, and a background job publishes it.
- **Read-only platforms** (Yelp, Tripadvisor, Booking.com, Yotpo, REVIEWS.io, G2): these platforms have no reply API for third parties, so Prisma reads their reviews but can't reply. `POST` and `DELETE` return `422 reply_not_supported` with the review's `url`, a link to answer it on the platform.

The full table, with per-platform limits, is on [Platforms](/docs/api-reference/platforms).

## Create or replace a reply

`POST /v1/reviews/{id}/reply`

| Body param | Required | Description |
| --- | --- | --- |
| `text` | yes | Reply text. Leading and trailing spaces are trimmed; 1 to 10,000 characters, and the platform's own limit applies (see below). |

| Header | Required | Description |
| --- | --- | --- |
| `Idempotency-Key` | no | A unique value per reply. Retrying with the same key and body returns the first response instead of replying twice. |

```bash
curl -X POST https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply \
  -H "Authorization: Bearer $PRISMA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1e2a90-4b1d-4e0a-9d55-1f6c0b7f2e31" \
  -d '{"text": "Thanks Marta! We have added a second barista at lunch."}'
```
```javascript
import crypto from "node:crypto";

const res = await fetch(
  "https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer " + process.env.PRISMA_API_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({ text: "Thanks Marta! We have added a second barista at lunch." }),
  }
);
const review = await res.json();
console.log(res.status, review.reply.status); // 202 "queued"
```
```python
import os
import uuid
import requests

resp = requests.post(
    "https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply",
    json={"text": "Thanks Marta! We have added a second barista at lunch."},
    headers={
        "Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    timeout=30,
)
print(resp.status_code, resp.json()["reply"]["status"])
```

The response is the full [review object](/docs/api-reference/reviews) with the new `reply`.

**Response `202`** (API platforms)

```json
{
  "id": "rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E",
  "platform": "google",
  "location_id": "loc_01KJ8P9W2C4D6F8G0H2J4K6M8N",
  "rating": 4,
  "title": null,
  "text": "Great flat white, a bit slow at lunchtime.",
  "author": "Marta G.",
  "language": "en",
  "url": null,
  "created_at": "2026-10-19T12:41:07.000Z",
  "updated_at": "2026-10-19T12:41:07.000Z",
  "reply": {
    "text": "Thanks Marta! We have added a second barista at lunch.",
    "created_at": null,
    "status": "queued",
    "error": null
  }
}
```

**Response `422`** (read-only platforms): nothing is stored or sent. Answer the review on the platform with the link in `url`.

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "reply_not_supported",
    "message": "Yelp has no reply API for third parties, so Prisma only reads its reviews. Answer this one on the platform: https://www.yelp.com/biz/example-cafe-san-francisco",
    "retryable": false,
    "request_id": "req_01KJ8T6F8G0H2J4K6M8N0P2Q4R",
    "docs_url": "https://prismareviews.com/docs/errors#reply_not_supported",
    "platform": "yelp",
    "url": "https://www.yelp.com/biz/example-cafe-san-francisco"
  }
}
```

### What happens to a queued reply

1. A background job sends the reply to the platform. When the queue is busy, jobs from bigger plans run first.
2. When the platform accepts it, `reply.status` becomes `published`, `reply.created_at` is set and you get a `reply.published` [webhook](/docs/api-reference/webhooks).
3. If the platform is rate limiting or down (HTTP 429 or 5xx), Prisma retries with exponential backoff: 30 seconds, then doubling up to one hour between attempts, for up to 8 attempts.
4. If the platform refuses the reply, or every attempt fails, `reply.status` becomes `failed`, `reply.error` says why and you get a `reply.failed` webhook. Fix the cause and `POST` the reply again.
5. If the platform rejects Prisma's access (expired or revoked token or key), the connection becomes `reauth_required` and you get a `connection.updated` webhook. See [Connections](/docs/api-reference/connections).

With a test key, queued replies go through the same steps and end as `published`, but nothing reaches any platform.

### Replacing a reply

Posting again replaces the stored reply and, on API platforms, publishes the new text: Google Business Profile, App Store, Google Play and Trustpilot update the reply on the platform. Judge.me's API can create replies but not edit them, so send a Judge.me reply once.

### Reply length limits

Prisma checks the platform's limit before queueing, so a reply that is too long fails at once instead of in the background:

| Platform | Limit |
| --- | --- |
| Google Business Profile | 4,096 bytes (UTF-8) |
| App Store | 5,970 characters |
| Google Play | 350 characters |
| Others | 10,000 characters (Prisma's own limit) |

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "reply_too_long",
    "message": "Google Play accepts replies of up to 350 characters.",
    "retryable": false,
    "request_id": "req_01KJ8T3C5D7E9F1G3H5J7K9M1N",
    "docs_url": "https://prismareviews.com/docs/errors#reply_too_long",
    "platform": "google_play",
    "max_length": 350
  }
}
```

### Errors

| Status | `code` | When |
| --- | --- | --- |
| 404 | `resource_not_found` | No review with that ID in your workspace and mode. |
| 409 | `connection_reauth_required` | The connection of the review's location is not `active`. The error includes `connection_id`. Reconnect, then retry. |
| 409 | `idempotency_conflict` | The `Idempotency-Key` was already used with a different request. |
| 422 | `invalid_request` | `text` is missing or empty, or the body isn't valid JSON. |
| 422 | `reply_not_supported` | The platform is read only (Yelp, Tripadvisor, Booking.com, Yotpo, REVIEWS.io, G2). The error includes `platform` and `url`. |
| 422 | `reply_too_long` | The text is over the platform's limit. The error includes `platform` and `max_length`. |

## Delete a reply

`DELETE /v1/reviews/{id}/reply`

```bash
curl -X DELETE https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply \
  -H "Authorization: Bearer $PRISMA_API_KEY"
```
```javascript
const res = await fetch(
  "https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply",
  { method: "DELETE", headers: { Authorization: "Bearer " + process.env.PRISMA_API_KEY } }
);
console.log(res.status, await res.json());
```
```python
resp = requests.delete(
    "https://api.prismareviews.com/v1/reviews/rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E/reply",
    headers={"Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}"},
    timeout=30,
)
print(resp.status_code, resp.json())
```

**Response `202`** (a reply published through a platform that supports deleting: Google Business Profile, App Store, Trustpilot). A job removes it from the platform; when it's done, `reply` becomes `null`.

```json
{ "id": "rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E", "deleted": false, "status": "queued" }
```

| Status | `code` | When |
| --- | --- | --- |
| 404 | `resource_not_found` | No review with that ID in your workspace and mode. |
| 404 | `reply_not_found` | The review has no reply. |
| 422 | `operation_not_supported` | The platform's API can't delete replies: Google Play and Judge.me. On Google Play you can replace the reply instead. |
| 422 | `reply_not_supported` | The platform is read only. Remove the reply on the platform, with the link in `url`. |

All error codes are on [Errors](/docs/errors).
