# Rover Pet Care Scraper - Sitters, Rates & Reviews (`abotapi/rover-pet-care-scraper`) Actor

Scrape Rover.com pet-care providers: sitter search by city, rates per stay type, ratings and review history, verification badges, repeat clients, response times, service policies and availability signals.

- **URL**: https://apify.com/abotapi/rover-pet-care-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 pet-care service records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Rover Pet Care Scraper

Structured pet-care service records from Rover: sitter search by city, full
sitter profiles, rates, verification badges, response stats, policies and the
complete review history.

### What you get

One record per sitter (40+ fields), including:

- **Rates**: price per service unit (night/walk/visit), the full add-on rate
  table from the profile (holiday rate, additional dog, pick-up and drop-off),
  currency.
- **Quality signals**: average rating, rating distribution, total ratings,
  years of experience, repeat clients, Star Sitter flag, engagement label,
  availability recency.
- **Profile**: headline, full description, response rate and response time,
  photo-update rate, member since, verification badges, own pets.
- **Services**: every service the sitter offers with spaces available, dog
  sizes and cats accepted, home attributes, cancellation policy, customer
  policy flags.
- **Reviews**: the review history embedded in the record (rating, date,
  service, text, sitter reply, reviewer name, pet names).
- **Location**: neighborhood, city, state, ZIP, coordinates, distance from
  the searched location.

### Modes

- **Search** (default): enter one or more locations (city, neighborhood or
  ZIP). Each location is resolved through Rover's own geocoder and every
  matching sitter page is walked forward. Service type (boarding, day care,
  walking, drop-in) and pet type (dog/cat) are applied by the source as
  search settings.
- **URL mode**: paste sitter profile links (`rover.com/members/...`), sitter
  search links (`rover.com/search/...`), or city pages like
  `rover.com/san-francisco--ca--dog-boarding/`.
- **Filters** (minimum rating, min/max rate, Star Sitters only) apply in
  BOTH modes: they narrow Search-mode walks and every search or city page
  walked in URL mode. Sitter profile links return their full record
  regardless of filters.

### Enrichment

`Fetch full profiles` and `Fetch reviews` (both on by default) read each
sitter's profile and review history in the detail phase. Every enriched
sitter adds one small per-sitter surcharge (see the input description for
the exact event); with both toggles off you get the fast search-card fields
only. A per-sitter review cap (`Max reviews per sitter`, 0 = all) bounds the
embedded review list.

### Limits

`Max items` is the only cap that stops a run early, and it **defaults to
20** — one search page. Raise it, or set it to 0 for no limit, to collect
more. `Max pages per search` and `Max reviews per sitter` still default to
0 (no limit); searches also stop at their natural end.

### Resume and recurring updates

- **Resume from a previous run**: continue one interrupted pull; records
  already collected there are skipped.
- **Incremental mode**: for scheduled monitoring of the same search. First
  run marks everything NEW; later runs return only NEW, UPDATED and
  REAPPEARED records. UNCHANGED and EXPIRED rows are opt-in because they
  return, and bill, extra rows.
- **Rate display volatility**: the source flips the displayed rate
  (`pricePerUnit`) between two display states about 12.5% apart (e.g. 48 to
  54\) between runs, with no underlying change. Incremental mode excludes it
  from change detection and from the stored baseline, so a display flip
  alone never marks a sitter UPDATED; the value itself is still in every
  emitted record. A genuine rate change is therefore not flagged by
  incremental mode either - the embedded `services` rate table always shows
  the current rate.
