# Google Patents Scraper (`lmbtechnology/google-patents-scraper`) Actor

Search Google Patents by keywords, assignee, inventor, CPC code, country and dates, or look up patent numbers. One row per patent: title, assignees, inventors, dates, status, CPC, abstract, claims, citations, family, PDF. Splits dates to pass the 1,000-result cap. Monitor mode. Pay per patent.

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

## Pricing

from $1.00 / 1,000 patents

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

## Google Patents Scraper

Turn a Google Patents search into a clean table of patents. Type keywords (`solid state battery`), a company (`Tesla`), an inventor, a CPC code (`H01M10/0562`), pick countries and dates, or paste patent numbers, and get **one row per patent**: publication number, title, assignees, inventors, priority / filing / publication / grant dates, status, CPC codes, abstract, claims, citation counts, patent family, PDF link. No Google account, no API key.

Built for **patent landscaping, competitor watching, prior-art searches and AI agents** that need structured patent data: list everything a company filed since 2024, map who works on a technology, count a startup's patent family, feed abstracts and claims to an LLM, or get an alert when a competitor publishes a new application.

Google Patents shows at most 1,000 results per search. This scraper can **split a search into date ranges** to collect tens of thousands of patents from one query, without duplicates.

### What you get

For every patent (one row each):

- **Basics** (from the search results): publication number, title, text snippet, country, status (granted / application), priority, filing, publication and grant dates, first inventor and first assignee, language, PDF link, thumbnail, countries of the family.
- **Details** (on by default, from the patent page): abstract, **all** inventors and assignees (original and current), application number, kind code, CPC codes, number of claims and independent claims, the first claim, counts of citations / cited-by / family citations / non-patent citations, family id and family members, legal status (Active, Pending, Expired...), the event timeline (filed, published, granted, reassigned), drawings, prior-art keywords, links to the USPTO and Espacenet pages.
- **Full text** (optional): the complete claims, the description, the lists of cited and citing patents, legal events and similar documents.
- **Where it came from**: the search that found it, Google's rank, the date range (when split).

Errors (a number Google does not know, a search Google rejects) come out as separate `error` rows that are **not charged**, and the rest of the run continues.

### What it does not do

- **More than 1,000 results per search without splitting.** That limit is Google's. Turn on "Split by date" to go past it; results then come in date order, not by relevance.
- **Exact totals.** For big searches Google's "about N results" is an estimate; the scraper reports it as `resultsOnGoogle` in the run summary.
- **All inventors and assignees without details.** Google's search results only name the first inventor and the first assignee. Keep "Include details" on when you need the full lists (or the abstract, CPC codes, claims, citations, family).
- **Grant date filter.** Google filters on priority, filing and publication dates only. A granted patent is published on its grant date, so use publication date with status "Granted only".
- **PDFs for brand-new publications.** Google adds the PDF a little after the publication; until then `pdfUrl` is empty.
- **Images of the drawings, chemistry, non-patent literature texts, Google Scholar results.**
- **Logging in or anything private.** Only public pages are read. This scraper is not affiliated with Google.

Google changes its website now and then. The scraper is tested every day; if Google blocks or changes something, runs report clear error rows instead of silently returning nothing, and fixes are published quickly.

### Input

