# dm Germany Products, Ingredients & Store Availability Scraper (`dromb/dm-de-product-scraper`) Actor

Search dm Germany products, extract ingredients and warnings, find stores, and compare online or pickup availability.

- **URL**: https://apify.com/dromb/dm-de-product-scraper.md
- **Developed by:** [Dmitriy Gyrbu](https://apify.com/dromb) (community)
- **Categories:** Automation, Developer tools, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 results

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/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

## dm Germany Products, Ingredients & Store Availability Scraper

Search dm Germany products, extract rich product details such as ingredients and warnings, find real stores, and check online or pickup availability. Use it for catalog enrichment, assortment research, price monitoring, local availability checks, and beauty or pharmacy product research.

This is an unofficial scraper and is not affiliated with or endorsed by dm-drogerie markt.

### Supported operations

- **search** — keyword search with pagination, sorting, ratings, prices, images, and optional rich-detail enrichment.
- **category** — category products using a dm category ID.
- **product** — exact rich product details by DAN or dm.de product URL.
- **stores** — nearby stores by coordinates or exact store details by real internal store IDs.
- **availability** — online availability and store-specific pickup status by DAN.

The default input is intentionally small and returns non-empty shampoo results:

```json
{
  "operation": "search",
  "query": "shampoo",
  "maxItems": 20,
  "includeDetails": false,
  "proxyMode": "auto"
}
```

#### Rich product details

```json
{
  "operation": "product",
  "dans": ["3058454", "3043247"],
  "proxyMode": "auto"
}
```

Product records use stable retail fields such as id, barcode, name, brand, price, currency, breadcrumbs, source\_url, image, and images. Exact detail responses can also include description, ingredients, usage\_instructions, warnings, hazard\_information, benefits, and product attributes. Empty fields are omitted.

#### Category products

```json
{
  "operation": "category",
  "categoryId": "060502",
  "maxItems": 25,
  "sort": "editorial_relevance"
}
```

Category IDs are dm's internal public identifiers. A category URL alone is not accepted unless it contains an allCategories.id query parameter.

#### Nearby stores

```json
{
  "operation": "stores",
  "latitude": 52.52,
  "longitude": 13.405,
  "maxStores": 10
}
```

Store rows contain the internal store\_id, customer-facing store\_number, structured address, coordinates, opening hours, services, and express-pickup support. Preserve store\_id for availability requests.

#### Store pickup availability

```json
{
  "operation": "availability",
  "dans": ["3043247"],
  "storeIds": ["D20D"],
  "availabilityMode": "both"
}
```

Online, pickup, and both modes are supported. Pickup results are source-reported status labels for the selected store; they do not represent a guaranteed shelf quantity. Global product prices are never presented as store-specific prices.

### Filters and enrichment

Search and category stay lightweight by default. Use includeDetails only when ingredients, warnings, or other product-detail sections are required, because it performs one additional request per returned product.

Listing filters include exact brands, minimum or maximum price, minimum rating, and optional pharmacy exclusion. Sorting supports relevance, editorial relevance, ascending or descending price, newest, and rating.

### Proxy modes and failures

Auto tries direct access first and rotates through supplied custom proxies on retryable blocks. Direct, custom, and German Apify proxy modes are also available. Requests retry HTTP 403, 429, and transient server failures, reject non-JSON responses, and verify product/store identity before publishing.

Invalid input or exhausted request retries fail the Actor run after writing a structured OUTPUT summary. A source failure is not reported as a successful empty scrape.

Respect dm.de's terms, robots policy, and applicable law. Keep result limits proportionate and avoid unnecessary detail enrichment.

# Actor input Schema

## `operation` (type: `string`):

Search products, browse a category, extract rich product details, find stores, or check availability.

## `query` (type: `string`):

Required for search.

## `categoryId` (type: `string`):

Required for category, for example 060502 for fabric softener.

## `dans` (type: `array`):

Required for product or availability. Supply up to 50 dm article numbers.

## `productUrls` (type: `array`):

Product or availability input; DAN identifiers are extracted from dm.de product URLs.

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

Maximum unique products returned by search or category.

## `pageSize` (type: `integer`):

Number of products requested from dm per search or category page.

## `startPage` (type: `integer`):

One-based first page for search or category.

## `sort` (type: `string`):

Source-supported ordering for search or category products.

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

Fetch one rich product-detail record per listing result. This increases request count.

## `brands` (type: `array`):

Optional exact brand filter applied to listing results.

## `minPrice` (type: `number`):

Keep listing products at or above this price in EUR.

## `maxPrice` (type: `number`):

Keep listing products at or below this price in EUR.

## `minimumRating` (type: `number`):

Keep listing products with at least this source rating.

## `includePharmacy` (type: `boolean`):

Keep dm pharmacy products in search and category results.

## `latitude` (type: `number`):

Required with longitude for nearby stores.

## `longitude` (type: `number`):

Required with latitude for nearby stores.

## `maxStores` (type: `integer`):

Maximum number of nearby stores returned.

## `storeIds` (type: `array`):

Real internal dm store IDs returned by the stores operation.

## `availabilityMode` (type: `string`):

Pickup requires at least one store ID.

## `includeRaw` (type: `boolean`):

Add the exact source object to each row for advanced debugging.

## `proxyMode` (type: `string`):

Auto tries direct access first and uses supplied custom proxies as fallbacks.

## `customProxyUrls` (type: `array`):

Used in rotation by auto or custom proxy mode.

## Actor input object example

```json
{
  "operation": "search",
  "query": "shampoo",
  "maxItems": 20,
  "pageSize": 50,
  "startPage": 1,
  "sort": "relevance",
  "includeDetails": false,
  "includePharmacy": true,
  "maxStores": 10,
  "availabilityMode": "both",
  "includeRaw": false,
  "proxyMode": "auto"
}
```

# Actor output Schema

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

Normalized dm Germany product rows.

## `summary` (type: `string`):

Counts, missing DAN identifiers, proxy mode, and errors.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("dromb/dm-de-product-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("dromb/dm-de-product-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call dromb/dm-de-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dromb/dm-de-product-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/mKKqTtWIKnW3TqpLw/builds/My8VFiSXpam5nhI0t/openapi.json