- **EXPIRED needs a full scan**: the source sometimes serves a reduced
  result window after heavy use, ending exactly like a natural end. When a
  run could see fewer sitters than the source itself reports as matching,
  EXPIRED detection is skipped for that run rather than guessing.

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | `search` | `search` (locations + filters) or `url` (paste links) |
| locations | array | `["San Francisco, CA, USA"]` | Cities, neighborhoods or ZIP codes to search around (search mode) |
| serviceType | string | `overnight-boarding` | `overnight-boarding`, `doggy-day-care`, `dog-walking`, `drop-in` (search mode) |
| petType | string | `dog` | `dog` or `cat` (search mode) |
| minRating | integer | `0` | Minimum star rating, 1 to 5; 0 = no floor. Applies in BOTH modes |
| minPrice | integer | `0` | Minimum rate per service unit; 0 = no floor. Applies in BOTH modes |
| maxPrice | integer | `0` | Maximum rate per service unit; 0 = no ceiling. Applies in BOTH modes |
| starSitter | boolean | `false` | Star Sitters only. Applies in BOTH modes |
| urls | array | empty | Sitter profiles, sitter-search pages or city pages (url mode) |
| fetchDetails | boolean | `true` | Read each sitter's full profile (adds the per-sitter surcharge) |
| fetchReviews | boolean | `true` | Read each sitter's review history (adds the per-sitter surcharge) |
| maxReviewsPerSitter | integer | `0` | Cap the embedded review list per sitter, newest first; 0 = all |
| maxItems | integer | `20` | Max sitter records in total; the only cap that stops a run early; 0 = no limit |
| maxPages | integer | `0` | Page cap per search, 20 sitters per page; 0 = no limit |
| resumeFromRunId | string | empty | Continue ONE interrupted run/dataset without re-collecting its sitters |
| incrementalMode | boolean | `false` | Recurring monitoring of the same search: later runs return only NEW/UPDATED/REAPPEARED sitters |
| stateKey | string | empty | Optional name for an incremental-mode monitoring campaign; auto-derived when empty |
| emitUnchanged | boolean | `false` | Incremental mode only: also return (and bill for) unchanged sitters |
| emitExpired | boolean | `false` | Incremental mode only: also return (and bill for) sitters no longer found, once a run fully scans the tracked search |
| mcpConnectors | array | empty | MCP connectors to export results into (optional; never changes the dataset) |
| notionParentPageUrl | string | empty | Notion parent page under which item pages are created (Notion connector only) |
| maxNotifyListings | integer | `50` | Cap on items written to each connector per run; does not affect the dataset |
| proxyConfiguration | object | Standard pool | Connection settings; the default standard pool works on every proxy plan |

### Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, API & Integrations, then select it in the `mcpConnectors` field. Each connector receives a condensed, human-readable summary per sitter, while the complete record always stays in the Apify dataset. For Notion, set `notionParentPageUrl` to the page the item pages should be created under, and optionally cap the export per connector with `maxNotifyListings`. Supported connectors: Notion, Linear, Airtable, and Apify. Leave the field empty to skip; it never changes the dataset output.

### Sample output

Values below are unmistakably fictional examples of the record shape:

```json
{
  "kind": "sitter",
  "recordId": "SA1MPLE1",
  "shortName": "Sitter One S.",
  "headline": "Loving care for your sample pets",
  "url": "https://www.rover.com/members/sitter-one-sample-profile/",
  "serviceType": "overnight-boarding",
  "pricePerUnit": 56.0,
  "priceUnit": "night",
  "city": "Sample City",
  "state": "CA",
  "ratingsAverage": 5.0,
  "ratingsCount": 12,
  "yearsOfExperience": 5,
  "isStarSitter": true,
  "verificationBadges": ["Verified Sample Background Check"],
  "responseTimeText": "Usually responds in a few minutes",
  "memberSince": "2019-03-10",
  "repeatClients": 7,
  "reviewsTotalRatings": 15,
  "reviewsDistribution": {"5star": 10, "4star": 2, "3star": 0, "2star": 0, "1star": 0},
  "reviews": [
    {"rating": 5, "date": "2026-08-10", "serviceName": "Boarding",
     "text": "Sample review text.", "sitterReply": null,
     "reviewerName": "Reviewer A.", "petNames": ["Biscuit"]}
  ],
  "services": [
    {"name": "Boarding", "slug": "overnight-boarding", "standardRate":
     {"name": "Standard Rate", "price": 56.0, "unit": "night"}}
  ]
}
```

### Usage notes

- The default proxy configuration uses the standard shared pool and works
  on every proxy plan; if your plan includes residential or other dedicated
  groups, select them in the proxy input.
- Rate data is the sitter's standard rate; holiday and add-on rates are in
  the embedded `services` block.
- City landing pages cover the platform's pet-care services; training pages
  are not part of the sitter search and are skipped in URL mode.

# Actor input Schema

## `mode` (type: `string`):

How to find sitters: search around one or more locations, or paste sitter, search or city page links.

## `locations` (type: `array`):

Cities, neighborhoods or ZIP codes to search around (Search mode), e.g. 'San Francisco, CA, USA'. Each location is searched separately.

## `serviceType` (type: `string`):

Which service the search covers (Search mode).

