Skip to content

About

USPTO patents scraper for Node.js: query US grants and published applications by keyword, assignee or CPC class and get typed patent objects with dates, CPC codes and document links for your API or worker. JavaScript example for the Devil Scrapes Apify Actor.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

USPTO Patent Scraper — JavaScript example

USPTO Patents Scraper for JavaScript and Node.js: US patent search as a JSON API

Run on Apify JavaScript MIT license CI

Use this repository to query the USPTO Patent Scraper from Node.js. One ES module and Apify's official client turn a search string such as TI/(solid state battery) into an array of US patent objects carrying number, title, abstract, inventors, assignees, CPC codes, kind code, dates and a link to the full document. The heavy lifting runs on Apify against Google Patents' index of US documents, so your Express service, Lambda function or queue worker sends a query, waits and reads JSON. No patent-office credentials live in your app; the only secret is the Apify token, which is about as much paperwork as a patent search should need.

Actor: USPTO Patent Scraper · Publisher: Devil Scrapes · Also in Python: uspto-patents-scraper-python

🔥 What you get

  • US documents only: every search is restricted to US grants and published applications, so a sweep on one company does not fill up with foreign family members of the same invention.
  • Search-box qualifiers that work: TI/ for titles, AB/ for abstracts, AN/ for assignee, IN/ for inventor and CPC/ for a classification, one qualifier per query, or plain words across title, abstract and claims.
  • Three orderings: relevance, newest publication first or oldest publication first.
  • Grants told apart from applications: grant_date is filled only for B1 and B2 kind codes, while publication_date, filing_date and priority_date arrive as ISO YYYY-MM-DD strings.
  • Lists stay lists: inventors, assignees and CPC codes come back as arrays, never as one comma-joined string you have to split.
  • Stops where you told it to: the maxResults cap (up to 2,000 per run) is enforced in the middle of a page, so you never pay for overshoot.
  • One failed document never sinks the run: a patent page that errors is logged and skipped, it is not billed, and the rest of the result set still lands.
  • Every row links home: patent_url points to the full document on Google Patents for claims, drawings and citations.

🎯 Use cases

Patent search inside your own product

Wrap the core call in a route that accepts a query and a limit, start the run, and return the objects to your front end. Users of an R&D or legal-tech tool search patents without leaving your app, and you control how results are cached and displayed.

New-filing alerts for watched companies

A scheduled worker runs one AN/ query per watched assignee with newest-first sorting, compares the patent_number values with what is already stored, and posts only the unseen documents to a Slack or Teams webhook. People hear about a new publication the week it appears.

Patent metadata in a search index

Stream the objects into Elasticsearch, OpenSearch or a Postgres full-text column, keyed by patent_number. Titles and abstracts become searchable in your own stack, and the CPC arrays make good facet filters.

Background enrichment for company records

When a CRM or diligence app adds a company, enqueue an assignee search and attach counts of grants and pending publications to the record. It is a cheap, automatic signal of how much IP a target actually holds.

⚡ Quick start

You need an Apify account and an API token from Console → Settings → Integrations. Apify's free plan includes monthly usage credit; this Actor's event prices are listed under Pricing below.

git clone https://github.com/devilscrapes/uspto-patents-scraper-javascript.git
cd uspto-patents-scraper-javascript
npm install
export APIFY_TOKEN=your_token_here
node index.js                       # uses input.json
node index.js my-input.json --out data --max-charge 2

The script starts the USPTO Patent Scraper, waits for it to finish, prints a link to the run in Apify Console and saves every result to results.json and results.csv. It exits with code 1 and the run's status message if the run fails.

🧩 The core call

The integration comes down to these lines. call() returns once the run has completed, and listItems() fetches the default dataset as an array of objects.

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('DevilScrapes/uspto-patents-scraper').call({"searchQuery": "TI/(solid state battery)", "maxResults": 10, "sortBy": "publication_date_desc", "proxyConfiguration": {"useApifyProxy": false}});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

📥 Input

index.js sends input.json to the Actor as is. The sample searches patent titles for a single phrase, newest first, and caps the run at ten documents so a test costs a few cents. In a service you would build this object per request, putting the user's text in searchQuery, a CPC or assignee qualifier when they pick a filter, and a sensible maxResults ceiling.