| Field | Default | Meaning |
|---|---|---|
| `query` | | Keywords, with Google Patents syntax allowed: `"solid electrolyte" OR sulfide`, `TI=(battery)`, `AB=(...)`, `CL=(...)`, `CPC=H01M10/0562`. |
| `assignees` | | Patent owners, one per line (any of them). Use short names: `Tesla`, `Samsung Electronics`. |
| `inventors` | | Inventor names, one per line (any of them). |
| `cpcCodes` | | CPC codes, one per line (any of them); a code also matches its sub-codes. |
| `countries` | | Patent office codes, one per line: `US`, `EP`, `WO`, `CN`, `JP`, `KR`, `DE`... |
| `dateType` | priority | What the date range applies to: priority, filing or publication date. |
| `dateFrom`, `dateTo` | | Date range, YYYY-MM-DD, both ends included. |
| `status` | any | `GRANT` (granted only) or `APPLICATION` (applications only). |
| `patentType` | any | `PATENT` (utility) or `DESIGN`. |
| `languages` | all | Document languages (English, German, Chinese, Japanese...). |
| `litigation` | any | `YES` (known litigation) or `NO`. |
| `deduplicate` | family | `family` = one row per patent family (Google's default), `publication` = every publication. |
| `sortBy` | relevance | `relevance`, `new` or `old` (newest / oldest filing date first). |
| `patents` | | Patent numbers (`US11000000B2`, `EP3849475A4`), Google Patents patent links and Google Patents search links. |
| `maxResults` | 100 | Patents per search (and per search link). |
| `includeDetails` | true | Open each patent's page for the abstract, all inventors and assignees, CPC codes, claims, citations, family and legal status. |
| `includeFullText` | false | Also save the complete claims and description text, citation lists, legal events (needs details). |
| `splitByDate` | false | Go past Google's 1,000-result limit by splitting the date range. |
| `onlyNewPatents` | false | Monitor mode: save only patents not seen in earlier runs. |
| `monitorName` | | Name for the monitor's "already seen" list (otherwise per saved Task or per search configuration). |
| `maxConcurrency` | 10 | Requests at the same time (a run with details is CPU-bound: give it 1-2 GB of memory). |
| `proxyConfiguration` | Apify residential proxy | Google rate-limits every IP after a few dozen requests, so the scraper uses a fresh IP every few requests. Residential proxies work best; with datacenter proxies the run switches to residential by itself when Google starts blocking. |

The search form and the patent list can be used together; each patent number or link always comes with details.

#### Example: everything a company published since 2024

```json
{
  "assignees": ["Tesla"],
  "countries": ["US", "WO", "EP"],
  "dateType": "publication",
  "dateFrom": "2024-01-01",
  "sortBy": "new",
  "maxResults": 500
}
```

#### Example: a technology landscape, past the 1,000 limit

```json
{
  "query": "solid state battery",
  "cpcCodes": ["H01M10/0562"],
  "countries": ["US"],
  "dateFrom": "2020-01-01",
  "maxResults": 5000,
  "splitByDate": true,
  "includeDetails": false
}
```

Without details this is the cheapest way to map a field: number, title, snippet, dates, status, first assignee and inventor for each patent. Run the numbers you care about with details afterwards.

#### Example: watch a competitor (schedule weekly)

```json
{
  "assignees": ["QuantumScape"],
  "onlyNewPatents": true,
  "monitorName": "quantumscape-watch",
  "maxResults": 200
}
```

The first run saves the baseline. Every later run looks at publications since the last run (minus a 7-day overlap) and saves only the patents it has not seen before. Save it as a Task, schedule it, and add an integration (email, Slack, webhook) that fires when the dataset is not empty.

#### Example: specific patents with full text

```json
{
  "patents": [
    "US11000000B2",
    "US 10,886,558 B2",
    "https://patents.google.com/patent/EP3849475A4/en"
  ],
  "includeFullText": true
}
```

#### Example: a Google Patents link

Build the search on patents.google.com, copy the address bar and paste it:

```json
{
  "patents": ["https://patents.google.com/?q=(lidar)&assignee=Waymo&after=priority:20230101&status=GRANT"],
  "maxResults": 300
}
```

### Output example

```json
{
  "type": "patent",
  "publicationNumber": "US11000000B2",
  "title": "Repositioning wires and methods for repositioning prosthetic heart valve devices within a heart chamber and related systems, devices and methods",
  "url": "https://patents.google.com/patent/US11000000B2/en",
  "pdfUrl": "https://patentimages.storage.googleapis.com/78/2c/e4/f1371fcd4ef87a/US11000000.pdf",
  "country": "US",
  "kindCode": "B2",
  "status": "granted",
  "legalStatus": "Active",
  "legalStatusCategory": "active",
  "inventors": ["Jason S. Diedering", "Saravana B. Kumar"],
  "assignees": ["4C Medical Technologies Inc"],
  "assigneesCurrent": ["4C Medical Technologies Inc"],
  "priorityDate": "2018-09-14",
  "filingDate": "2019-09-12",
  "publicationDate": "2021-05-11",
  "grantDate": "2021-05-11",
  "applicationNumber": "US16/568,903",
  "language": "en",
  "abstract": "The invention provides methods, devices and systems for delivering, positioning and/or repositioning an expandable prosthetic heart valve in a patient's heart chamber. ...",
  "snippet": "... repositioning an expandable prosthetic heart valve ...",
  "cpcCodes": ["A61F2/243", "A61F2/2439", "A61F2/90", "A61F2/966", "A61F2/2418", "A61F2002/9511", "A61F2002/9534"],
  "claimsCount": 11,
  "independentClaimsCount": 1,
  "firstClaim": "1. A method for delivering, positioning and/or repositioning a collapsible and expandable stent having a stent frame within a patient's heart chamber, comprising: ...",
  "citationsCount": 9,
  "citedByCount": 15,
  "familyCitationsCount": 19,
  "familyCitedByCount": 20,
  "nonPatentCitationsCount": 1,
  "familyId": "69773736",
  "familyMembers": ["AU2019337666B2", "EP3849475A4", "CA3109662C", "CN112702979A", "JP7018543B2", "US20200085571A1", "WO2020056234A1"],
  "familyCountries": ["US", "EP", "JP", "CN", "AU", "CA", "TW", "WO"],
  "otherVersions": ["US20200085571A1"],
  "thumbnailUrl": "https://patentimages.storage.googleapis.com/68/d9/26/1e0769dff0771b/US11000000-20210511-D00000.png",
  "imageUrls": ["https://patentimages.storage.googleapis.com/89/31/d7/5fa0fd8c6c423f/US11000000-20210511-D00000.png"],
  "priorArtKeywords": ["looped", "wire", "stent", "looped wire", "delivery catheter"],
  "events": [
    { "date": "2019-09-12", "type": "filed", "title": "Application filed by 4C Medical Technologies Inc" },
    { "date": "2020-03-19", "type": "publication", "title": "Publication of US20200085571A1" },
    { "date": "2021-05-11", "type": "granted", "title": "Application granted" }
  ],
  "externalLinks": [
    { "name": "USPTO", "url": "https://patft.uspto.gov/..." },
    { "name": "Espacenet", "url": "https://worldwide.espacenet.com/publicationDetails/biblio?CC=US&NR=11000000B2&KC=B2&FT=D" }
  ],
  "searchQuery": "q=(heart valve repositioning) country=US",
  "searchUrl": "https://patents.google.com/?q=(heart+valve+repositioning)&country=US",
  "rank": 1,
  "dateRange": null,
  "detailsScraped": true,
  "scrapedAt": "2026-10-21T20:16:40.777Z"
}
```

Without details the detail fields are `null` and `inventors` / `assignees` hold the first name only. With "Include full text" the item also has `claimsText`, `descriptionText`, `citations`, `citedBy`, `familyCitations`, `familyCitedBy`, `legalEvents` and `similarDocuments`.

Download the results as JSON, CSV, Excel or HTML from the run's **Output** tab. The dataset has three table views: **Overview** (bibliographic data and links), **Classification and claims** and **Search position**. The `RUN-SUMMARY` record in the key-value store shows, per search, how many results Google reports, how many were saved, pages loaded and any error.

### Pricing

You pay per patent, not for compute time or proxies:

| Event | When | Price |
|---|---|---|
| Patent | Each patent saved | see the Pricing tab |
| Patent detail | Each patent saved with details (`includeDetails`, and every patent number / link) | see the Pricing tab |
| Actor start | Once per run | Apify's standard small start fee |

Error rows are free. Duplicates are free. Patents skipped by monitor mode are free. Full text costs nothing extra. If the details of a patent cannot be loaded, the patent is saved with its search data, a `detailsError` note, and only the patent event is charged.

Set **Maximum cost per run** in the run options to cap spending: the scraper stops cleanly when it is reached and keeps everything already saved.

### Tips

- **Use short assignee names** (`Tesla`, not `Tesla, Inc.`): Google matches the words, and a name with a comma and "Inc" matches far too much.
- **Dates:** priority date = the earliest filing in the family (best for "when was this invented"); publication date = when the document appeared (best for monitoring); filing date = this application.
- **Granted only, since a date:** status `GRANT` + date type `publication` + `dateFrom`.
- For **big landscapes** turn details off first, then run the interesting numbers with details and full text.
- Patents found by two searches in one run are saved once per search with their own rank; use `publicationNumber` to merge.
- The search results group documents by **family** (Google's default): one row per invention. Set `deduplicate` to `publication` to get every country's version.
- The monitor compares publication numbers, so it works across any search; schedule it weekly, not hourly: Google Patents is updated about once a week.

### Is it legal to scrape Google Patents?

Patent documents are public records; Google Patents shows them to every visitor without logging in. This scraper reads those public pages at a modest rate, with no login and no bypass of Google's CAPTCHA (a rate-limited request is simply retried from another IP). It is not affiliated with, endorsed by or connected to Google. Patent texts and drawings may be subject to the rights of the patent offices and applicants in some countries; check your use case before republishing them.

### Support

Found a problem or need a field? Open an issue on the **Issues** tab with the run link and the input you used. Issues are answered within a few days.

# Changelog

This Actor's version history is a separate document: https://apify.com/lmbtechnology/google-patents-scraper/changelog.md

# Actor input Schema

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

What to search for, as you would type it on Google Patents. Plain words (`solid state battery`) or Google Patents syntax: `"solid electrolyte" OR sulfide`, `(lithium) (anode OR cathode)`, `TI=(battery)` (title), `AB=(...)` (abstract), `CL=(...)` (claims), `CPC=H01M10/0562`. Leave empty to search only by assignee, inventor or CPC code.

## `assignees` (type: `array`):

Patent owners, one per line, as named on the patents: `Tesla`, `Toyota Jidosha Kabushiki Kaisha`, `Samsung Electronics`. Several lines = any of them. Short names match more (`Tesla` finds `Tesla, Inc.` and `Tesla Motors`).

## `inventors` (type: `array`):

Inventor names, one per line (`Elon Musk`). Several lines = any of them.

## `cpcCodes` (type: `array`):

Cooperative Patent Classification codes, one per line: `H01M10/0562` (solid electrolytes), `A61F2/24` (heart valves), `G06N3` (neural networks). A code also matches its sub-codes. Several lines = any of them.

## `countries` (type: `array`):

Two-letter codes of the patent offices, one per line: `US`, `EP`, `WO`, `CN`, `JP`, `KR`, `DE`, `GB`, `FR`, `CA`, `AU`, `IN`. Leave empty for all. Several lines = any of them.

## `dateType` (type: `string`):

Which date the date range (and "Split by date") applies to. Priority date is the earliest filing date of the patent family; publication date is when Google Patents shows the document. For the grant date, use publication date with status "Granted": a grant is published on its grant date.

## `dateFrom` (type: `string`):

Earliest date, YYYY-MM-DD.

## `dateTo` (type: `string`):

Latest date, YYYY-MM-DD.

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

Granted patents only, published applications only, or both.

## `patentType` (type: `string`):

Utility patents, design patents, or both.

## `languages` (type: `array`):

Keep only documents written in these languages. Leave empty for all.

## `litigation` (type: `string`):

Only patents with known litigation, only patents without, or all.

## `deduplicate` (type: `string`):

Google Patents groups documents by patent family by default (one row per family, the representative publication). Choose "publication" to get every publication (each country's version) as its own row.

## `sortBy` (type: `string`):

Google's order of the results. With a "Maximum results" below the number of matches this decides which patents you get. "Newest" and "oldest" sort by filing date.

## `patents` (type: `array`):

Optional. Patent numbers (`US11000000B2`, `EP3849475A4`, `WO2020056234A1`, also `US 11,000,000 B2`), Google Patents patent links (`https://patents.google.com/patent/US11000000B2/en`) and Google Patents search links (`https://patents.google.com/?q=...&assignee=...`). Patent numbers always come with details.

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

How many patents to save for each search (the form above and each search link). Google Patents serves at most 1,000 results per search; turn on "Split by date" to go past that.

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

Open each patent's page to add the abstract, all inventors and assignees (search results only name the first ones), application number, CPC codes, number of claims and the first claim, citation counts, family id and family members, legal status and the event timeline. Costs one extra `patent-details` event per patent and one page load (about 100-300 KB each). When off you get what the search list shows: number, title, snippet, first inventor and assignee, dates, status, PDF link.

## `includeFullText` (type: `boolean`):

Needs "Include details". Adds the complete claims text, the description text (often 50-500 KB per patent), the lists of cited and citing patent numbers, family citations, the legal events table and similar documents. No extra charge, but large items: download the dataset as JSON, not CSV.

## `splitByDate` (type: `boolean`):

When a search has more than 1,000 results, split it into date ranges (on the "Date type" above), again and again, until every range has at most 1,000. Use it with a higher "Maximum results per search". Results are then in date order, not by relevance, and a search of a whole field can take thousands of requests.

## `onlyNewPatents` (type: `boolean`):

Save only patents not seen in earlier runs of this monitor; later runs also limit the search to publications since the last run. The first run saves everything it finds (up to "Maximum results per search") as the baseline. State is kept in the key-value store `google-patents-scraper-state` per saved Task, per "Monitor name" or per search configuration. Schedule the Task weekly to watch a competitor or a technology.

## `monitorName` (type: `string`):

Optional name for the monitor state, so that different runs (for example from the API) share the same "already seen" list. Without it the state is kept per saved Task, or per search configuration.

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

How many requests to run at the same time. Google rate-limits each IP after a few dozen requests, so the scraper uses a fresh proxy IP every few requests anyway; higher values mainly make the run faster (a run with details is limited by CPU: give it 1-2 GB of memory).

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

Google blocks an IP for a long time after a few dozen requests, so the scraper needs many IPs: Apify residential proxies (the default) work well. Datacenter proxies work until each IP is rate-limited; with them the run switches to residential proxies by itself when Google starts blocking.

## Actor input object example

```json
{
  "query": "solid state battery",
  "countries": [
    "US"
  ],
  "dateType": "priority",
  "dateFrom": "2024-01-01",
  "status": "any",
  "patentType": "any",
  "litigation": "any",
  "deduplicate": "family",
  "sortBy": "relevance",
  "maxResults": 10,
  "includeDetails": true,
  "includeFullText": false,
  "splitByDate": false,
  "onlyNewPatents": false,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `patents` (type: `string`):

All items as JSON (type "patent" or "error").

## `overviewCsv` (type: `string`):

Number, title, assignees, inventors, dates, status and links as CSV.

## `runSummary` (type: `string`):

Per search: results Google shows, patents saved, pages loaded, date ranges 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 = {
    "query": "solid state battery",
    "countries": [
        "US"
    ],
    "dateFrom": "2024-01-01",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lmbtechnology/google-patents-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 = {
    "query": "solid state battery",
    "countries": ["US"],
    "dateFrom": "2024-01-01",
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lmbtechnology/google-patents-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 '{
  "query": "solid state battery",
  "countries": [
    "US"
  ],
  "dateFrom": "2024-01-01",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call lmbtechnology/google-patents-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lmbtechnology/google-patents-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/eXniy1vRTHmgAdXQC/builds/WXCHQEPQWacTVVkZ8/openapi.json
