# Google Maps Reviews Scraper - $0.27 per 1,000 Reviews (`dami_studio/google-maps-reviews-scraper`) Actor

$0.27 per 1,000 reviews, the cheapest Google Maps reviews scraper on the market. Star rating, full text, exact date, reviewer with lifetime review count, owner reply and photos, from a place link, place ID, CID or business name. No API key, no quota, no five-review cap.

- **URL**: https://apify.com/dami\_studio/google-maps-reviews-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.27 / 1,000 review scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Maps Reviews Scraper

Point it at a Google Maps place — a link, a place ID, a CID or just the business name — and get its reviews back as flat rows: star rating, the full review text, the exact date, the reviewer with their lifetime review and photo counts, the owner's reply, and the photos attached to the review. It pages through the whole review history, not just the first screen. No account, no cookies, no login, no browser.

- Four ways to name a place: a Maps link straight from the address bar, a short maps.app.goo.gl link, a place ID, a numeric CID, or the business name.
- Full pagination — ask for 5 reviews or 5,000 and it keeps turning pages until it has them.
- Sort newest, most relevant, highest or lowest, exactly like the Reviews tab does.
- "Only reviews since" turns it into a monitor: with newest-first it stops as soon as it is past your cutoff, so a daily check costs a couple of requests.
- Owner replies come back on the same row as the review they answer, so a complaint and the response to it are never separated.
- Exact publication timestamps, not just "3 months ago" — both are on the row.
- Reviews written in another language are translated into the language you asked for, with the writer's original wording kept alongside.
- Runs with empty input return a labelled sample row, free, so you can see the shape first.

### Price

**$0.27 per 1,000 reviews**, plus a **$0.0005 start fee per run** (billed per gigabyte of run memory, so exactly that on the default 1 GB).

This is **the cheapest Google Maps reviews scraper on the market**, and it is the same rate on every plan, free or paid. There are no volume tiers, no minimum spend, no subscription and no add-on fees. What you read here is what you pay on day one and on day four hundred.

| Reviews | Total cost |
|---|---|
| 100 | $0.0275 |
| 1,000 | $0.2705 |
| 10,000 | $2.7005 |
| 100,000 | $27.0005 |

#### What is actually charged

- **One `review-scraped` event per review row written to the dataset.** Nothing else is metered per row.
- **Free:** the sample row an empty run returns, and every diagnostic row — a blocked target, a dead URL, a search that matched nothing. Those rows all carry `"charged": false`.
- Star-only ratings you filtered out with "Skip star-only ratings" are dropped before they are charged.
- Reviews older than your "Only reviews since" cutoff are dropped before they are charged.
- Reviews already returned earlier in the same run are deduplicated on review ID and charged once.
- Looking a place up from its name, its short link or its place ID is part of the run, not a separate charge.
- A run that finds nothing costs the start fee and nothing more.
- Rows never leave the dataset without a charge, and are never charged without a row. The billed event is a named one, so there is no price quietly attached to `apify-default-dataset-item` — the trick that makes some scrapers bill you for their own error messages.

### Input

```json
{
  "placeUrls": [
    "https://www.google.com/maps/place/Katz's+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea",
    "ChIJN1t_tDeuEmsRUsoyG83frY4"
  ],
  "searchTerms": [
    "Pike Place Chowder Seattle"
  ],
  "maxReviews": 300,
  "maxReviewsPerPlace": 100,
  "sort": "newest",
  "reviewsSince": "90 days",
  "onlyWithText": true,
  "language": "en"
}
```

