Prisma Reviews Replies API

Publish and delete replies through each platform's official API.

Operations 2

POST /v1/reviews/{id}/reply Create or replace a reply #
DELETE /v1/reviews/{id}/reply Delete a reply #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/prismareviews:prismareviews-replies-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

prismareviews-replies-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Prisma Reviews Replies API
  version: 1.0.0
  summary: One REST API to read and reply to reviews on the App Store, Google Play, Yelp, Tripadvisor and more.
  description: 'Read the reviews of the businesses and apps you own or manage on the App Store, Google Play, Judge.me, eBay, Trusted Shops, eKomi, Yelp, Tripadvisor, Booking.com, G2 and 50+ more platforms, all in one normalized JSON shape, and reply through each platform''s official API where it has one (read-only platforms return the link where a review is answered). Google Business Profile, Trustpilot, Allegro, Etsy, Angi and Mercado Libre are coming soon: `GET /v1/platforms` says which platforms are ready (`live_ready`).


    - **Auth:** `Authorization: Bearer `. Live keys (`pk_live_…`) work with real accounts; test keys (`pk_test_…`) connect any platform with sample locations and reviews and never publish replies. Test and live data never mix.

    - **Format:** JSON in and out; timestamps are ISO 8601 in UTC; IDs are prefixed (`rev_`, `loc_`, `con_`, `we_`, `evt_`, `req_`).

    - **Pagination:** `GET /v1/reviews` is cursor paginated (`data` + `next_cursor`).

    - **Rate limits:** per key and per minute, set by the plan (Spark 60, Beam 120, Spectrum 600, Aurora 1,200), reported in `X-RateLimit-Limit` and `X-RateLimit-Remaining`.

    - **Errors:** one shape, `{ "error": { "type", "code", "message", "retryable", "request_id", "docs_url" } }`; codes on https://prismareviews.com/docs/errors.

    - **Webhooks:** signed `POST`s for new and updated reviews, published or failed replies and connection changes.


    Get a free API key at https://app.prismareviews.com/signup.'
  termsOfService: https://prismareviews.com/terms
  contact:
    name: Prisma Reviews
    url: https://prismareviews.com
    email: hello@prismareviews.com
  x-logo:
    url: https://prismareviews.com/favicon.svg
    altText: Prisma Reviews
servers:
- url: https://api.prismareviews.com
  description: Production (live and test keys)
security:
- apiKey: []
tags:
- name: Replies
  description: Publish and delete replies through each platform's official API.
  externalDocs:
    description: Docs
    url: https://prismareviews.com/docs/api-reference/replies
