# Pitchup Campsite Reviews & Ratings Scraper (`gtforgedata/pitchup-campsite-reviews-scraper`) Actor

Extract campsite, glamping and holiday-park reviews from Pitchup. 52,000+ European sites with guest reviews, 1-10 ratings, and category sub-scores on every individual review.

- **URL**: https://apify.com/gtforgedata/pitchup-campsite-reviews-scraper.md
- **Developed by:** [GTForge Data](https://apify.com/gtforgedata) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 campsite 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

## Pitchup Campsite Reviews & Ratings Scraper

Extract **campsite, glamping and holiday-park reviews** from
[Pitchup](https://www.pitchup.com) — **52,000+ outdoor accommodation sites** across the UK,
France, Spain, Italy, the Netherlands and beyond.

Built for outdoor-hospitality analytics, park groups, booking platforms and travel research teams
who need structured European camping review data.

### The thing that makes this different

Most review sources give you one number per venue. **Pitchup publishes category sub-scores on
every individual review**, and this actor returns all of them:

```
location · value for money · accommodation · facilities
customer service · child friendliness · cleanliness · wifi
```

A venue average tells you a site scores 9.4. **Per-review scores tell you which guests marked
cleanliness 2 while rating location 5** — and when. That is the difference between a dashboard
number and something you can actually act on, and no other camping source on this store returns it.

Skipped categories come back as `null`, never `0`. A guest who did not rate wifi and a guest who
rated it zero mean opposite things, and collapsing them quietly corrupts every average built on
top.

### What you get

Per campsite:

| Field | Detail |
|---|---|
| Profile | name, Pitchup id, full postal address, region, country |
| Coordinates | latitude and longitude |
| Aggregate rating | native **1–10** score **and** a 0–5 normalisation for cross-source comparison |
| Category averages | the 8 published dimensions at venue level |
| Review count | the site's total, so you know what a sample represents |

Per review:

| Field | Detail |
|---|---|
| Review id | Pitchup's own id — **stable across runs**, so incremental syncs dedupe cleanly |
| Rating | native 1–10 plus the 0–5 normalisation |
| Text | full review, with the site's **Liked / Disliked** split preserved |
| Category scores | the guest's own sub-scores, `null` where they skipped one |
| Author | display name and profile URL |
| Date | **ISO-8601** publish timestamp |
| Reviewer country | where the guest travelled from |
| Pitch booked | the exact pitch or unit type they stayed in |
| Recommends | whether they would recommend it and return |

### One schema across sources

Ratings carry both the site's native scale **and** a normalised 0–5 value, so this data merges
with other sources without transformation code. Useful if you already ingest campsite or hotel
review feeds and want European outdoor coverage on the same shape.

### Use cases

- **Park group benchmarking** — compare a site against its regional set on eight dimensions
- **Reputation monitoring** — track score and new reviews over time, deduped by review id
- **Booking platform enrichment** — add reviews and coordinates to 52,000+ European sites
- **Complaint analysis** — find which categories drive low scores, per guest, with dates
- **Text analytics** — clean English review text, already split into positives and negatives

### Input

| Field | Meaning |
|---|---|
| `venueUrls` | Pitchup campsite page URLs |
| `discoverAll` | Ignore the list and enumerate campsites from the sitemaps |
| `maxVenues` | Bound the run (default 100) |
| `includeReviews` | Off = profiles + aggregate ratings only, at lower cost |
| `outputMode` | `venue` (nested), `review` (flat rows), or `both` |
| `minReviewCount` | Skip thin listings — **skipped campsites are not charged** |

```json
{
  "venueUrls": [
    "https://www.pitchup.com/campsites/England/South_West/Somerset/wrantage/5-acres/"
  ],
  "includeReviews": true,
  "outputMode": "venue",
  "maxVenues": 100
}
```

### Residential proxy is required

Pitchup blocks datacenter IP ranges. Measured 2026-08-10, same code and same request each time:

| Route | Result |
|---|---|
| Direct from the platform | **403** |
| Datacenter proxy | **403** |
| **Residential proxy** | **200**, full page, all reviews |

The input defaults to Apify Proxy with the `RESIDENTIAL` group, so it works out of the box.
Proxy usage is billed by Apify to the account running the Actor, and residential bandwidth is the
main cost of a large sweep — campsite pages are around 1.4 MB each. Two ways to keep that down:

- set **`minReviewCount`** so thin listings are never fetched
- turn **`includeReviews`** off when you only need profiles and aggregate scores

### Honest notes

**Each campsite page carries about 10 reviews**, of what is often far more — the 5 Acres example
has 133. Every row is flagged `reviewsTruncated` with the true `totalReviewCount`, so a partial
sample is always labelled as one rather than passed off as complete.

**Catalogue sweeps hit a long tail of sites with no reviews at all.** Use `minReviewCount` to skip
them; skipped campsites are not charged.

**This actor is polite by design** — one request per 800 ms per host, robots.txt enforced on every
request, and the booking and payment paths the site disallows are never fetched.

### Support

Issues and field requests: open an issue on the actor, or see
[gtforgedata.com](https://gtforgedata.com).

# Actor input Schema

## `venueUrls` (type: `array`):

Pitchup campsite pages, e.g. https://www.pitchup.com/campsites/England/South\_West/Somerset/wrantage/5-acres/. Leave empty and enable 'Scrape all campsites' to sweep the catalogue.

## `discoverAll` (type: `boolean`):

Ignore the URL list and enumerate campsites from Pitchup's sitemaps (52,000+). Always pair with 'Max campsites'.

## `maxVenues` (type: `integer`):

Upper bound on campsites processed in one run.

## `includeReviews` (type: `boolean`):

Include individual guest reviews with their per-review category scores. Turn off for a cheaper run returning only campsite profiles and aggregate ratings.

## `outputMode` (type: `string`):

'venue' = one row per campsite with reviews nested. 'review' = one flat row per review. 'both' = campsite row followed by its review rows.

## `maxConcurrency` (type: `integer`):

Parallel campsite fetches. Requests are additionally rate-limited per host to stay polite.

## `requestDelayMs` (type: `integer`):

Extra politeness delay. The actor enforces its own 800ms minimum for this source regardless of this value.

## `minReviewCount` (type: `integer`):

Skip campsites with fewer than this many reviews. Catalogue sweeps hit a long tail of listings with no reviews at all — skipped campsites are NOT charged. Leave at 0 to return everything.

## `proxyConfiguration` (type: `object`):

Pitchup blocks datacenter IPs. Verified 2026-08-10: direct and datacenter proxy both return 403; residential returns 200. Residential proxy is REQUIRED — leaving this off will make every request fail.

## Actor input object example

```json
{
  "venueUrls": [
    "https://www.pitchup.com/campsites/England/South_West/Somerset/wrantage/5-acres/"
  ],
  "discoverAll": false,
  "maxVenues": 100,
  "includeReviews": true,
  "outputMode": "venue",
  "maxConcurrency": 4,
  "requestDelayMs": 800,
  "minReviewCount": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "venueUrls": [
        "https://www.pitchup.com/campsites/England/South_West/Somerset/wrantage/5-acres/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("gtforgedata/pitchup-campsite-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 = {
    "venueUrls": ["https://www.pitchup.com/campsites/England/South_West/Somerset/wrantage/5-acres/"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("gtforgedata/pitchup-campsite-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 '{
  "venueUrls": [
    "https://www.pitchup.com/campsites/England/South_West/Somerset/wrantage/5-acres/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call gtforgedata/pitchup-campsite-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gtforgedata/pitchup-campsite-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/If0s3o7yWelLXp8jh/builds/ykZglzDjKYV7Pyde8/openapi.json