| Field | What it does |
|---|---|
| `placeUrls` | Maps links, short links, place IDs (`ChIJ…`) or numeric CIDs. Up to 50 per run. Paste the link exactly as the address bar gives it to you — the coordinates and tracking parameters in it are ignored. |
| `searchTerms` | Business names to look up first, e.g. `Katz's Delicatessen New York`. The top matching place is used. Add the town or city: a bare `Starbucks` can match anywhere on earth. |
| `maxReviews` | Total reviews across every place in the run. The budget is split evenly between the places, so five places and 100 reviews gives you twenty each. Default 20, hard ceiling 5,000. Keep it low while testing — you pay per review. |
| `maxReviewsPerPlace` | Optional per-place cap on top of the total. Use it when one place has 40,000 reviews and you only want the newest hundred from each. |
| `sort` | `newest`, `relevant`, `highest` or `lowest`. Newest for monitoring; relevant returns the longer, photo-heavy reviews Google promotes to the top of the tab. |
| `reviewsSince` | A cutoff, written either as a date (`2026-01-01`) or as a window (`30 days`). Combined with newest-first it also ends the paging, which is what makes a scheduled monitor cheap. |
| `onlyWithText` | Google counts a bare star rating with no words as a review. Turn this on and those are dropped before they are charged. |
| `language` | Two-letter code for the language you want the reviews in (`en`, `de`, `fr`, `es`, …). Foreign-language reviews are translated into it and the original wording is kept in `originalText`. |
| `country` | Two-letter country code for the Google edition to read (`us`, `gb`, `de`, …). Mostly affects how dates and place names are written. |
| `proxyUrls` | Leave empty. Fill it in only if you want the traffic to leave through proxy servers you already pay for, as `http://user:pass@host:port`. |

Run it with **empty input** and you get one clearly labelled sample row, free, so you can see the output shape before you spend anything.

### Output

One row per review. A real row from a real run:

```json
{
  "ok": true,
  "charged": true,
  "recordType": "review",
  "target": "https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e",
  "placeName": "Starbucks Reserve Roastery",
  "placeUrl": "https://www.google.com/maps?cid=7899526995152106350",
  "placeId": "ChIJsU30zM1qkFQRbnOm1_LBoG0",
  "cid": "7899526995152106350",
  "featureId": "0x54906acdccf44db1:0x6da0c1f2d7a6736e",
  "reviewId": "Ci9DQUlRQUNvZENodHljRjlvT2toT0xYYzNkWFJqVlRaUFlVNHRObG94TWtWU05tYxAB",
  "rating": 5,
  "text": "Tried the flight and tiramisu latte. Both were pretty good. Prices are pretty high though around 10-15 dollars for coffee and the wait time to get your order was around 40 minutes.",
  "originalText": null,
  "language": "en",
  "publishedAt": "2025-09-25T07:31:34.977Z",
  "relativeDate": "10 months ago",
  "reviewerName": "A. Reviewer",
  "reviewerUrl": "https://www.google.com/maps/contrib/000000000000000000000/reviews?hl=en-US",
  "reviewerPhotoUrl": "https://lh3.googleusercontent.com/a-/example=s64-c-rp-mo-ba12-br100",
  "reviewerReviewsCount": 580,
  "reviewerPhotosCount": 1322,
  "isLocalGuide": true,
  "ownerReply": "Hi there, we apologize for the long wait time you experienced. If you would like to share additional details or feedback, please get in touch through our Contact Us page!",
  "ownerReplyRelativeDate": "10 months ago",
  "reviewPhotosCount": 1,
  "reviewPhotoUrls": [
    "https://lh3.googleusercontent.com/grass-cs/ACvplmOBJA3PJJYg_dTGWYHdAOjL4eb8rXecb_4RtOrVKLk8D0IJyiV7LHm4q09eqGFjK1zeSep2lmcmGrgmFyVTvnLL8yQpPvmE0R1C5LkVb7aZ2rvhNzMEvGQAQHyAl9Jj1IHfGMWHQIuNF8yS=k-no"
  ],
  "reviewUrl": "https://www.google.com/maps/reviews/data=!4m8!14m7!1m6!2m5!1sCi9DQUlRQUNvZENodHljRjlvT2toT0xYYzNkWFJqVlRaUFlVNHRObG94TWtWU05tYxAB",
  "scrapedAt": "2026-08-15T22:44:25.870Z"
}
```

#### Field notes

