Turo Scraper - Vehicle Search, Trip Quotes and Hosts
Pricing
from $1.20 / 1,000 vehicle results
Turo Scraper - Vehicle Search, Trip Quotes and Hosts
Collect Turo vehicles by location and trip dates or listing URLs. Get make, model, year, ratings, photos, dated price estimates, vehicle details and public host profiles, with resume and recurring change detection.
Pricing
from $1.20 / 1,000 vehicle results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
8
Monthly active users
5 days ago
Last modified
Categories
Share
Turo Scraper: Vehicle Listings, Trip Quotes & Host Profiles
Turo Scraper turns Turo into structured vehicle data. Search by location and trip dates, or paste direct vehicle listing links, to collect make, model, year, rating, public location, photos and a dated price estimate for your exact trip. Turn on full details to add specifications, delivery options, owner information and the public host profile. Export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two ways in. Search by location, make and trip dates, or paste direct vehicle listing links when you already know which cars you want.
- Dated trip quotes. Each vehicle is joined to a Turo-estimated quote for your exact trip dates, not just the generic search-card daily average, so
tripTotalandquotedDailyPricereflect the dates you asked for. - Full details on demand. Switch on specifications, delivery options, owner information and the public host profile per run, and pay the detail surcharge only for records where a host profile was actually fetched.
- Multi-location coverage that shares fairly. Several locations in one run split the output budget round robin, so the first location can't consume the whole cap.
- Resume without repaying. Continue one interrupted run by its run ID and skip vehicles it already returned, instead of recollecting from scratch.
- Built for recurring monitoring. Incremental mode returns only new and updated vehicles on repeat runs against the same search (and, with Emit expired listings on, vehicles that disappear or return), so scheduled comparisons don't reprocess everything each time.
- Fails loudly when blocked. If a location search or a pasted listing link can't be read, the run stops with an error instead of quietly returning an empty dataset that looks like "no vehicles found."
Use Cases
- Car-sharing market research: compare vehicle types, ratings and pricing by city or make to benchmark host supply against your own fleet.
- Dynamic pricing analysis: pull dated quotes across many vehicles to build a competitor pricing baseline for a specific trip window.
- Fleet and demand monitoring: schedule Incremental mode runs to catch new listings, price changes, or vehicles that disappear from a market.
- Host outreach and lead lists: collect public host profiles and completed-trip counts to identify active hosts worth contacting.
- Travel and rental comparison tools: feed live vehicle availability and dated pricing into your own booking or comparison app.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | "101" |
url | Turo link to the vehicle listing |
title | "2020 Tesla Model 3" |
make / model | "Tesla" / "Model 3" |
year | 2020 |
vehicleType | "CAR" |
rating | 4.8 |
completedTrips | 126 |
hostId | 1101 |
city / state / country | "Los Angeles" / "CA" / "US" |
latitude / longitude | 34.0522 / -118.2437 |
averageDailyPrice | { "amount": 35, "currency": "USD" } (search-card estimate) |
tripTotal / currency | 117 / "USD" (dated quote for the requested trip) |
quotedDailyPrice | 39 (dated quote, before taxes and checkout add-ons) |
quoteStatus | "complete" or "unavailable" |
startDateTime / endDateTime | requested trip window used for the quote |
detailStatus / hostStatus | "complete", "not_requested", or "unavailable" |
images | array of photo URLs |
location | structured place object; precision noted when known |
scopeId / scrapedAt | baseline scope hash and collection timestamp |
With full details enabled (the default), each record also carries description (the host's listing text), owner (the public owner block), basicCarDetails (specifications such as seat count), host (the separate public host profile: bio and verification badges), quote (the full dated quote object, including nonIncludedLineItems and pricingDisplay), searchVehicle (the raw public search card) and detail (the raw public vehicle response), so nothing public is lost. Every row also carries a coverage object reporting how the search behind it went (returned count, source total, whether it was a complete scan). In Incremental mode, rows also carry changeType (NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED), changedFields, firstSeenAt and lastSeenAt.
How to Use
- Pick a mode:
search(locations and trip dates) orurl(paste direct vehicle listing links). - For search mode, set
locations, and optionallymakesto narrow the search itself, plusminYear,maxYearandminRatingto filter what comes back before the output limit. - Set trip dates with
startDateTimeandendDateTime, or leave both empty for the default three-day trip starting seven days out. TurnfetchDetailson or off and setmaxItems, then click Start. - Download the dataset as JSON, CSV or Excel, or read it through the API.
Search a city with defaults:
{"mode": "search","locations": ["Los Angeles, California"],"maxItems": 20,"fetchDetails": true}
Filtered search with a fixed trip window:
{"mode": "search","locations": ["Chicago, Illinois"],"makes": ["Tesla"],"minYear": 2020,"minRating": 4.5,"startDateTime": "2026-11-10T10:00:00","endDateTime": "2026-11-13T10:00:00","maxItems": 15}
Paste specific vehicle links:
{"mode": "url","urls": ["https://turo.com/us/en/car-rental/united-states/los-angeles-ca/tesla/model-3/101"],"fetchDetails": true}
Recurring monitoring of one market:
{"mode": "search","locations": ["Miami, Florida"],"startDateTime": "2026-11-10T10:00:00","endDateTime": "2026-11-13T10:00:00","maxItems": 0,"incrementalMode": true,"stateKey": "miami-monitor","emitExpired": true}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/turo-scraper").call(run_input={"mode": "search", "locations": ["Los Angeles, California"], "maxItems": 20})for vehicle in client.dataset(run["defaultDatasetId"]).iterate_items():print(vehicle["title"], vehicle["tripTotal"], vehicle["currency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/turo-scraper').call({ mode: 'search', locations: ['Los Angeles, California'], maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Turo's own limits and maxItems
Turo can cap a single location at around 200 vehicles, even when its reported total is larger, and this actor cannot page past that. makes narrows the search itself at the source; minYear, maxYear and minRating are applied locally to what Turo returned, before maxItems is enforced, so a narrow filter can return fewer records than maxItems while other matching vehicles remain outside what was fetched. Narrow your locations or add a make filter for more targeted coverage. maxItems: 0 removes this actor's own limit but does not make a run exhaustive.
Resume and Incremental mode
- Resume (
resumeFromRunId) continues one interrupted run with the same query, dates and detail settings: it skips vehicle IDs already returned there, so you don't pay twice. The trip dates are part of that scope, so a Resume withstartDateTime/endDateTimeleft empty (which roll forward to seven days out from whenever the run starts) can fail the scope check on a later day; set explicit dates for a Resume you expect to run more than once. - Incremental mode (
incrementalMode) is for recurring runs over the same scope (mode, locations or URLs, trip dates, filters andfetchDetails). Each vehicle is classifiedNEW,UPDATED(withchangedFields), orUNCHANGED(suppressed and not billed unlessemitUnchangedis on); withemitExpiredon and a clean complete scan, a vehicle can also classifyEXPIREDor, on a later such run,REAPPEARED. An existing baseline cannot be combined withresumeFromRunId. Trip dates are part of the scope too, so leavingstartDateTime/endDateTimeempty (they roll forward daily) starts a fresh baseline on every run and preventsEXPIRED/REAPPEAREDfrom ever firing; set explicit dates for recurring monitoring. EXPIREDrows, and theREAPPEAREDclassification that can follow them, only ever come from a run that scanned its whole scope without hittingmaxItems, without a resume, and without any quote, detail or host lookup failing along the way, and only whenemitExpiredwas turned on for that scan. A capped, resumed, partial or degraded run never marks anything expired, so one bad run can't wipe out your baseline; the next clean run re-evaluates those vehicles instead.- Baselines are always kept separate per search scope;
stateKeyonly gives a baseline a memorable name so you can track several searches independently. Avoid scheduling overlapping runs against the same key, since state is committed only after a run finishes normally.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each vehicle becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (locations and trip dates) or url (paste vehicle listing links). |
locations | array | no default (prefill: ["Los Angeles, California"]) | Search mode only. City, airport, or place names. |
makes | array | no default | Search mode only. Vehicle make names, such as Tesla. |
minYear | integer | no default | Search mode only. Applied to returned vehicles before the output limit. |
maxYear | integer | no default | Search mode only. Applied to returned vehicles before the output limit. |
minRating | number | no default | Search mode only. Excludes unrated vehicles; applied before the output limit. |
urls | array | no default (prefill: one sample vehicle URL) | URL mode only. Turo vehicle listing links ending in the numeric vehicle ID, not search or host profile links. |
startDateTime | string | no default | Local ISO trip start, both modes. Omit together with endDateTime for a three-day trip starting in seven days. |
endDateTime | string | no default | Local ISO trip end, after startDateTime. Must be supplied together with the start. |
fetchDetails | boolean | true | Return full specifications and the public host profile. Charges one detail-enrichment event per returned record with a successfully fetched host profile. |
maxItems | integer | 20 | Maximum returned records. 0 removes this actor's output limit; Turo's own per-location cap still applies. |
proxy | object | Residential (Apify Proxy) | Connection settings. Turo blocks datacenter IPs, so the default uses the Residential proxy group. |
resumeFromRunId | string | no default | Continue one interrupted run with the same query, dates and detail settings. |
incrementalMode | boolean | false | Remember a baseline and return only new and changed vehicles on repeat runs. |
stateKey | string | no default | Optional name for a baseline. Use different keys for different searches. |
emitUnchanged | boolean | false | Also return (and bill) unchanged vehicles in Incremental mode. |
emitExpired | boolean | false | Also return (and bill) vehicles no longer found, only after a complete scan in Incremental mode. |
mcpConnectors | array | no default | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | no default | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": "101","url": "https://turo.com/us/en/car-rental/united-states/los-angeles-ca/tesla/model-3/101","title": "2020 Tesla Model 3","make": "Tesla","model": "Model 3","year": 2020,"vehicleType": "CAR","rating": 4.8,"completedTrips": 126,"hostId": 1101,"city": "Los Angeles","state": "CA","country": "US","latitude": 34.0522,"longitude": -118.2437,"location": {"city": "Los Angeles","country": "US","latitude": 34.0522,"longitude": -118.2437,"precision": { "level": "APPROXIMATE" }},"images": ["https://images.turo.com/media/vehicle/images/sample1.jpg"],"averageDailyPrice": { "amount": 35, "currency": "USD" },"tripTotal": 117,"currency": "USD","quotedDailyPrice": 39,"quote": {"totalTripPrice": { "amount": 117, "currencyCode": "USD" },"vehicleDailyPriceAfterDiscount": { "amount": 39, "currencyCode": "USD" },"nonIncludedLineItems": [{ "type": "PROTECTION" }]},"quoteStatus": "complete","startDateTime": "2026-11-10T10:00:00","endDateTime": "2026-11-13T10:00:00","detailStatus": "complete","hostStatus": "complete","basicCarDetails": { "numberOfSeats": 5 },"owner": { "id": 1101, "name": "Public Host" },"host": { "driver": { "id": 1101 }, "bio": "Public biography", "verifications": { "emailVerified": true } },"coverage": { "query": "Los Angeles, California", "returned": 18, "totalHits": 18, "complete": true, "reason": "source_end" },"scopeId": "8f2a1c4d9b3e7f60a1c2d3e4","scrapedAt": "2026-11-05T02:00:00+00:00"}
Plan Requirement
The default Connection setting uses Apify's Residential proxy group, which this actor needs to reach Turo reliably, so no manual proxy setup is required to get started. Vehicle results and optional detail enrichment are billed as pay-per-event usage; see the actor's Pricing tab for current rates before running at scale.
FAQ
How much does it cost?
You pay per vehicle record returned, plus one optional detail-enrichment event for each record where full details were requested and a public host profile was actually fetched. Suppressed unchanged rows in Incremental mode and failed enrichment attempts are not billed. The Pricing tab shows current rates; use Maximum vehicles (maxItems) to cap the cost of any run.
Is it legal to scrape Turo?
This actor collects only publicly available vehicle listing data. You are responsible for how you use it: follow Turo's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts such as make, model and year are generally not protected, but photos and host-written text may carry separate rights.
Can I track new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated vehicles for the same search scope, and unchanged vehicles are not billed unless you opt in; with Emit expired listings also on and a clean complete scan, expired and reappeared vehicles are included too. Keep the trip dates fixed (don't leave them empty) so the scope stays the same run to run.
Why did my run return fewer vehicles than maxItems?
Turo can cap each location around 200 vehicles regardless of how many it reports in total. makes narrows the search at the source; minYear, maxYear and minRating are applied locally before maxItems, so a narrow filter can leave matching vehicles outside what was returned. Widen the filters or add more locations for broader coverage.
Why did my run fail instead of returning an empty dataset?
A run fails when any location search or pasted listing link can't be read, such as a removed vehicle link, or when the input itself is invalid (for example an unreadable Resume ID, or Resume combined with an existing Incremental baseline). A location with no matching address returns zero vehicles for that location normally, without failing the run. If only some per-vehicle detail or quote lookups fail partway through, you still get the base records that were found, with their status fields marked accordingly.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 Want more car data?
Pair this actor with these related scrapers from the same team:
| 🚗 Cars.com Scraper Scrape cars.com listings by make, ZIP and radius. 90+ fields per car: price, MSRP... | 🚗 EasyAuto123 Scraper Scrape EasyAuto123 vehicle listings into clean structured data. Extract prices, VINs... |
| 🚗 mobile.de From $0.8/1K. Scrape mobile.de vehicle listings with 30+ structured fields including... | 🚗 Autotrader US Scrape US car listings from Autotrader by make, model, ZIP, price, year, body style... |
| 🚗 Carsales.com.au Scraper Scrape structured vehicle listings from Carsales.com.au from $1 per 1K results. Built to... | 🚗 SpaceX Launches Pull the full SpaceX launch catalog from spacex.com in clean JSON. Filter by vehicle... |
💬 Support & custom scrapers
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.