# Bring a Trailer Scraper (`tortuga/bringatrailer-scraper`) Actor

Scrape Bring a Trailer live auctions and sold results by make, model or search: sold price or high bid, end date, year, mileage, VIN, bids and comments. Built for collector car valuations.

- **URL**: https://apify.com/tortuga/bringatrailer-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 auction scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bring a Trailer Scraper

Scrape Bring a Trailer (BaT) auction results and live auctions: sold prices, high bids, end dates, year, make, model, mileage, VIN, bid history and photos. Works with any make, model, category or results URL, or a plain search query.

Bring a Trailer has the most-watched sold-price history for collector and enthusiast cars, but no export. Paste a model page like `https://bringatrailer.com/porsche/911/` or type "BMW E30 M3" and get every completed auction as clean JSON, CSV or Excel, or straight into your app through the API. The actor reads the structured data BaT itself uses to render its results (including the same filter endpoint as the "Results" page), so prices and dates are exact numbers instead of scraped text. It throttles itself, retries on a fresh proxy session and never logs in. You pay only for the auctions you get.

### What data does Bring a Trailer Scraper extract?

Every auction from a results or live list gives you:

| Field | Description |
|---|---|
| `id`, `url` | BaT listing id and listing URL |
| `title` | Listing title, e.g. "RoW 1980 Porsche 911SC Coupe" (the "No Reserve:" prefix is moved to `isNoReserve`) |
| `year`, `make`, `model` | Model year (number), make, and the model of the page you scraped (e.g. `911` for /porsche/911/) |
| `status` | `sold`, `reserve not met`, `withdrawn`, `live`, or `ended` (closed without a result) |
| `soldPrice` | Hammer price as a number, when sold |
| `highBid` | Highest bid as a number for reserve-not-met, withdrawn and live auctions |
| `currency`, `priceText` | `USD`, `EUR`, `GBP`, ... and BaT's own text ("Sold for USD $82,000 on 9/14/2026") |
| `endedAt` / `endsAt` | Auction end time (ISO 8601, UTC) for completed / live auctions |
| `isNoReserve`, `isPremium`, `isRepeatListing` | No Reserve, Premium and "BaT Alumni" (car sold on BaT before) flags |
| `country`, `countryCode`, `latitude`, `longitude` | Where the vehicle is located (coordinates for live auctions) |
| `thumbnailUrl`, `imageUrl`, `excerpt` | Card photo (thumbnail and full size) and the listing summary |
| `sourceUrl`, `scrapedAt` | The URL or search the auction came from, and when it was scraped |

Turn on **Include listing details** to also open each listing page and add:

| Field | Description |
|---|---|
| `vin` | VIN or chassis number as listed |
| `mileage`, `mileageUnit`, `mileageText` | Odometer as a number (`miles` or `km`) plus BaT's wording ("54k Miles Shown on Replacement Speedometer", "TMU") |
| `engine`, `transmission` | e.g. "3.0-Liter Flat-Six", "Five-Speed Manual Transaxle" |
| `exteriorColor`, `interiorColor` | e.g. "Minerva Blue Metallic", "Tan Upholstery w/Plaid Cloth Inserts" |
| `essentials` | The full "Listing Details" bullet list |
| `location` | City, state and postal code of the vehicle |
| `sellerUsername`, `sellerType` | Seller's public BaT handle and `private` or `dealer` |
| `lotNumber` | BaT lot number |
| `bidCount`, `openingBid`, `firstBidAt`, `lastBidAt`, `bidHistory` | Number of bids and every bid as `{amount, at}` (bidder names are not collected) |
| `commentCount`, `views`, `watchers` | Engagement counters |
| `model`, `modelFull`, `era`, `origin` | BaT's precise model tag (e.g. `911SC`), decade and origin |
| `images`, `imageCount` | All gallery photo URLs in full resolution |
| `description` | Full listing description as plain text |

### How to scrape Bring a Trailer sold prices