- `target` — the exact string you supplied for this place, so you can join the rows back to your input list.
- `placeName` — filled in when the link you pasted carried the name in it, or when Google's answer to a name lookup included it. A bare place ID or CID carries no name, and Google sometimes answers a lookup with the identifier only, so this can be null — the place is still fully identified by `placeUrl`, `placeId`, `cid` and `featureId`, and `target` still holds what you asked for.
- `placeUrl` — a clean, permanent link to the place. Safe to store; it does not expire the way a copied address-bar URL does.
- `placeId` — the `ChIJ…` identifier Google publishes. Null when the run only ever knew the place by CID.
- `rating` — the star rating, 1 to 5, as an integer.
- `text` — the review in the language you asked for. Null when the reviewer left stars and no words.
- `originalText` — the reviewer's own wording, present only when it differs from `text` — i.e. only when the review was translated.
- `publishedAt` — the exact moment the review was posted, ISO 8601 in UTC. This is the field to sort and diff on.
- `relativeDate` — the wording Google shows ("3 months ago"). Convenient for display, useless for sorting.
- `reviewerReviewsCount` — how many reviews that person has written in total, across all places — a decent proxy for how seriously to take the review.
- `reviewerPhotosCount` — how many photos that person has contributed in total.
- `isLocalGuide` — true when Google badges the reviewer as a Local Guide.
- `ownerReply` — the business owner's public response, on the same row as the review it answers. Null when there is none.
- `reviewPhotosCount` — how many photos are attached to this review.
- `reviewPhotoUrls` — direct links to those photos, up to ten per review. They are Google-hosted and can be resized by editing the size suffix.
- `reviewUrl` — a permanent link to this single review on Google Maps.

Every real row carries `"charged": true`. Sample rows carry `"_sample": true` and diagnostic rows carry `"_diagnostic": true` with an `errorCode` you can filter on, and neither is ever billed.

### How it works

- It reads reviews from the same public data service the Reviews tab itself calls, and asks it directly for the reviews of one place — no page rendering, no headless browser, no login, no cookies.
- A Maps link, a place ID and a CID all already contain the identifier the service needs, so those are decoded locally and cost no request at all. Only a business name needs a lookup first, and that is one small call.
- Reviews are pulled in pages of up to fifty, following Google's own pagination token, and the run asks for only as many as you still need — sampling three reviews does not download fifty.
- Requests leave through a large pool of rotating datacenter addresses, so a per-address rate limit is answered by moving rather than by waiting.
- Review IDs are remembered for the whole run, so the same review is never returned — or charged — twice.

### What people use it for

- Reputation monitoring: schedule the same places daily with `sort: newest` and `reviewsSince: "2 days"`, and you get only what is new — a handful of billed rows each time instead of the whole history.
- Answering complaints: `ownerReply` sits on the same row as the review, so filtering for `rating <= 2 AND ownerReply == null` gives you the exact list of unhappy customers nobody has replied to yet.
- Competitive benchmarking across a set of locations: pull the same number of newest reviews for each place and compare average rating, reply rate and review velocity side by side.
- Sentiment and topic analysis: `text` is the full review body, already translated into one language, which is what a classifier or an LLM wants as input.
- Location audits for chains and franchises: feed a list of place IDs, cap `maxReviewsPerPlace`, and get a comparable sample from every branch in one dataset.
- Due diligence on a business before buying, partnering with or franchising it — the full history, with dates, rather than the handful of reviews the page shows.
- Academic and market research where you need reviews with exact timestamps, reviewer experience counts and photo counts as structured columns.

### Naming a place four different ways

All of these point at the same restaurant, and all of them work:

```
https://www.google.com/maps/place/Katz's+Delicatessen/@40.7223,-73.9874,17z/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8cea
https://maps.app.goo.gl/xxxxxxxxxxxxxxxx
ChIJCar0f49ZwokR6ozLV-dHNTE
3545819340560108778
```

Put any of them in `placeUrls`. Put a plain business name in `searchTerms` instead and the run looks it up first. The three identifier forms are decoded without contacting Google at all, so they are the fastest and the most precise — if you are running the same list every day, store the `placeId` or `cid` from your first run and use that from then on.

### Reading the output

Every run writes three kinds of row, and they are easy to tell apart:

