# Google Reviews

`POST https://api.serpkite.com/v1/reviews` · Credits: 1 per 10 reviews

Reviews for a place (by place_id, cid or fid), 10 per credit, sortable by newest or rating. Page with next_page_token.

Reviews for one place, identified by `place_id`, `cid` or `fid` (all three come back from [/v1/maps](https://serpkite.com/docs/endpoints/maps) and [/v1/places](https://serpkite.com/docs/endpoints/places)). Each call returns up to `num` reviews in `results` and a `next_page_token` for the next page.

## Request body

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `place_id` | string |  | Google place ID. One of `place_id`, `cid` or `fid` is required. |
| `cid` | string |  | Reviews: Google customer ID of the place. |
| `fid` | string |  | Reviews: Google feature ID of the place. |
| `sort` | string | `most_relevant` | Reviews: sort order. One of: `most_relevant`, `newest`, `highest_rating`, `lowest_rating`. |
| `page_token` | string |  | Reviews: next_page_token from the previous page, unchanged (bound to the place and sort). Paging reaches the first 100 reviews per sort order. |
| `num` | integer | `10` | Reviews per call, up to 50. Billed 1 credit per 10. |
| `country` | string | `us` | Country to search from, as a two-letter ISO code (us, gb, de, in…). |
| `language` | string | `en` | Interface language, as a language code (en, de, fr, pt-BR…). |
| `format` | string | `json` | Response format. markdown is LLM-ready prose; compact is JSON with only the fields agents need. One of: `json`, `compact`, `markdown`. |
| `fields` | string |  | Comma-separated projection, e.g. results.title,results.link,knowledge_graph. Cuts tokens. |
| `max_age` | integer |  | Accept a cached result up to this many seconds old. Cache hits cost 50% of the credits. |

## Example request

cURL:

```bash
curl https://api.serpkite.com/v1/reviews \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"place_id":"ChIJLU7jZClu5kcR4PcOOO6p3I0","sort":"newest"}'
```

TypeScript:

```ts
import { SerpKite } from "serpkite";

const sk = new SerpKite(); // reads SERPKITE_API_KEY
const res = await sk.reviews({ place_id: "ChIJLU7jZClu5kcR4PcOOO6p3I0", sort: "newest" });
console.log(res.results.length, res.next_page_token);
```

Python:

```python
from serpkite import SerpKite

sk = SerpKite()  # reads SERPKITE_API_KEY
res = sk.reviews(place_id="ChIJLU7jZClu5kcR4PcOOO6p3I0", sort="newest")
print(len(res.results), res.next_page_token)
```

## Response fields

| Field | Type | Description |
| --- | --- | --- |
| `request` | object | The normalised request, with defaults filled in: `endpoint`, `engine`, `q`, `country`, `language`, `location`, `num`, `page`, `device`, `autocorrect`… |
| `results[]` | array | `rating`, `date`, `iso_date`, `snippet`, `likes`, `user` (`name`, `thumbnail`, `reviews`), `response` (`snippet`, `date`) for owner replies. |
| `next_page_token` | string | Pass back as `page_token` (with the same place and `sort`) to get the next page. Absent on the last page and once the first 100 reviews are reached. |
| `meta` | object | `request_id`, `credits_used`, `cached`, `cached_at`, `engine` (the provider that answered), `route` (provider attempts, see [Search providers](https://serpkite.com/docs/providers)), `latency_ms`, `parse_quality` (`ok`, `partial`, `empty`), `resolved_urls`. |

## Example response

```json
{
  "request": {
    "endpoint": "reviews",
    "engine": "google",
    "place_id": "ChIJLU7jZClu5kcR4PcOOO6p3I0",
    "sort": "newest",
    "num": 10,
    "language": "en"
  },
  "results": [
    {
      "rating": 5,
      "date": "2 weeks ago",
      "iso_date": "2026-09-14T10:21:00Z",
      "snippet": "Great view from the top, book tickets online to skip the queue.",
      "likes": 3,
      "user": {
        "name": "Alex",
        "reviews": 41
      }
    }
  ],
  "next_page_token": "CAESBkVnSUlDZw",
  "meta": {
    "request_id": "req_01J8ZK4M6Q2V7",
    "credits_used": 1,
    "cached": false,
    "engine": "google",
    "latency_ms": 1034,
    "parse_quality": "ok",
    "resolved_urls": true
  }
}
```

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `invalid_request` | A parameter is missing or invalid. |
| 401 | `unauthorized` | The API key is missing, invalid or revoked. |
| 402 | `insufficient_credits` | Your balance is too low. Buy a pack or wait for the monthly free grant. |
| 429 | `rate_limited` | Too many requests per second for your plan. Retry after the Retry-After header. |
| 503 | `upstream_error` | Google could not be fetched or parsed. Not billed; retry after Retry-After. |

All errors: https://serpkite.com/docs/errors

## Notes

- Use `sort: "newest"` with `max_age` to monitor new reviews cheaply.

## Related

- [Maps](https://serpkite.com/docs/endpoints/maps)
- [Places](https://serpkite.com/docs/endpoints/places)