1. Open bringatrailer.com and go to a make or model page (for example Porsche -> 911), or to **Auctions -> Results** and set filters (search words, sold only, year range). Copy the URL into **Start URLs**. Or just type a **Search query** such as "Ferrari 308".
2. Choose **Auctions**: completed results (default), live auctions, or both.
3. Set **Max items** (your cost cap) and optionally turn on **Include listing details**.
4. Click **Start** and export the dataset as JSON, CSV or Excel, or read it through the API.

### Input example

```json
{
  "startUrls": [
    { "url": "https://bringatrailer.com/porsche/911/" },
    { "url": "https://bringatrailer.com/auctions/results/?search=e30+m3&result=sold&yearFrom=1988&yearTo=1991" }
  ],
  "mode": "completed",
  "maxItems": 500,
  "includeDetails": true
}
```

or by keywords, live and completed:

```json
{
  "searchQuery": "Land Cruiser FJ40",
  "mode": "both",
  "maxItems": 200
}
```

### Output example

```json
{
  "id": 114307212,
  "url": "https://bringatrailer.com/listing/1980-porsche-911sc-139/",
  "title": "RoW 1980 Porsche 911SC Coupe",
  "year": 1980,
  "make": "Porsche",
  "model": "911SC",
  "status": "sold",
  "soldPrice": 82000,
  "highBid": null,
  "currency": "USD",
  "priceText": "Sold for USD $82,000 on 9/14/2026",
  "endedAt": "2026-09-14T18:08:17Z",
  "isNoReserve": false,
  "country": "United States",
  "thumbnailUrl": "https://bringatrailer.com/wp-content/uploads/2026/05/1980_porsche_911sc_...-scaled.jpg?w=470&h=318&crop=1",
  "excerpt": "This 1980 Porsche 911SC is a rest-of-world coupe that has been imported from Germany to the US...",
  "vin": "91A0131527",
  "mileage": 54000,
  "mileageUnit": "miles",
  "mileageText": "54k Miles Shown on Replacement Speedometer",
  "engine": "3.0-Liter Flat-Six",
  "transmission": "Five-Speed Manual Transaxle",
  "exteriorColor": "Minerva Blue Metallic",
  "interiorColor": "Tan Upholstery w/Plaid Cloth Inserts",
  "location": "Seattle, Washington 98112",
  "sellerUsername": "Porscheplatz1",
  "sellerType": "private",
  "lotNumber": "263041",
  "bidCount": 48,
  "commentCount": 160,
  "views": 19337,
  "watchers": 2463,
  "openingBid": 1,
  "bidHistory": [{ "amount": 1, "at": "2026-09-07T18:38:31Z" }, { "amount": 82000, "at": "2026-09-14T18:06:17Z" }],
  "essentials": ["Chassis: 91A0131527", "54k Miles Shown on Replacement Speedometer", "3.0-Liter Flat-Six", "..."],
  "images": ["https://bringatrailer.com/wp-content/uploads/2026/05/1980_porsche_911sc_...-scaled.jpg", "..."],
  "description": "This 1980 Porsche 911SC is a rest-of-world coupe...",
  "sourceUrl": "https://bringatrailer.com/porsche/911/",
  "scrapedAt": "2026-09-14T20:17:53Z"
}
```

### How many results can I get from one model or search?

All of them up to 10,000 per start URL. Bring a Trailer serves completed results 60 at a time and stops at the 10,000th result of any single query, which only matters for the very biggest makes (Porsche has 33,000+ results, the 911 alone about 20,000). For those, add several URLs split by year range, e.g. `https://bringatrailer.com/auctions/results/?search=porsche+911&yearFrom=1965&yearTo=1989` and `...&yearFrom=1990&yearTo=2004`. Duplicates across URLs are removed automatically. Live auctions are always returned in full.

### Can I scrape live Bring a Trailer auctions?