- **Real rows** carry `"charged": true` and `"recordType": "review"`. These are the rows you paid for, one billed event each.
- **The sample row** carries `"_sample": true` and `"charged": false`. There is exactly one, it only appears when the input named no place at all, and it exists so you can look at the shape of the output before you spend anything.
- **Diagnostic rows** carry `"_diagnostic": true`, `"charged": false` and an `errorCode` you can switch on: `NO_PLACE_FOUND` when a name matched nothing on Maps, `NO_REVIEWS` when a place has no reviews (or none matching your filters), `SHORTLINK_UNRESOLVED` or `PLACE_ID_UNRESOLVED` when an identifier could not be expanded, `REVIEWS_403`/`REVIEWS_429` when Google throttled the run, `NETWORK` when the service could not be reached, and `TIME_BUDGET` when the run ran out of time before reaching a place. Each one carries a plain-English `error` and the `target` it belongs to.

If you only want the data, filter on `charged == true`. The count of those rows always equals the number of events you were billed for, so the dataset is its own invoice.

### Making a scheduled monitor cheap

The combination that matters is `sort: "newest"` plus `reviewsSince`. With newest-first, the run can stop paging a place the moment it crosses your cutoff, because everything after that point is older still. A place that got two new reviews since yesterday therefore costs one request and two billed rows — not a walk through its 40,000-review history.

Set `reviewsSince` a little wider than your schedule interval (`"2 days"` for a daily run) so a late-arriving review is never missed, and deduplicate on `reviewId` on your side. Review IDs are stable, so the same review always arrives with the same ID.

### Limitations

- Reviews only. Place details — opening hours, phone number, address, category, the overall star average and the total review count — are not part of this Actor's output.
- `placeName` is null when the place was identified by a bare place ID or CID, and also when a name lookup came back with the identifier but no label — Google decides which of its two answer shapes to send. Everything else on the row still identifies the place, and `target` still holds exactly what you asked for.
- Pagination is Google's, and it is bound to the page size the run started with. That is handled internally, but it does mean a place is read in one consistent pass rather than resumed later from a stored cursor.
- Google does not expose its entire review history through this route. Very large places return several thousand reviews and then stop handing out pagination tokens; the hard ceiling here is 5,000 per run in any case.
- A review can be edited or deleted after it was written. Rows are a snapshot at read time, and `scrapedAt` records when that was.
- Star-only ratings have no text — roughly a quarter of what a busy place receives. `text` is null for those unless you turn on "Skip star-only ratings".
- Translation is Google's own. `text` comes back in the language you asked for and `originalText` holds the writer's wording; the quality of the translation is not something this Actor controls.
- "Local Guide" is a badge, not a level. The badge is reported as true or false; the numeric level Google shows on some profiles is not.
- Photo links are Google-hosted CDN URLs. They are stable for a long time but are not archival — download anything you need to keep.
- A business name that matches several places resolves to Google's top match. If you need a specific branch, use its link or place ID instead of its name.
- Sorting is Google's, applied before pagination. Asking for 20 reviews sorted "highest" gives you the 20 highest Google is willing to serve first, not a full sort of the whole history.
- Very heavy runs can be throttled by Google; the run reports that as an uncharged diagnostic row and keeps whatever it already collected rather than failing.
- The row budget is split evenly between your places. A place with fewer reviews than its share simply returns fewer rows; the leftovers are not handed to the other places.

### Questions

**Do I need a Google API key?**

No. Nothing here uses the Google Maps Platform, so there is no key to obtain, no quota to manage and no per-place billing from Google. There is also no five-review cap, which is what the official Places API gives you.

**How many reviews can I get for one place?**

As many as Google will page out, up to the 5,000-per-run ceiling. Several thousand is normal for a large, busy place; small places simply run out of reviews and the run moves on to the next place.

**What happens if a place has no reviews at all?**

You get one uncharged diagnostic row with `errorCode: "NO_REVIEWS"`, and the run carries on to your other places. You are never billed for a place that returned nothing.

**Will the run fail if Google throttles it?**

No. It moves to a different address and tries again, and if it still cannot get through it writes an uncharged diagnostic row and finishes as succeeded, keeping everything it already collected. A failed run would still bill you the start fee, which would mean paying to be told something went wrong.

**Can I get the reviews in English for a place in Japan?**

Yes — set `language` to `en`. Google translates the reviews into it and the reviewer's original wording arrives in `originalText`, so you can keep both.

