Google Patents API: Search Patents and Get Details
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.
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 if you don't have one yet.
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 …:
{
"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 cover the api_key query parameter for places where headers aren't possible. The requests and responses docs 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 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:
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.
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 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 advise.
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 and 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 shows how. To walk further than three pages, see paginating a web data API safely.
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 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, and the data is returned as found at the time of the call.
For agents, the MCP server 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 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, then copy the cURL call into your own code. The same key also covers Google Scholar if you want papers next to patents, and the rest of the search engines APIs.
APIs in this post
Frequently asked questions
Is there an official way to get Google Patents data?
For bulk analysis, Google publishes Google Patents Public Datasets on BigQuery. 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 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.