# Back Market Scraper (`datascrapers/backmarket-scraper`) Actor

Scrape Back Market product listings from search queries or start URLs across 17 countries, with optional product details and customer reviews.

- **URL**: https://apify.com/datascrapers/backmarket-scraper.md
- **Developed by:** [Data Scrapers](https://apify.com/datascrapers) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 product scrapeds

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?

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

**Back Market Scraper** creates a structured dataset of refurbished product offers collected from Back Market. Each dataset item is one product offer and can include the product and listing ids, name, brand, grade, price, currency, rating, review count, stock, and product URL. Query the source with search terms or Back Market URLs, choose one of 17 country sites, optionally add product details and reviews, limit results with `maxItems`, and retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, XML, or another supported format.

[![Back Market Scraper — input to structured data](https://raw.githubusercontent.com/faizanalii/apify-actor-assets/main/backmarket-scraper/backmarket-scraper-value-demo.gif)](https://apify.com/datascrapers/backmarket-scraper)

### Dataset at a glance

| Property | Value |
|---|---|
| Source | Back Market country sites |
| Record unit | One product offer |
| Input methods | `searchQueries` or `startUrls`, plus `country` |
| Main identifiers | `listingId` for the offer, `productId` for the product |
| Delivery | Apify Dataset and API |
| Export formats | JSON, CSV, Excel, XML, and other Apify dataset exports |
| Update model | Fresh records per Actor run |
| Pricing | $1.50 per 1,000 `product`, `product-details`, and `product-reviews` events on the free plan |

### Coverage and available records

Search queries use the selected `country` site. Start URLs can be a search page, a category page, or a product page, and they keep the country in the URL. The saved run searched `iphone` on the Germany site.

Supported countries: Germany, Austria, Australia, Belgium, Spain, Finland, France, United Kingdom, Greece, Ireland, Italy, Japan, Netherlands, Portugal, Sweden, Slovakia, and the United States.

A search card includes name, model, brand, color, subtitle, URL, image, current and original price, currency, grade, category, rating, review count, warranty months, stock, country, locale, and the query that produced it.

`includeProductDetails` adds description, HTML description, what the offer comes with, score chips, units sold, specifications, variants, and stock flags. `includeReviews` adds a `reviews` array, capped by `maxReviews` (default 10). Those two options are off by default. The saved sample had both on, with three reviews.

`maxItems` defaults to 0, which means no product cap. The input prefill is 10.

Not currently collected: a historical price series, or reviews beyond `maxReviews`.

### Data dictionary

Types below match a saved Germany search offer for an iPhone 16 Pro, with details and reviews enabled. `description` and `descriptionHtml` in that file are long. The example later keeps a short prefix of `description` and omits the HTML.

| Field | Type | Nullable | Description | Example |
|---|---|---:|---|---|
| `productId` | string | No | Back Market product id. | `12d2e039-0c01-4db9-ba49-69ab1a0eb4e8` |
| `listingId` | string | No | Offer id. Best field for deduplicating a specific offer. | `be8a0fd7-1370-4b13-9b81-4a4abc4d9d2f` |
| `legacyId` | integer | Yes | Numeric legacy id when present. | `5119359` |
| `name` | string | Yes | Offer title. | `iPhone 16 Pro 128GB - Titan Schwarz - Ohne Vertrag` |
| `model` | string | Yes | Model name. | `iPhone 16 Pro` |
| `brand` | string | Yes | Brand slug. | `apple` |
| `color` | string | Yes | Color label. | `Titan Schwarz` |
| `subtitle` | string | Yes | Short variant line. | `Titan Schwarz • 128 GB • eSim` |
| `url` | string | No | Product page URL. | `https://www.backmarket.de/de-de/p/iphone-16-pro` |
| `imageUrl` | string | Yes | Primary image URL. | CloudFront image URL |
| `price` | number | Yes | Current price in `currency`. | `630.0` |
| `formattedPrice` | string | Yes | Display price. | `630,00 €` |
| `originalPrice` | number | Yes | Compared-at price. | `1199.0` |
| `formattedOriginalPrice` | string | Yes | Display compared-at price. | `1.199,00 €` |
| `currency` | string | Yes | ISO currency. | `EUR` |
| `grade` | string | Yes | Condition label in the site language. | `Gut` |
| `gradeValue` | integer | Yes | Numeric grade. | `12` |
| `productType` | string | Yes | Offer type. | `Refurbished` |
| `category` | string | Yes | Category label. | `Smartphone` |
| `categoryId` | integer | Yes | Category id. | `2` |
| `rating` | number | Yes | Average rating. | `4.51` |
| `reviewCount` | integer | Yes | Review count on the card. | `15817` |
| `warranty` | integer | Yes | Warranty length in months. | `12` |
| `stock` | integer | Yes | Units available on the offer. | `19` |
| `countryCode` | string | No | Site country. | `DE` |
| `locale` | string | Yes | Site locale. | `de-de` |
| `sourceType` | string | No | `search` or the URL type that produced the row. | `search` |
| `sourceQuery` | string | Yes | Search term. Empty when the row came only from a URL. | `iphone` |
| `sourceUrl` | string | Yes | Search or page URL. | `https://www.backmarket.de/de-de/search?q=iphone` |
| `imageUrls` | array of strings | No | Image URLs. Present when details are included. | See stored record |

Detail-only fields, present when `includeProductDetails` is true: `description`, `descriptionHtml`, `comesWith` (`type`, `text`), `scores` (`id`, `label`, `value`), `unitsSold`, `dualSim`, `isTradeInEligible`, `parentProductSlug`, `supportsAppleIntelligence`, `specifications` (`label`, `value`, `field`), `isOutOfStock`, and `variants`.

`reviews` is present when `includeReviews` is true. Each review has `id`, `rating`, `comment`, `createdAt`, `languageCode`, `countryCode`, `relevance`, `details`, and `attachments`. One review charges one `product-reviews` event.

### Example dataset record

This offer came from `searchQueries: ["iphone"]` on country `DE`, with details and reviews enabled. The stored description and image list are longer. Review comments are omitted here. `imageUrls` keeps the first URL only.

```json
{
  "productId": "12d2e039-0c01-4db9-ba49-69ab1a0eb4e8",
  "listingId": "be8a0fd7-1370-4b13-9b81-4a4abc4d9d2f",
  "legacyId": 5119359,
  "name": "iPhone 16 Pro 128GB - Titan Schwarz - Ohne Vertrag",
  "model": "iPhone 16 Pro",
  "brand": "apple",
  "color": "Titan Schwarz",
  "subtitle": "Titan Schwarz • 128 GB • eSim",
  "url": "https://www.backmarket.de/de-de/p/iphone-16-pro",
  "price": 630.0,
  "formattedPrice": "630,00 €",
  "originalPrice": 1199.0,
  "currency": "EUR",
  "grade": "Gut",
  "gradeValue": 12,
  "productType": "Refurbished",
  "category": "Smartphone",
  "rating": 4.51,
  "reviewCount": 15817,
  "warranty": 12,
  "stock": 19,
  "countryCode": "DE",
  "locale": "de-de",
  "sourceType": "search",
  "sourceQuery": "iphone",
  "sourceUrl": "https://www.backmarket.de/de-de/search?q=iphone"
}
```

### Query and input reference

| Input | Type | Required | Default | Accepted values | Description |
|---|---|---:|---|---|---|
| `searchQueries` | string array | No | None | Search text | Prefill: `iphone`. Uses `country`. |
| `startUrls` | URL array | No | None | Search, category, or product URLs | Country is taken from the URL. |
| `country` | string | No | `DE` | `DE`, `AT`, `AU`, `BE`, `ES`, `FI`, `FR`, `GB`, `GR`, `IE`, `IT`, `JP`, `NL`, `PT`, `SE`, `SK`, `US` | Site for search queries. |
| `maxItems` | integer | No | `0` | `0` or a positive integer | Product cap. `0` means no cap. Prefill `10`. |
| `includeProductDetails` | boolean | No | `false` | `true` or `false` | Fetch the product page and charge `product-details`. |
| `includeReviews` | boolean | No | `false` | `true` or `false` | Fetch reviews and charge `product-reviews` per review. |
| `maxReviews` | integer | No | `10` | Positive integer | Review cap per product. |
| `detailConcurrency` | integer | No | `5` | Integer | Parallel detail and review requests. |
| `proxyConfiguration` | object | No | Apify residential proxy | Apify proxy editor | Proxy for Back Market requests. |

Provide `searchQueries` or `startUrls`.

Minimal request:

```json
{
  "searchQueries": ["iphone"],
  "country": "DE",
  "maxItems": 10
}
```

Details and reviews:

```json
{
  "searchQueries": ["iphone"],
  "country": "DE",
  "maxItems": 3,
  "includeProductDetails": true,
  "includeReviews": true,
  "maxReviews": 3
}
```

### Retrieve the data through the API

1. Start `datascrapers/backmarket-scraper` with the JSON input.
2. Wait until the run finishes, or call the synchronous dataset endpoint.
3. Read items from the run's default dataset.
4. Paginate with dataset `offset` and `limit`, or export from the Apify console.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("datascrapers/backmarket-scraper").call(
    run_input={
        "searchQueries": ["iphone"],
        "country": "DE",
        "maxItems": 10,
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["listingId"], item["name"], item["price"])
```

Other languages are listed on the Actor's API tab. This is the Apify Actor API, not a Back Market API.

### Data quality and record handling

- One pushed record is one offer. The `product` event is charged when that record is pushed.
- Deduplicate offers on `listingId`. Use `productId` when you want one row per product across grades and colors.
- The same product can appear as several offers. Do not collapse them on `name`.
- Price is a number in `currency`. `formattedPrice` keeps the site's grouping and symbol.
- Grade labels follow the country locale. `Gut` is the German label on the saved card.
- Detail and review fields are absent when those options are off. A failed detail request does not invent them.
- Each successfully collected review adds one `product-reviews` charge. A product-page enrichment adds one `product-details` charge.
- `reviewCount` is the count shown on the card. It can be larger than the `reviews` array, which stops at `maxReviews`.

### Pricing and cost examples

The price file in the Actor folder prices every event at **$1.50 per 1,000** on the free plan. The same file lowers that rate on paid plans. Prices are per event, not per 1,000 as a single invoice line. One `product` charge is one pushed offer. One `product-details` charge is one enriched product. One `product-reviews` charge is one review.

| Plan | Price per 1,000 events |
|---|---:|
| Free | $1.50 |
| Bronze | $1.40 |
| Silver | $1.30 |
| Gold | $1.20 |
| Platinum and Diamond | $1.20 |

Platinum and Diamond are not listed in the file. They use the Gold rate. The file also sets platform usage as not charged to the user.

| Offers | Cards only | Cards, details, and 3 reviews each |
|---:|---:|---:|
| 1,000 | $1.50 | $7.50 |
| 10,000 | $15.00 | $75.00 |

The second column is the free-plan rate: one product, one detail, and three reviews per offer. It is lower on Bronze, Silver, and Gold.

### Limitations and responsible data use

- Coverage is the search or URL you send, on the country site you select.
- Start URLs ignore `country` and use the country in the URL.
- Prices, stock, and grades change on Back Market. This dataset is not a price history.
- Review text is written by customers and can include personal details.
- You are responsible for complying with Back Market's terms and applicable law.

### Dataset questions

#### What does one dataset item represent?

One Back Market product offer. With details and reviews enabled, that same record also contains the product page and the reviews that were collected.

#### Which field should I use as a unique identifier?

Use `listingId` for the offer. Use `productId` for the product across grades and storage options.

#### Are fields nullable or conditional?

Yes. Description, specifications, variants, and `reviews` appear only when the matching option is enabled and the page returns them.

#### Can I retrieve the records as CSV or JSON?

Yes. Export the default dataset as JSON, CSV, Excel, XML, or another Apify format.

#### How do I paginate large datasets?

Set `maxItems` on the run. `0` removes the cap. Read items with dataset `limit` and `offset`.

#### Does the Actor return historical data?

No. Each run returns the offers available at request time.

#### What counts as a billable result?

Each pushed offer charges `product`. Each enriched product charges `product-details`. Each collected review charges `product-reviews`. The free-plan price is $0.0015 per event.

### Related datasets from Data Scrapers

- [Amazon Scraper](https://apify.com/datascrapers/amazon-scraper) collects marketplace product records you can compare on price and rating.
- [Best Buy Scraper](https://apify.com/datascrapers/best-buy-scraper) collects electronics offers alongside refurbished phone and laptop rows.
- [AliExpress Scraper](https://apify.com/datascrapers/aliexpress-scraper) collects product listings with price and review fields.
- [Alibaba Scraper](https://apify.com/datascrapers/alibaba-scraper) collects wholesale product records for the same catalog research.
- [Adidas Scraper](https://apify.com/datascrapers/adidas-scraper) collects brand product records with price and availability.

### Data Scrapers support

Need an additional field, record type, or export workflow? Contact Data Scrapers at stardustspotlight@gmail.com. Include a sample source URL, required fields, expected record volume, and preferred delivery format.

# Actor input Schema

## `searchQueries` (type: `array`):

Product search terms to look up on Back Market (e.g. "iphone 16", "macbook air"). Uses the selected country. Combined with Start URLs when both are set.

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

Back Market search, category, or product page URLs, e.g. https://www.backmarket.de/de-de/search?q=iphone, https://www.backmarket.at/de-at/l/smartphones/6c290010-c0c2-47a4-b68a-ac2ec2b64dca, or https://www.backmarket.de/de-de/p/iphone-16-pro. The country is taken from the URL host.

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

Back Market country used for search queries. Ignored for start URLs, which use the country from the hostname. Default is Germany.

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

Maximum number of products to scrape across all queries and URLs (0 = unlimited).

## `includeProductDetails` (type: `boolean`):

When enabled, fetch full product details for each item (description, specifications, images, variants). Charged as the product-details event in addition to each product.

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

When enabled, fetch customer reviews for each product. Charged as the product-reviews event once per review, in addition to each product.

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

Maximum number of reviews to collect per product when Include Product Reviews is enabled (0 = all available reviews).

## `detailConcurrency` (type: `integer`):

How many products to enrich in parallel when product details or reviews are enabled. Each worker uses a rotated residential proxy.

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

Proxy settings. Apify Residential proxies are recommended for reliable Back Market access.

## Actor input object example

```json
{
  "searchQueries": [
    "iphone"
  ],
  "startUrls": [
    {
      "url": "https://www.backmarket.de/de-de/search?q=iphone"
    }
  ],
  "country": "DE",
  "maxItems": 10,
  "includeProductDetails": false,
  "includeReviews": false,
  "maxReviews": 10,
  "detailConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Dataset containing scraped Back Market products

## `runStats` (type: `string`):

Aggregate scrape statistics for this run

# 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 = {
    "searchQueries": [
        "iphone"
    ],
    "startUrls": [
        {
            "url": "https://www.backmarket.de/de-de/search?q=iphone"
        }
    ],
    "maxItems": 10,
    "maxReviews": 10,
    "detailConcurrency": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascrapers/backmarket-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 = {
    "searchQueries": ["iphone"],
    "startUrls": [{ "url": "https://www.backmarket.de/de-de/search?q=iphone" }],
    "maxItems": 10,
    "maxReviews": 10,
    "detailConcurrency": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("datascrapers/backmarket-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 '{
  "searchQueries": [
    "iphone"
  ],
  "startUrls": [
    {
      "url": "https://www.backmarket.de/de-de/search?q=iphone"
    }
  ],
  "maxItems": 10,
  "maxReviews": 10,
  "detailConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call datascrapers/backmarket-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascrapers/backmarket-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/vNe6SFayuypRyCfQ7/builds/YMbnLrhno2Ui3T1BX/openapi.json