Yes. Set **Auctions** to "Live auctions" (or "Both"). A model page returns that model's live auctions; `https://bringatrailer.com/auctions/` returns every live auction on the site (usually 1,000+), and a search query filters them. Live items have `status: "live"`, the current `highBid` and `endsAt`. With details on you also get the bid history so far.

### Which URLs does it accept?

Make pages (`/porsche/`), model pages (`/porsche/911/`, `/bmw/e30-m3/`), category and origin pages (`/german/`), the results page with any filters from the browser (`/auctions/results/?search=...&result=sold&yearFrom=...&timeFrame=1Y`), BaT's search URLs (`/search/?s=...`, followed to the matching model page), the live auctions page, and single listing URLs (`/listing/...`), which always return a fully detailed item.

### Does it work without a Bring a Trailer account?

Yes. Everything comes from public pages that anyone can open without logging in. No account, cookies or API key are needed, and bidder names are never collected. The seller's public BaT handle is included because it is shown on the listing.

### Pricing

Pay per result: $0.003 per auction saved, plus $0.004 per listing page opened when **Include listing details** is on (and for single listing URLs). 1,000 results (price, status, end date, year, make, model) cost $3; with full vehicle details (VIN, mileage, specs, bids, photos) $7. No start fee, no subscription.

### Integrations and API

Run it from Python or Node with the Apify client, schedule it weekly to track a model's prices, or connect the dataset to Google Sheets, Zapier, Make or n8n. See the **API** tab for ready-made snippets.

### Is it legal to scrape Bring a Trailer?

This Actor collects only publicly visible auction data: vehicle details, prices, dates and the listing's public seller handle. It does not log in, does not collect bidder or commenter identities, and does not collect contact details. You are responsible for how you use the data and for complying with Bring a Trailer's terms and applicable law.

### Support

Missing a field or found a URL that does not work? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

## `startUrls` (type: `array`):

Bring a Trailer pages to scrape: make or model pages (https://bringatrailer.com/porsche/911/, https://bringatrailer.com/porsche/), category pages (https://bringatrailer.com/german/), the results page with filters applied in the browser (https://bringatrailer.com/auctions/results/?search=e30+m3\&result=sold\&yearFrom=1988), the live auctions page (https://bringatrailer.com/auctions/), or single listing URLs (https://bringatrailer.com/listing/...), which always return full details. Leave empty if you use Search query.

## `searchQuery` (type: `string`):

Alternative to Start URLs: keywords searched across all Bring a Trailer auctions, e.g. "Porsche 911 GT3", "BMW E30 M3", "1967 Mustang". Same matching as the search box on the results page.

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

Which auctions to return: completed results (sold, reserve not met, withdrawn), live auctions currently taking bids, or both (live first).

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

Stop after this many auctions in total (across all start URLs). Keeps cost predictable. Bring a Trailer serves at most 10,000 completed results per search, so split very large makes by model or year range (yearFrom/yearTo in the results URL).

## `includeDetails` (type: `boolean`):

Also open every listing page to add VIN/chassis, mileage, engine, transmission, exterior and interior color, the full BaT Essentials list, location, seller handle and dealer/private type, lot number, bid count and bid history (amounts and times), comment/view/watcher counts, all gallery photo URLs and the full description. One extra request per auction; charged extra per listing (see pricing).

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

Apify Proxy settings. Datacenter proxy (the default) works for Bring a Trailer; switch to residential only if runs show 403 errors.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://bringatrailer.com/porsche/911/"
    }
  ],
  "mode": "completed",
  "maxItems": 100,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        {
            "url": "https://bringatrailer.com/porsche/911/"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/bringatrailer-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 = {
    "startUrls": [{ "url": "https://bringatrailer.com/porsche/911/" }],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/bringatrailer-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 '{
  "startUrls": [
    {
      "url": "https://bringatrailer.com/porsche/911/"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/bringatrailer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tortuga/bringatrailer-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/2ZJqrh5cyXdS88a3W/builds/jQvIgnVJABQ0XAhPP/openapi.json