{
  "searchQuery": "TI/(solid state battery)",
  "maxResults": 10,
  "sortBy": "publication_date_desc",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
Field Type Required Default Allowed values
searchQuery string yes "neural network training" —
maxResults integer no 30 —
sortBy string no "relevance" relevance, publication_date_desc, publication_date_asc
proxyConfiguration object no {"useApifyProxy": false} —

📤 Output

Each object is one US document. Arrays are always arrays, dates are YYYY-MM-DD strings or null, and grant_date stays null unless the kind code is B1 or B2. The applicants and ipc_classifications arrays exist in the schema but currently come back empty, so build filters on assignees and cpc_classifications.

Field Type Always present
patent_number string yes
publication_id string no
title string yes
abstract string or null no
inventors array no
assignees array no
applicants array no
cpc_classifications array no
ipc_classifications array no
publication_date string or null no
grant_date string or null no
filing_date string or null no
priority_date string or null no
kind_code string or null no
patent_url string yes
scraped_at string no

💰 Pricing

Event Price (USD)
Actor start $0.2
Result emitted $0.003

Prices as configured on 2026-08-20. The Actor page always shows the current price. Runs are billed to the Apify account that owns the token. Use --max-charge to cap what a single run can cost.

🛠️ Working with the data in JavaScript

The script below uses Node.js built-ins only. It groups the saved documents by assignee, counts grants against other publications, records the CPC subclasses each owner works in, and writes a JSON summary your API can serve directly.

import { readFile, writeFile } from 'node:fs/promises';

const rows = JSON.parse(await readFile('results.json', 'utf8'));
const owners = new Map();

for (const row of rows) {
    const names = row.assignees?.length ? row.assignees : ['(no assignee listed)'];
    for (const name of names) {
        const entry = owners.get(name) ?? { name, granted: 0, other: 0, latest: null, subclasses: new Set() };
        if (row.grant_date) entry.granted += 1;
        else entry.other += 1;
        if (row.publication_date && (!entry.latest || row.publication_date > entry.latest)) entry.latest = row.publication_date;
        for (const code of row.cpc_classifications ?? []) entry.subclasses.add(code.slice(0, 4));
        owners.set(name, entry);
    }
}

const summary = [...owners.values()]
    .map((entry) => ({ ...entry, subclasses: [...entry.subclasses].sort() }))
    .sort((a, b) => b.granted + b.other - (a.granted + a.other));

await writeFile('assignee-summary.json', `${JSON.stringify(summary, null, 2)}\n`);
console.table(summary.slice(0, 10).map(({ name, granted, other, latest }) => ({ name, granted, other, latest })));

❓ FAQ

Is there an official USPTO API I should call instead?

The USPTO publishes bulk data files and its own search tools, but this Actor gives a backend one small JSON contract for keyword, assignee and CPC search with no account. Pick the bulk files when you need the entire corpus; pick this when you need answers to specific queries.

How do I run it from a serverless function without hitting a timeout?

Call client.actor('DevilScrapes/uspto-patents-scraper').start(input) instead of call(), return right away, and register an Apify webhook for successful runs that points at a second function. That one reads the dataset by its ID and stores the documents.

Can I use the qualifiers in user-facing search?

Yes, with one rule: a query holds plain text or exactly one qualifier such as CPC/ or IN/, and AND or OR between qualifiers is not supported. Validate that in your route, or fan out one run per filter and intersect the arrays in JavaScript.

How do I keep costs predictable?

There is a start fee per run and a per-document charge, listed under Pricing. Cap maxResults in your route, and pass --max-charge to node index.js while you experiment so a broad query cannot run away.

Does it cover European or international patents?

No. Results are limited to US grants and published applications, and patent family members are not returned, so treat each object as a single US document.

🧯 Troubleshooting

  • Set APIFY_TOKEN first: export the token in the same shell, or put it in a local .env file your shell loads. Never commit it.
  • Run finished with FAILED or ABORTED: open the printed Console link; the run log says why. Input validation errors name the field.
  • Fewer rows than expected: a --max-charge cap also limits how many results can be charged. Raise the cap or lower the limits in your input.
  • Something looks wrong in the data: open an issue on the Actor page so the maintainers see it.

🔗 More from Devil Scrapes

Related Actors:


MIT licensed example code. The Actor itself runs on Apify and is maintained by Devil Scrapes. Not affiliated with the USPTO or Google.

About

USPTO patents scraper for Node.js: query US grants and published applications by keyword, assignee or CPC class and get typed patent objects with dates, CPC codes and document links for your API or worker. JavaScript example for the Devil Scrapes Apify Actor.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages