# German Trademark Register Scraper (`nowologix/german-trademark-register-scraper`) Actor

Search the German trademark register (DPMA). Export names, filing & registration dates, applicants, Nice classes (Nizza Klassen), goods & services, legal status and the real figurative mark images.

- **URL**: https://apify.com/nowologix/german-trademark-register-scraper.md
- **Developed by:** [Robin Schwarzfeld](https://apify.com/nowologix) (community)
- **Categories:** Lead generation, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 trademark records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## German Trademark Register Scraper (DPMA)

Search the German trademark register (DPMAregister, run by the Deutsches Patent- und Markenamt) and
export structured data: trademark names, filing and registration dates, applicants, Nice classes,
goods and services, legal status, the full procedure history, and the figurative mark images
(Bildmarken) as downloadable files. No DPMA account needed.

> **Demo mode (currently on).** By default this Actor runs in Demo mode and returns a small set of
> bundled sample records, including one example figurative mark image, so you can see the exact
> output format for free. This sample data is not live register data. Turn Demo mode off to scrape
> live from DPMAregister.

### What you get

- Word marks, word/figurative marks, figurative marks and 3D marks from the German register.
- Figurative mark images downloaded to the key-value store, linked from every record.
- Full detail per mark: goods and services text per Nice class, applicant name and address,
  former proprietors, opposition period, expiry, and the complete status and procedure history.
- Flexible search: by mark text, applicant, Nice class, file or registration number, mark form,
  status, or filing-date range. A raw expert query is supported for full control.
- Sortable results, so you can list the most recent registrations first.
- A direct link to the official DPMAregister entry for every mark.

### Who uses it

IP attorneys and paralegals (clearance and availability searches), brand-protection teams
(competitor and infringement monitoring), M\&A and due-diligence analysts (IP asset enumeration),
domainers and startups (name availability), and market researchers.

### Example output

Each trademark becomes one dataset item:

```json
{
  "applicationNumber": "951141",
  "registrationNumber": "951141",
  "markText": "Appletiser Pure Natural Apple Juice",
  "markFeature": "Wort-/Bildmarke",
  "markCategory": "Individualmarke",
  "niceClasses": ["32"],
  "applicationDate": "04.03.1970",
  "registrationDate": "10.11.1976",
  "statusText": "Marke eingetragen",
  "applicantName": "European Refreshments Unlimited Company, Drogheda, IE",
  "applicants": ["European Refreshments Unlimited Company, Drogheda, IE"],
  "goodsServices": [
    { "class": "32", "description": "Fruchtsäfte und andere alkoholfreie Getränke." }
  ],
  "records": [
    { "type": "Anmeldeverfahren", "status": "Marke eingetragen", "date": "10.11.1976" }
  ],
  "thumbnailUrl": "https://register.dpma.de/DPMAregister/marke/de/images/..-thumbnail.jpg",
  "imageUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/image-951141.jpg",
  "detailUrl": "https://register.dpma.de/DPMAregister/marke/register/951141/DE",
  "hasImage": true,
  "source": "dpmaregister",
  "scrapedAt": "2026-08-22T19:05:00.000Z"
}
```

The image files live in the run's key-value store and are linked from every record via `imageUrl`.
Word-only marks have no image and are skipped automatically.

#### Output fields

| Field | Description |
|---|---|
| `applicationNumber` | File / registration number (Aktenzeichen) |
| `registrationNumber` | Registration number (RN) |
| `markText` | Verbal element of the mark |
| `markFeature` / `markCategory` | Mark form (Wortmarke, Wort-/Bildmarke, ...) and category |
| `niceClasses` | Nice classes (array) |
| `applicationDate` / `registrationDate` | Filing (Anmeldetag) and registration date |
| `publicationDate` / `expiryDate` / `cancellationDate` | Publication, expiry, cancellation dates |
| `statusText` | Current file status (Aktenzustand) |
| `applicantName` / `applicants` / `formerApplicants` | Current proprietor(s) and previous ones |
| `representative` | Representative (Vertreter), if any |
| `goodsServices` | Goods and services description per class |
| `oppositionPeriodStart` / `oppositionPeriodEnd` | Opposition window |
| `records` | Procedure history (registration, opposition, transfer, renewal, cancellation, ...) |
| `thumbnailUrl` / `imageUrl` / `hasImage` | Thumbnail and full figurative mark image |
| `detailUrl` | Link to the official DPMAregister entry |

### Input

Fill any combination of the structured fields (combined with AND), or provide a raw expert query.
Key options:

| Input | Meaning |
|---|---|
| `markText` | Mark text (field `MARKE`). Wildcards: `?` any, `!` one, `#` one-or-none |
| `applicant` | Applicant or proprietor (`INH`) |
| `niceClasses` | Nice classes, e.g. `9, 35, 42` (`KL`) |
| `registrationNumber` | Exact registration or file number (`RN`) |
| `markForm` | Mark form (`MF`), e.g. `Bildmarke`, `Wort-Bildmarke` |
| `status` | Current status (`ST`) |
| `database` | Data stock: `DE` (default), `EM`, `IR` (`DB`) |
| `applicationDateFrom` / `applicationDateTo` | Filing-date range (`AT`) |
| `rawQuery` | Full DPMAregister expert query. Overrides the fields above. |
| `maxResults` | Cap on exported records (up to 250 per run) |
| `fetchDetails` | Fetch full detail per mark (goods and services, applicant, history) |
| `downloadImages` | Download figurative mark images |
| `useProxy` | Route the browser through Apify Proxy (recommended) |

Raw query example: `MARKE=Apple UND (KL=09 ODER KL=42) UND AT>=01.01.2015`

Operators: `UND` / `ODER` / `NICHT`, comparisons `= >= <= > <`, quotes for phrases, `( )` grouping.

#### Note on result size

Keep your query reasonably specific. The register does not render result sets of many thousands, so a
very broad query (a whole Nice class, or all of Germany) returns nothing usable. For a specific query
the Actor collects every match up to `maxResults` by paging through the hit list, so you can sort the
export (for example by registration date) in the Apify dataset view or your own tooling.

### Monitoring (watch mode)

Turn the Actor into a watchdog for new German filings, useful for brand protection and competitor
tracking:

1. Set your search criteria (your brand terms plus Nice classes, or a competitor's name).
2. Enable `watchMode` and give it a `watchId` label (e.g. `my-brand`).
3. Optionally set `notifyWebhookUrl` (Slack, Make, Zapier, n8n) and/or `notifyEmail`.
4. Schedule it under Apify Schedules (e.g. daily or weekly).

The first run establishes a baseline: it records what already exists and exports nothing. Every run
afterwards exports and alerts on only the marks that are new since the last run (`isNew: true`).
Seen marks are remembered across runs in a named key-value store, so the state survives between
scheduled runs. Set `alertOnFirstRun: true` to also report all current matches on the first run.

### How it works

The DPMAregister search is JavaScript-driven, so the Actor drives it with a headless browser
(Playwright) to run your query and read the hit list. Detail pages and mark images are then fetched
over plain HTTP, which keeps runs fast. Data comes straight from register.dpma.de; no account and no
API contract are required.

### How you are billed (pay-per-event)

This Actor uses Apify pay-per-event pricing:

| Event | Fires when |
|---|---|
| `actor-start` | A run starts |
| `mark-scraped` | A trademark record is exported |

Figurative mark images (Bildmarken) are included at no extra charge. In Demo mode no charges are
made, so you can try it for free first.

### Legal and data protection

- DPMA register data is public. This Actor reads publicly accessible pages of register.dpma.de.
  Automated access is not covered by the site's robots.txt; use it responsibly and at your own
  discretion. If you need a contractually sanctioned feed, the DPMA offers the official
  DPMAconnectPlus interface.
- Records include personal data (applicant names and addresses). If you process or resell this data,
  you are responsible for complying with the GDPR and the DPMA terms of use for your use case.

### Development and deployment

```bash
npm install
npm test                 # run the smoke tests
npm start                # local demo run (uses storage/key_value_stores/default/INPUT.json)

## deploy to Apify
npm i -g apify-cli
apify login
apify push
```

Structure:

```
.actor/        actor.json, input_schema.json, dataset_schema.json, output_schema.json
src/main.js    orchestration (search, detail, images, dataset)
src/search.js  Playwright expert-search (returns the hit list)
src/detail.js  HTTP detail page + image fetch
src/parse.js   DPMAregister HTML to clean JSON
src/query.js   structured input to expert-search query
src/watch.js   monitoring state and notifications
src/mock.js    offline demo data and image generator
test/          smoke tests
```

Not affiliated with or endorsed by the DPMA.

# Actor input Schema

## `mockMode` (type: `boolean`):

When ON, the actor returns a small bundled sample of records (incl. a figurative mark image) so you can see the output shape. This is not live register data. Turn OFF to scrape live from DPMAregister.

## `markText` (type: `string`):

The word / verbal element of the mark. Wildcards: ? (any chars), ! (one char), # (one or no char). Example: Apple or App?e

## `applicant` (type: `string`):

Name of the applicant or proprietor. Example: Apple Inc.

## `niceClasses` (type: `string`):

One or more Nice classes (1 to 45), comma or space separated. Example: 9, 35, 42

## `registrationNumber` (type: `string`):

Exact registration number or file number (Aktenzeichen). Example: 30512345

## `markForm` (type: `string`):

DPMA Markenform, for example Wortmarke, Bildmarke, Wort-Bildmarke. Leave empty for all forms.

## `database` (type: `string`):

Which register to search: German national marks (DE), EU marks (EM) or international registrations (IR).

## `applicationDateFrom` (type: `string`):

Only marks with an application date (Anmeldetag) on or after this date.

## `applicationDateTo` (type: `string`):

Only marks with an application date (Anmeldetag) on or before this date.

## `status` (type: `string`):

Filter by current status, for example Marke eingetragen. Leave empty for any status.

## `rawQuery` (type: `string`):

DPMAregister expert syntax. Operators UND / ODER / NICHT, comparisons = >= <= > <, wildcards ? ! #, quotes for phrases, ( ) grouping. Example: MARKE=Apple UND (KL=09 ODER KL=42) UND AT>=01.01.2015

## `maxResults` (type: `integer`):

Maximum number of records to export. The scraper pages through the hit list (25 per page) until this many are collected.

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

Fetch the detail page for every hit to get goods and services, applicant, dates, opposition period, and the full status history. Turn OFF for a faster list-only run.

## `downloadImages` (type: `boolean`):

Download the full-resolution mark image for figurative marks and store it in the key-value store. Word-only marks have no image.

## `maxConcurrency` (type: `integer`):

How many detail/image requests to run in parallel. Keep it modest to stay polite to the server.

## `requestDelayMs` (type: `integer`):

Small pause between detail requests.

## `useProxy` (type: `boolean`):

Route the browser through Apify Proxy. Recommended to reduce the chance of rate limiting or blocks.

## `watchMode` (type: `boolean`):

Only export marks not seen in earlier runs. Seen marks are remembered across runs in a named key-value store.

## `watchId` (type: `string`):

Optional label to keep multiple monitors apart, for example my-brand. Defaults to a hash of your query.

## `alertOnFirstRun` (type: `boolean`):

By default the first run only establishes a baseline. Enable this to also export and alert on all current matches the first time.

## `notifyWebhookUrl` (type: `string`):

If set, new marks are POSTed as JSON to this URL (Slack, Make, Zapier, n8n, etc.).

## `notifyEmail` (type: `string`):

If set, a summary of new marks is e-mailed here (uses the apify/send-mail integration).

## Actor input object example

```json
{
  "mockMode": true,
  "markText": "Apple",
  "database": "DE",
  "maxResults": 50,
  "fetchDetails": true,
  "downloadImages": true,
  "maxConcurrency": 4,
  "requestDelayMs": 150,
  "useProxy": true,
  "watchMode": false,
  "alertOnFirstRun": false
}
```

# Actor output Schema

## `trademarks` (type: `string`):

Dataset of matched German trademarks: names, filing & registration dates, applicants, Nice classes, goods & services, legal status and image links.

## `images` (type: `string`):

Downloaded figurative mark image files (Bildmarken) stored in the key-value store.

# 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 = {
    "mockMode": true,
    "markText": "Apple"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nowologix/german-trademark-register-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 = {
    "mockMode": True,
    "markText": "Apple",
}

# Run the Actor and wait for it to finish
run = client.actor("nowologix/german-trademark-register-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 '{
  "mockMode": true,
  "markText": "Apple"
}' |
apify call nowologix/german-trademark-register-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nowologix/german-trademark-register-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/O9DtDwb18pO2XmmUW/builds/7AYIBfaRJodzAH4Vm/openapi.json
