<!-- Reviews API Reference: Endpoints, Webhooks, JSON · Prisma · https://prismareviews.com/docs/api-reference -->
> Reviews API reference for Prisma: locations, reviews, replies, connections, usage and webhooks, with request and response examples and the normalized JSON.

# Reviews API reference

The Prisma reviews API is a REST API at `https://api.prismareviews.com/v1` that reads and replies to reviews of the businesses and apps you own or manage on Google Business Profile, the App Store, Google Play, Judge.me, Trustpilot, Yelp, Tripadvisor, Booking.com, Yotpo, REVIEWS.io and G2. It uses Bearer API keys, JSON request and response bodies, cursor pagination and signed webhooks. Every review comes back in one normalized shape, whatever the platform.

New here? The [Quickstart](/docs/quickstart) takes you to your first call. This reference describes every endpoint as it works today.

## Resources

| Page | Endpoints |
| --- | --- |
| [Authentication](/docs/api-reference/authentication) | API keys, live and test mode, rate limit headers |
| [Reviews](/docs/api-reference/reviews) | `GET /v1/reviews`, `GET /v1/reviews/{id}` |
| [Replies](/docs/api-reference/replies) | `POST /v1/reviews/{id}/reply`, `DELETE /v1/reviews/{id}/reply` |
| [Locations](/docs/api-reference/locations) | `GET /v1/locations`, `GET /v1/locations/{id}` |
| [Connections](/docs/api-reference/connections) | `POST /v1/connections`, `GET /v1/connections`, `DELETE /v1/connections/{id}` |
| [Webhooks](/docs/api-reference/webhooks) | `POST /v1/webhooks`, `GET /v1/webhooks`, `DELETE /v1/webhooks/{id}`, events and signatures |
| [Usage](/docs/api-reference/usage) | `GET /v1/usage` |
| [Platforms](/docs/api-reference/platforms) | How each platform connects, reply support, limits and sync frequency |

Error codes are on [Errors](/docs/errors) and changes to the API on the [Changelog](/changelog).

## Basics

**Base URL:** `https://api.prismareviews.com/v1`

**Authentication:** send your secret key in the `Authorization` header of every request.

```bash
curl https://api.prismareviews.com/v1/locations \
  -H "Authorization: Bearer $PRISMA_API_KEY"
```
```javascript
const res = await fetch("https://api.prismareviews.com/v1/locations", {
  headers: { Authorization: "Bearer " + process.env.PRISMA_API_KEY },
});
console.log(res.status, await res.json());
```
```python
import os
import requests

resp = requests.get(
    "https://api.prismareviews.com/v1/locations",
    headers={"Authorization": f"Bearer {os.environ['PRISMA_API_KEY']}"},
    timeout=30,
)
print(resp.status_code, resp.json())
```

A request without a well-formed key returns `401 missing_api_key`; a key that doesn't exist or was revoked returns `401 invalid_api_key`. Keys are secret: call Prisma from your server, never from a browser or mobile app. Details on [Authentication](/docs/api-reference/authentication).

**Format:** JSON in, JSON out. Send `Content-Type: application/json` with a body. Timestamps are ISO 8601 in UTC with milliseconds (`2026-10-19T12:41:07.000Z`). A body that isn't valid JSON returns `422 invalid_request`.

**IDs:** every object has a prefixed, URL-safe ID: `rev_` (review), `loc_` (location), `con_` (connection), `we_` (webhook endpoint), `evt_` (event), `req_` (request). Treat them as opaque strings.

**Request IDs:** every response carries a `Request-Id` header, and every error body repeats it as `request_id`. Log it: support can trace any call with it.

## Pagination

`GET /v1/reviews` is paginated with a cursor. It returns `data` and `next_cursor`:

```json
{
  "data": [ { "id": "rev_01KJ8Q2M4T7HX3VB9CWD6NRZ5E", "...": "..." } ],
  "next_cursor": "MjAyNi0xMC0xOVQxMjo0MTowNy4wMDBafHJldl8wMUtKOFEyTTRUN0hYM1ZCOUNXRDZOUlo1RQ"
}
```

- Results are ordered newest first (by the date the review was written on the platform).
- `limit` sets the page size: 1 to 100, default 50.
- Pass `cursor=<next_cursor>` with the same filters to get the next page. `next_cursor: null` means the last page.
- A cursor that can't be decoded returns `422 invalid_request`.

`GET /v1/locations` and `GET /v1/connections` return every item in one page, with `next_cursor: null`. `GET /v1/webhooks` returns `data` only.

## Idempotency

`POST /v1/reviews/{id}/reply` accepts an `Idempotency-Key` header. Send a unique value (a UUID works) per reply you intend to post:

- The same key with the same body returns the stored response, with the original status code, and does not reply twice.
- The same key with a different body or a different review returns `409 idempotency_conflict`.
- Keys are scoped to your workspace. Only successful responses are stored, so a request that failed with an error can be retried with the same key.

The other `POST` endpoints don't read the header. Retrying `POST /v1/connections` or `POST /v1/webhooks` creates a second object, so check with the matching `GET` first.

## Rate limits

Each API key has a limit of requests per minute, set by your plan, counted in fixed one-minute windows:

| Plan | Requests per minute, per key |
| --- | --- |
| Spark (free) | 60 |
| Beam | 120 |
| Spectrum | 600 |
| Aurora | 1,200 |

Every authenticated response carries `X-RateLimit-Limit` and `X-RateLimit-Remaining`. Above the limit you get `429 rate_limited` with a `Retry-After` header (seconds until the window resets). Requests over the limit are not counted in your usage. Plans and prices are on [Pricing](/pricing).

Platform limits apply on top, for example Google's per-profile edit limit (see [Google Business Profile API usage limits](https://developers.google.com/my-business/content/limits)) or the [App Store Connect API rate limits](https://developer.apple.com/documentation/appstoreconnectapi/identifying-rate-limits). Prisma never calls a platform inside your request: syncs and replies run in a background queue that retries when a platform is busy. Per-platform details are on [Platforms](/docs/api-reference/platforms).

## Versioning

The version is in the path: `/v1`. Within `v1` we only make additive changes, such as new endpoints, new optional parameters, new fields in responses and new webhook event types. Write your client so that unknown fields and event types are ignored. Every change is listed on the [Changelog](/changelog).

## The review object

Every platform maps to the same fields. The full description is on [Reviews](/docs/api-reference/reviews).

```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": null
}
```

## Machine-readable docs

A plain-text index of Prisma and its docs lives at [/llms.txt](/llms.txt), following the [llms.txt specification](https://llmstxt.org/), so coding assistants and agents can find the right page without parsing HTML.

## FAQ

### Is there an OpenAPI spec?

Not yet. This reference is the contract for v1. The API is plain REST and JSON, so any HTTP client works.

### Is there an SDK?

Not yet. Use curl, `fetch` in Node.js 18+ or `requests` in Python, as in the examples.

### Can I filter reviews by rating?

Not in the API today. `GET /v1/reviews` filters by `location_id`, `platform`, `since` and `has_reply`; filter by rating on your side.

### Do test keys behave like live keys?

Yes, with sample data. A `pk_test_` key can connect any platform without real credentials, gets two sample locations with sample reviews, and accepts replies without publishing them anywhere. Test and live data never mix. See [Authentication](/docs/api-reference/authentication).