## `petType` (type: `string`):

Which pet the sitter must care for (Search mode).

## `urls` (type: `array`):

Rover links (URL mode): sitter profiles (/members/...), sitter-search pages (/search/...), or city pages like <city>--<ST>--dog-boarding.

## `minRating` (type: `integer`):

Only sitters rated at least this many stars, 1 to 5 (0 or empty = no floor). Applies in BOTH modes: it narrows Search-mode walks and every search or city page walked in URL mode.

## `minPrice` (type: `integer`):

Only sitters charging at least this much per service unit (0 = no floor). Applies in BOTH modes: it narrows Search-mode walks and every search or city page walked in URL mode.

## `maxPrice` (type: `integer`):

Only sitters charging at most this much per service unit (0 = no ceiling). Applies in BOTH modes: it narrows Search-mode walks and every search or city page walked in URL mode.

## `starSitter` (type: `boolean`):

Only return sitters in the platform's Star Sitter program (top-rated, responsive). Applies in BOTH modes: it narrows Search-mode walks and every search or city page walked in URL mode.

## `fetchDetails` (type: `boolean`):

Read each sitter's full profile: services and rate tables, home and care policies, verification badges, response stats, repeat clients, own pets.

## `fetchReviews` (type: `boolean`):

Read each sitter's review history (rating, date, service, text, sitter reply) and the rating distribution, embedded in the record.

## `maxReviewsPerSitter` (type: `integer`):

Cap the embedded review list per sitter, newest first (0 = all reviews).

## `maxItems` (type: `integer`):

Stop after this many sitter records in total. Defaults to 20 (one search page). Set 0 for no limit. This is the only limit that stops a run early by default.

## `maxPages` (type: `integer`):

Stop each search after this many sitter pages, 20 sitters per page (0 = no limit; searches also stop at their natural end).

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching record as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, filter and URL setup; use State key to name or deliberately share a monitoring campaign. The displayed rate (pricePerUnit) is excluded from change detection: the source flips it between two display states between runs with no underlying change, so a rate-display flip alone never marks a sitter UPDATED.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search and filter settings.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search; the source sometimes serves a reduced result window after heavy use, and a run that could not see every matching sitter skips EXPIRED detection rather than guessing.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

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

Apify Proxy settings. The default uses the standard shared pool and works on every proxy plan; if your plan includes residential or other dedicated groups, name them here.

## Actor input object example

```json
{
  "mode": "search",
  "locations": [
    "San Francisco, CA, USA"
  ],
  "serviceType": "overnight-boarding",
  "petType": "dog",
  "urls": [
    "https://www.rover.com/san-francisco--ca--dog-boarding/"
  ],
  "minRating": 0,
  "minPrice": 0,
  "maxPrice": 0,
  "starSitter": false,
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerSitter": 0,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "locations": [
        "San Francisco, CA, USA"
    ],
    "serviceType": "overnight-boarding",
    "petType": "dog",
    "urls": [
        "https://www.rover.com/san-francisco--ca--dog-boarding/"
    ],
    "minRating": 0,
    "minPrice": 0,
    "maxPrice": 0,
    "starSitter": false,
    "fetchDetails": true,
    "fetchReviews": true,
    "maxReviewsPerSitter": 0,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "maxNotifyListings": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/rover-pet-care-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 = {
    "mode": "search",
    "locations": ["San Francisco, CA, USA"],
    "serviceType": "overnight-boarding",
    "petType": "dog",
    "urls": ["https://www.rover.com/san-francisco--ca--dog-boarding/"],
    "minRating": 0,
    "minPrice": 0,
    "maxPrice": 0,
    "starSitter": False,
    "fetchDetails": True,
    "fetchReviews": True,
    "maxReviewsPerSitter": 0,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "maxNotifyListings": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/rover-pet-care-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 '{
  "mode": "search",
  "locations": [
    "San Francisco, CA, USA"
  ],
  "serviceType": "overnight-boarding",
  "petType": "dog",
  "urls": [
    "https://www.rover.com/san-francisco--ca--dog-boarding/"
  ],
  "minRating": 0,
  "minPrice": 0,
  "maxPrice": 0,
  "starSitter": false,
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerSitter": 0,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/rover-pet-care-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/rover-pet-care-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/F9101QbZ9KoC5OsdP/builds/fI9LQQE0ZVmKvSl8y/openapi.json
