---
title: "Google Patents API: Search Patents and Get Details"
description: "Search Google Patents by keyword, inventor or assignee with one GET call, then fetch full details by patent_id. Both endpoints cost 1 credit per call."
url: https://perceptlayer.com/blog/google-patents-api-search-details
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# Google Patents API: Search Patents and Get Details

13 Oct 2026 Perceptlayer 6 min read

You can get Google Patents results as JSON with two calls. `GET /v1/google-patents/search` takes a query and returns matching patents with title, dates, inventor and assignee. `GET /v1/google-patents/details` takes one `patent_id` and returns that patent's record. Each successful call costs 1 credit.

## Key takeaways

-   Search first, then fetch details: `search` needs only `q` (up to 500 characters), and `details` needs only the `patent_id` that search returns.
-   `search` filters by `status` ( `GRANT` or `APPLICATION`), `type` ( `PATENT` or `DESIGN`), `sort` ( `new` or `old`), plus `country`, `language`, `before`, `after`, `inventor` and `assignee`.
-   Both endpoints cost 1 credit on success. A failed call costs nothing and returns `X-Credits-Used: 0`.
-   The recorded search for `machine learning` reported 122,797 results over 99 pages, so page through with `page` rather than expecting everything in one response.
-   For whole-corpus analysis, an official bulk dataset is usually a better fit than any per-call API.

## How do you search Google Patents with an API?