paths:
  /v1/reviews/{id}/reply:
    post:
      operationId: replyToReview
      tags:
      - Replies
      summary: Create or replace a reply
      description: 'Stores the reply and queues it for publishing through the platform''s official API: `202` with the review and `reply.status: "queued"`. A background job publishes it (`reply.published` webhook), marks it `failed` (`reply.failed` webhook), or, when the platform never answered and the reply can''t be read back, marks it `unknown` without retrying (`reply.unknown` webhook). Posting again replaces the stored reply. With a test key the reply goes through the same steps but never reaches the platform. Read-only platforms return `422 reply_not_supported` with the review''s `url`, where it can be answered.'
      parameters:
      - name: id
        in: path
        required: true
        description: Review ID (`rev_…`).
        schema:
          type: string
        example: rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E
      - name: Idempotency-Key
        in: header
        required: false
        description: A unique value per reply (a UUID works). The same key with the same request returns the stored response instead of replying twice; with a different request it returns `409 idempotency_conflict`. Scoped to the workspace; only successful responses are stored.
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - text
              additionalProperties: true
              properties:
                text:
                  type: string
                  minLength: 1
                  maxLength: 10000
                  description: Reply text, trimmed. 1 to 10,000 characters; the platform's own limit also applies (Google Business Profile 4,096 bytes, App Store 5,970 characters, Google Play 350, eBay 80).
            example:
              text: Thanks Marta! We have added a second barista at lunch.
      responses:
        '202':
          description: Reply queued. The body is the review with its new `reply`.
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Review'
              example:
                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
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No review with that ID in this workspace and mode (`resource_not_found`).
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                resource_not_found:
                  value:
                    error:
                      type: not_found_error
                      code: resource_not_found
                      message: No review with that id in this workspace.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#resource_not_found
        '409':
          description: The `Idempotency-Key` was used with a different request, or the connection of the review's location is not `active` (reconnect it, then retry).
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                idempotency_conflict:
                  value:
                    error:
                      type: conflict_error
                      code: idempotency_conflict
                      message: This Idempotency-Key was already used with a different request.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#idempotency_conflict
                connection_reauth_required:
                  value:
                    error:
                      type: conflict_error
                      code: connection_reauth_required
                      message: The connection for this location is not active. Reconnect it and try again.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#connection_reauth_required
                      connection_id: con_01KJ8P7R5S3T1V9W7X5Y3Z1A2B
        '422':
          description: '`text` missing or empty, a body that isn''t valid JSON (`invalid_request`), a read-only platform (`reply_not_supported`, with `platform` and `url`) or a text over the platform''s limit (`reply_too_long`, with `platform` and `max_length`).'
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_request:
                  value:
                    error:
                      type: invalid_request_error
                      code: invalid_request
                      message: 'text: String must contain at least 1 character(s)'
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#invalid_request
                reply_not_supported:
                  value:
                    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-madrid'
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#reply_not_supported
                      platform: yelp
                      url: https://www.yelp.com/biz/example-cafe-madrid
                reply_too_long:
                  value:
                    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
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/Maintenance'
      externalDocs:
        description: Docs
        url: https://prismareviews.com/docs/api-reference/replies
    delete:
      operationId: deleteReply
      tags:
      - Replies
      summary: Delete a reply
      description: Queues the removal of the review's reply from the platform. When the job is done, `reply` becomes `null`. Only on platforms whose API can delete replies (Google Business Profile, App Store, Trustpilot).
      parameters:
      - name: id
        in: path
        required: true
        description: Review ID (`rev_…`).
        schema:
          type: string
        example: rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E
      responses:
        '202':
          description: Deletion queued.
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReplyDeletion'
              example:
                id: rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E
                deleted: false
                status: queued
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No review with that ID in this workspace and mode (`resource_not_found`), or the review has no reply (`reply_not_found`).
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                resource_not_found:
                  value:
                    error:
                      type: not_found_error
                      code: resource_not_found
                      message: No review with that id in this workspace.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#resource_not_found
                reply_not_found:
                  value:
                    error:
                      type: not_found_error
                      code: reply_not_found
                      message: This review has no reply.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#reply_not_found
        '422':
          description: The platform is read only (`reply_not_supported`, with `platform` and `url`) or its API can't delete replies (`operation_not_supported`).
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                reply_not_supported:
                  value:
                    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-madrid'
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#reply_not_supported
                      platform: yelp
                      url: https://www.yelp.com/biz/example-cafe-madrid
                operation_not_supported:
                  value:
                    error:
                      type: invalid_request_error
                      code: operation_not_supported
                      message: Google Play doesn't allow deleting replies through its API. You can edit the reply instead.
                      retryable: false
                      request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                      docs_url: https://prismareviews.com/docs/errors#operation_not_supported
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/Maintenance'
      externalDocs:
        description: Docs
        url: https://prismareviews.com/docs/api-reference/replies