**Do I need a proxy?**

No. The run brings its own egress and the cost of it is already inside the price you see. The `proxyUrls` field exists only for callers who specifically want traffic to leave through servers they already own.

**Can I run this on a schedule?**

Yes. Nothing is held between runs, so the same input is safe to repeat. Use `sort: "newest"` with `reviewsSince` to pay only for what is new, and deduplicate on `reviewId`.

**How do I get exactly the rows I paid for?**

Filter the dataset on `"charged": true`. Sample and diagnostic rows are always `false`, and the number of charged rows always equals the number of billed events.

# Actor input Schema

## `placeUrls` (type: `array`):

Google Maps place links (https://www.google.com/maps/place/... or a maps.app.goo.gl short link), place IDs (ChIJ...), or numeric CIDs. Up to 50 per run. Copy the link straight from the address bar - all the extra junk in it is ignored.

## `searchTerms` (type: `array`):

Business names to find on Google Maps first, e.g. "Katz's Delicatessen New York". The top matching place is used. Include the town or city - a bare "Starbucks" can match anywhere in the world.

## `maxReviews` (type: `integer`):

Total reviews to return across every place in this run. The budget is shared evenly between the places, so five places and 100 reviews gives you twenty of each. Hard ceiling 5,000. Keep it low while testing - you pay per review.

## `maxReviewsPerPlace` (type: `integer`):

Optional cap for a single place, on top of the total above. Useful when one place has 50,000 reviews and you only want the latest 100 from each.

## `sort` (type: `string`):

Which reviews Google hands over first. Newest is the right choice for monitoring; Most relevant returns the longer, photo-heavy reviews Google promotes.

## `reviewsSince` (type: `string`):

Optional cutoff. Either a date like 2026-01-01 or a window like "30 days". With Newest first the run stops paging a place as soon as it is past the cutoff, so a daily monitor costs a couple of requests instead of a full history pull.

## `onlyWithText` (type: `boolean`):

Google counts a bare star rating with no words as a review. Turn this on to drop those, so you only pay for reviews that actually say something.

## `language` (type: `string`):

Two-letter language code for the reviews, e.g. en, de, fr, es. Reviews written in another language come back translated, with the writer's original wording kept in originalText.

## `country` (type: `string`):

Two-letter country code for the Google edition to read, e.g. us, gb, de. Mostly affects how dates and place names are written.

## `proxyUrls` (type: `array`):

Leave this empty. By default the run rotates a large pool of addresses that cost you nothing per gigabyte. Fill it in only if you specifically want the traffic to leave through proxy servers you already pay for, in the form http://user:pass@host:port.

## Actor input object example

```json
{
  "placeUrls": [
    "https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e"
  ],
  "maxReviews": 20,
  "sort": "newest",
  "language": "en",
  "country": "us"
}
```

# Actor output Schema

## `results` (type: `string`):

Every row in the default dataset: target, placeName, placeUrl, placeId, cid, featureId, reviewId, rating, text, originalText, language, publishedAt, relativeDate, reviewerName, reviewerUrl, reviewerPhotoUrl, reviewerReviewsCount, reviewerPhotosCount, isLocalGuide, ownerReply, ownerReplyRelativeDate, reviewPhotosCount, reviewPhotoUrls, reviewUrl, scrapedAt. An empty, blocked or unmatched run returns a single uncharged row explaining what happened instead.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "placeUrls": [
        "https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e"
    ],
    "maxReviews": 20,
    "sort": "newest",
    "language": "en",
    "country": "us"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/google-maps-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "placeUrls": ["https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e"],
    "maxReviews": 20,
    "sort": "newest",
    "language": "en",
    "country": "us",
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/google-maps-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "placeUrls": [
    "https://www.google.com/maps/place/Starbucks+Reserve+Roastery/data=!4m2!3m1!1s0x54906acdccf44db1:0x6da0c1f2d7a6736e"
  ],
  "maxReviews": 20,
  "sort": "newest",
  "language": "en",
  "country": "us"
}' |
apify call dami_studio/google-maps-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-maps-reviews-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ApbVeQA01Detw5chW/builds/EiIe5q9GnpRYxpgt1/openapi.json