Send a GET request to `/v1/google-patents/search` with a `q` parameter and your key in the `X-API-Key` header. The response is JSON: a `data` object with result totals and a `patents` array. Every item carries a `patent_id`, a title, a snippet, dates, inventor and assignee. [Get a free API key](https://perceptlayer.com/signup) if you don't have one yet.

```bash
curl "https://api.perceptlayer.com/v1/google-patents/search?q=machine+learning" \
  -H "X-API-Key: $API_KEY"
```

Here is an excerpt of the recorded response for that request, trimmed with `…`:

```json
{
  "success": true,
  "data": {
    "total_results": 122797,
    "total_pages": 99,
    "current_page": 1,
    "many_results": false,
    "patents": [
      {
        "patent_id": "patent/US12438891B1/en",
        "rank": 0,
        "title": "Anomaly detection based on ensemble machine learning model",
        "snippet": "accessing the entity profile to read the plurality of features scores for the entity; …",
        "publication_number": "US12438891B1",
        "language": "en",
        "dates": {
          "priority": "2015-08-31",
          "filing": "2022-02-18",
          "grant": "2025-10-07",
          "publication": "2025-10-07"
        },
        "inventor": "…",
        "assignee": "Splunk Inc.",
        "family_status": [
          { "country": "US", "status": "ACTIVE" }
        ]
      },
      …
    ],
    "cached": false,
    "response_time_ms": 731
  }
}
```

Authentication is a single header; the [authentication docs](https://docs.perceptlayer.com/authentication) cover the `api_key` query parameter for places where headers aren't possible. The [requests and responses docs](https://docs.perceptlayer.com/requests) describe the envelope.

## Which parameters does the search endpoint take?

The search endpoint takes one required parameter, `q`, and eleven optional ones that narrow or order the results. Only `sort`, `status` and `type` have a fixed set of allowed values. The rest are free strings or integers, and nothing more is documented about them, so test a value in the [Google Patents search playground](https://perceptlayer.com/apis/google-patents/search) before you build on it.

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `q` | string | yes | Search query, up to 500 characters |
| `page` | integer | no | Results page; compare with `total_pages` in the response |
| `num` | integer | no | Number of results |
| `sort` | string | no | `new` or `old` |
| `before` | string | no | Date upper bound |
| `after` | string | no | Date lower bound |
| `country` | string | no | Country filter |
| `language` | string | no | Language filter |
| `status` | string | no | `GRANT` or `APPLICATION` |
| `type` | string | no | `PATENT` or `DESIGN` |
| `inventor` | string | no | Inventor name |
| `assignee` | string | no | Assignee name, such as a company |

A typical filtered call asks for granted utility patents, newest first:

```bash
curl "https://api.perceptlayer.com/v1/google-patents/search?q=solid+state+battery&status=GRANT&type=PATENT&sort=new" \
  -H "X-API-Key: $API_KEY"
```

## How do you get the details for one patent?

Pass a `patent_id` from the search results to `/v1/google-patents/details`. It's the only parameter, and it's required. The search response gives you the value to use in each item's `patent_id` field, for example `patent/US12438891B1/en` in the recorded sample above.

```bash
curl "https://api.perceptlayer.com/v1/google-patents/details?patent_id=patent/US12438891B1/en" \
  -H "X-API-Key: $API_KEY"
```

We haven't recorded a details response for this article, so we won't show one. Open the [Google Patents details endpoint](https://perceptlayer.com/apis/google-patents/details) and run it in the playground to see the fields for a patent you care about. That's the quickest way to decide which of them your code will read.

The two calls suit two jobs. A search page lists many patents for 1 credit, with the title, snippet, dates and assignee, so it works for triage. Details returns one patent for 1 credit, so save it for the short list you actually need to read.

## How do you pull patents for a topic in Python?

Loop over pages of search results, filter on the fields search already returns, then call details only for what survives. The script below stops at a page cap, so it can never spend more than a number you chose. It retries once on `429` and `503` using the `Retry-After` header, as the [rate limits docs](https://docs.perceptlayer.com/rate-limits) advise.

```python
import json
import os
import time

import requests

BASE = "https://api.perceptlayer.com/v1/google-patents"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}

def get(path, params):
    for attempt in range(2):
        r = requests.get(f"{BASE}/{path}", params=params, headers=HEADERS, timeout=30)
        if r.status_code in (429, 503) and attempt == 0:
            time.sleep(int(r.headers.get("Retry-After", "1")))
            continue
        r.raise_for_status()
        return r.json()["data"]

def search_topic(query, max_pages=3):
    found = []
    page = 1
    while page <= max_pages:
        data = get("search", {"q": query, "status": "GRANT", "sort": "new", "page": page})
        found.extend(data["patents"])
        if page >= data["total_pages"]:
            break
        page += 1
    return found

patents = search_topic("solid state battery")

# Triage on fields search already returns, before spending on details.
shortlist = [p for p in patents if p["dates"]["grant"] >= "2025-01-01"][:25]

records = [get("details", {"patent_id": p["patent_id"]}) for p in shortlist]

with open("patents.json", "w") as f:
    json.dump(records, f)
print(len(patents), "found,", len(records), "detailed")
```

The grant date is compared as an ISO string, which matches the format in the recorded sample ( `2025-10-07`). We haven't recorded a response for an application, so we haven't confirmed what `dates.grant` holds for patents without a grant. The search above sets `status` to `GRANT` so the filter doesn't depend on it.

### What does a run cost?

Every successful call is 1 credit, so the cost is the search pages plus the details calls. With `max_pages=3` and a shortlist capped at 25, the most this script can spend is 3 + 25 = 28 credits. Failed calls aren't billed. Read `X-Credits-Used` and `X-Credits-Remaining` on any response to track it, and see the [credits docs](https://docs.perceptlayer.com/credits) and [pricing](https://perceptlayer.com/pricing) for what credits cost.

The free tier gives 1,000 credits a month after you verify an email address, which covers about 35 runs of this script at its cap. If your pipeline repeats the same queries, cache the results; the post on [caching API responses in Python](https://perceptlayer.com/blog/cache-web-data-api-responses) shows how. To walk further than three pages, see [paginating a web data API safely](https://perceptlayer.com/blog/paginate-web-data-api-python).

## When is an official bulk dataset a better fit?

If you need the whole corpus, or every patent in a field over many years, use an official bulk dataset. A per-call API charges per call and fits targeted lookups and monitoring, while a dataset you query yourself fits full-corpus statistics. Using the API for the second job spends credits on data you can get in bulk.

One official option is worth knowing: [Google Patents Public Datasets on BigQuery](https://cloud.google.com/blog/topics/public-datasets/google-patents-public-datasets-connecting-public-paid-and-private-patent-data) puts patent publications from many countries in SQL-queryable tables, so landscape analysis runs as a query rather than a crawl.

The API suits the other cases: an agent that looks up the patents behind a product claim, a dashboard that watches a competitor's new grants, or a script that enriches a list of company names. The endpoints cover search on [Google Patents](https://patents.google.com/), and the data is returned as found at the time of the call.

For agents, the [MCP server](https://docs.perceptlayer.com/ai-agents) exposes the same endpoints as tools. `search_endpoints` and `get_endpoint` look up the catalogue for free, and `call_endpoint` spends credits only on success.

## What can go wrong?

Errors come back as an HTTP status and a JSON body with `error.code`, `error.message` and `error.request_id`. The ones you'll meet here are `invalid_parameters` (422), for example when `status` isn't `GRANT` or `APPLICATION`; `invalid_api_key` (401); `insufficient_credits` (402) when the balance runs out; and `rate_limited` (429). The [errors docs](https://docs.perceptlayer.com/errors) list them all.

Free accounts get 1 request a second, shared by all keys on the account. The script above is sequential, so it stays inside that. If you parallelise details calls, read `RateLimit-Remaining` and back off on `Retry-After`. A timed-out request may still have succeeded and been billed, because requests have no idempotency key.

Next step: run one search in the [playground on the Google Patents API page](https://perceptlayer.com/apis/google-patents), then copy the cURL call into your own code. The same key also covers [Google Scholar](https://perceptlayer.com/blog/google-scholar-api) if you want papers next to patents, and the rest of the [search engines APIs](https://perceptlayer.com/verticals/search).

## APIs in this post

-   [Google Patents **1 credit per call** · 2 endpoints](https://perceptlayer.com/apis/google-patents)

## Frequently asked questions

### Is there an official way to get Google Patents data?

For bulk analysis, Google publishes [Google Patents Public Datasets on BigQuery](https://cloud.google.com/blog/topics/public-datasets/google-patents-public-datasets-connecting-public-paid-and-private-patent-data). For per-query lookups, Perceptlayer's `search` and `details` endpoints return Google Patents results as JSON, with 1 credit per successful call. Use BigQuery for full-corpus work and the API for lookups.

### How much does the Google Patents API cost?

Both `search` and `details` cost 1 credit per successful call, and failed calls cost nothing. Free accounts get 1,000 credits a month after email verification, with no credit card. Fetching 100 patents' details after 5 search pages is 5 + 100 = 105 credits. [Pricing](https://perceptlayer.com/pricing) lists what credit packs cost.

### Can I search by inventor or company?

Yes. Use `inventor` for a person's name and `assignee` for the owning organisation, alone or together with `q`, which is always required. Add `status=GRANT` to keep only granted patents. The recorded sample shows `assignee` as a plain string, so match the company name as Google Patents writes it.

### How do I get all the results for a query?

Read `total_pages` from the first response, then request `page=2`, `page=3` and so on until you reach it. The recorded search for `machine learning` reported 99 pages. Cap your loop, because each page is a billed call, and cache anything you'll reread.

### Do I need the details call for every patent?

No. Search already returns title, snippet, publication number, dates, inventor, assignee and family status for each hit. Filter on those first and call `details` only for the patents you need to read in full. That keeps a run to a handful of credits instead of one details call per hit.

patents google patents search research json

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 14 Oct 2026 Perceptlayer 7 min read
    
    ## [Google News API: Search News Articles as JSON](https://perceptlayer.com/blog/google-news-api)
    
    One GET call to /v1/google-news/news returns articles with title, link, source and ISO date as JSON for 1 credit. Parameters, a real response, cost.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 19 Aug 2026 Perceptlayer 8 min read
    
    ## [Google Events API: Find Local Events as JSON](https://perceptlayer.com/blog/google-events-api-local-events)
    
    Search Google Events as JSON with one GET: q, hl, gl, location and start parameters, a recorded London response, and 1 credit per call.
    
3.  [API guides](https://perceptlayer.com/blog/category/api-guides) 7 Aug 2026 Updated 26 Oct 2026 Perceptlayer 6 min read
    
    ## [Yelp Reviews API: Business Search and Reviews as JSON](https://perceptlayer.com/blog/yelp-reviews-api-json)
    
    Three Yelp endpoints return search results, business details and reviews as JSON, 1 credit per call. Parameters, a real response and a cost example.