components:
  responses:
    InternalError:
      description: Something failed on Prisma's side. Retryable.
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            internal_error:
              value:
                error:
                  type: api_error
                  code: internal_error
                  message: Something went wrong on our side. It has been logged; try again.
                  retryable: true
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#internal_error
    RateLimited:
      description: More requests this minute than the plan allows for this key. Not counted in usage.
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            rate_limited:
              value:
                error:
                  type: rate_limit_error
                  code: rate_limited
                  message: Rate limit of 60 requests per minute exceeded. Retry in 12 s. Requests over the limit are never billed.
                  retryable: true
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#rate_limited
    Unauthorized:
      description: No API key or one not shaped like a Prisma key (`missing_api_key`), or a key that doesn't exist or was revoked (`invalid_api_key`).
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missing_api_key:
              value:
                error:
                  type: authentication_error
                  code: missing_api_key
                  message: 'Send your API key as "Authorization: Bearer pk_live_…".'
                  retryable: false
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#missing_api_key
            invalid_api_key:
              value:
                error:
                  type: authentication_error
                  code: invalid_api_key
                  message: This API key does not exist or was revoked.
                  retryable: false
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#invalid_api_key
    Forbidden:
      description: The account is suspended.
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            account_suspended:
              value:
                error:
                  type: permission_error
                  code: account_suspended
                  message: This account is suspended. Write to hello@prismareviews.com.
                  retryable: false
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#account_suspended
    Maintenance:
      description: Prisma is under maintenance and the API is paused. Retryable.
      headers:
        Request-Id:
          $ref: '#/components/headers/Request-Id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            maintenance:
              value:
                error:
                  type: api_error
                  code: maintenance
                  message: Prisma is under maintenance. Try again in a few minutes; see https://prismareviews.com/status.
                  retryable: true
                  request_id: req_01KJ8T3C5D7E9F1G3H5J7K9M1N
                  docs_url: https://prismareviews.com/docs/errors#maintenance
  headers:
    X-RateLimit-Remaining:
      description: Requests left in the current one-minute window.
      schema:
        type: integer
    Request-Id:
      description: The `req_…` ID of the request. Include it when you contact support.
      schema:
        type: string
    X-RateLimit-Limit:
      description: Requests allowed per minute for this key.
      schema:
        type: integer
    Retry-After:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  schemas:
    Reply:
      type: object
      required:
      - text
      - created_at
      - status
      - error
      description: The business reply to a review.
      properties:
        text:
          type: string
          description: Reply text.
        created_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the reply was published. `null` while a first reply is queued; when a reply is replaced, it keeps the previous value until the new one is published.
        status:
          type:
          - string
          - 'null'
          enum:
          - published
          - queued
          - failed
          - unknown
          - null
          description: '`published` (live on the platform, whoever wrote it), `queued` (sent through Prisma, waiting to be published), `failed` (the platform refused it; see `error`) or `unknown` (the request went out but the platform never answered and the reply can''t be read back, so Prisma didn''t retry; check the review on the platform before posting again; see `error`).'
        error:
          type:
          - string
          - 'null'
          description: Why publishing failed, when `status` is `failed`.
    Review:
      type: object
      required:
      - id
      - platform
      - location_id
      - rating
      - title
      - text
      - author
      - language
      - url
      - created_at
      - updated_at
      - reply
      description: One customer review, in the same shape on every platform.
      properties:
        id:
          type: string
          description: Review ID (`rev_…`).
          example: rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E
        platform:
          $ref: '#/components/schemas/PlatformId'
        location_id:
          type: string
          description: The location the review belongs to (`loc_…`).
        rating:
          type:
          - integer
          - 'null'
          minimum: 1
          maximum: 5
          description: 1 to 5 stars. `null` if the platform gave no rating.
        title:
          type:
          - string
          - 'null'
          description: Review title, on platforms that have one.
        text:
          type:
          - string
          - 'null'
          description: Review body. `null` for rating-only reviews.
        author:
          type:
          - string
          - 'null'
          description: Display name as shown by the platform.
        language:
          type:
          - string
          - 'null'
          description: Language code when the platform provides one.
        url:
          type:
          - string
          - 'null'
          format: uri
          description: Public link to the review when the platform provides one. On read-only platforms, where to answer it.
        created_at:
          type: string
          format: date-time
          description: When the review was written on the platform.
        updated_at:
          type: string
          format: date-time
          description: When it was last edited on the platform.
        reply:
          oneOf:
          - $ref: '#/components/schemas/Reply'
          - type: 'null'
          description: The business reply, or `null`.
    Error:
      type: object
      required:
      - error
      description: Every error has this shape. Some codes add fields (for example `platform`, `url`, `max_length`, `connection_id`, `upgrade_url`, `required_fields`).
      properties:
        error:
          type: object
          required:
          - type
          - code
          - message
          - retryable
          - request_id
          - docs_url
          additionalProperties: true
          properties:
            type:
              type: string
              enum:
              - authentication_error
              - permission_error
              - not_found_error
              - conflict_error
              - invalid_request_error
              - rate_limit_error
              - api_error
              description: Family of the error, from the HTTP status.
            code:
              type: string
              description: Stable, machine-readable code. Branch on this, not on `message`.
            message:
              type: string
              description: Human-readable explanation. It can change.
            retryable:
              type: boolean
              description: '`true` for 429 and 5xx: the same request can succeed later.'
            request_id:
              type: string
              description: The `req_…` ID, also in the `Request-Id` header.
            docs_url:
              type: string
              description: Description of this code.
              format: uri
    PlatformId:
      type: string
      enum:
      - google
      - app_store
      - google_play
      - judge_me
      - trustpilot
      - google_maps
      - yelp
      - tripadvisor
      - booking
      - yotpo
      - reviews_io
      - g2
      - ebay
      - etsy
      - steam
      - okendo
      - feefo
      - trusted_shops
      - ekomi
      - loox
      - proven_expert
      - shopper_approved
      - wordpress
      - appexchange
      - facebook
      - opentable
      - doordash
      - angi
      - checkatrade
      - avvo
      - capterra
      - apartments
      - gartner
      - healthgrades
      - vitals
      - classpass
      description: 'Platform ID.


        | ID | Platform | Connects with | Replies |

        | --- | --- | --- | --- |

        | `google` | Google Business Profile | oauth | by API |

        | `app_store` | App Store | credentials | by API |

        | `google_play` | Google Play | credentials | by API |

        | `judge_me` | Judge.me | credentials | by API |

        | `trustpilot` | Trustpilot | oauth | by API |

        | `google_maps` | Google Maps | listing_url | read only |

        | `yelp` | Yelp | listing_url | read only |

        | `tripadvisor` | Tripadvisor | listing_url | read only |

        | `booking` | Booking.com | listing_url | read only |

        | `yotpo` | Yotpo | credentials | read only |

        | `reviews_io` | REVIEWS.io | credentials | read only |

        | `g2` | G2 | credentials | read only |

        | `ebay` | eBay | oauth | by API |

        | `etsy` | Etsy | listing_url | read only |

        | `steam` | Steam | listing_url | read only |

        | `okendo` | Okendo | credentials | read only |

        | `feefo` | Feefo | credentials | read only |

        | `trusted_shops` | Trusted Shops | credentials | by API |

        | `ekomi` | eKomi | credentials | by API |

        | `loox` | Loox | credentials | read only |

        | `proven_expert` | ProvenExpert | credentials | read only |

        | `shopper_approved` | Shopper Approved | credentials | read only |

        | `wordpress` | WordPress.org | listing_url | read only |

        | `appexchange` | Salesforce AppExchange | listing_url | read only |

        | `facebook` | Facebook | listing_url | read only |

        | `opentable` | OpenTable | listing_url | read only |

        | `doordash` | DoorDash | listing_url | read only |

        | `angi` | Angi | listing_url | read only |

        | `checkatrade` | Checkatrade | listing_url | read only |

        | `avvo` | Avvo | listing_url | read only |

        | `capterra` | Capterra | listing_url | read only |

        | `apartments` | Apartments.com | listing_url | read only |

        | `gartner` | Gartner Peer Insights | listing_url | read only |

        | `healthgrades` | Healthgrades | listing_url | read only |

        | `vitals` | Vitals | listing_url | read only |

        | `classpass` | ClassPass | listing_url | read only |'
    ReplyDeletion:
      type: object
      required:
      - id
      - deleted
      - status
      properties:
        id:
          type: string
          description: Review ID.
        deleted:
          type: boolean
          const: false
          description: 'Always `false`: the deletion is queued.'
        status:
          type: string
          const: queued
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: pk_live_… / pk_test_…
      description: 'Your secret API key as a Bearer token: `pk_live_…` for real accounts, `pk_test_…` for sample data. Keep it on your server.'
externalDocs:
  description: Prisma Reviews API reference
  url: https://prismareviews.com/docs/api-reference