patentgrepDocs

PatentsView-compatible

PatentsView-compatible API

patentgrep serves PatentsView's PatentSearch API: all 27 endpoints, the same q, f, s and o parameters, the same field names and the same X-Api-Key header. Change the base URL and your code keeps working.

GroupEndpointsFields
Patents/patent132 / 133
Publications/publication101 / 102
Citations/patent/us_patent_citation /patent/us_application_citation /patent/foreign_citation /patent/other_reference /patent/rel_app_text /publication/rel_app_text28 / 28
Claims and text/g_claim /pg_claim /g_brf_sum_text /pg_brf_sum_text /g_detail_desc_text /pg_detail_desc_text /g_draw_desc_text /pg_draw_desc_text27 / 27
Assignees, inventors and locations/assignee /inventor /patent/attorney /location56 / 57
Classification/cpc_class /cpc_subclass /cpc_group /ipc /uspc_mainclass /uspc_subclass /wipo43 / 43

387 of 390 PatentsView fields are served. The 3 missing are inferred inventor gender. What else is different

The only change
# Before: BASE = "https://search.patentsview.org/api/v1"
BASE = "https://api.patentgrep.com/api/v1"
curl https://api.patentgrep.com/api/v1/patent/ \
  -H "X-Api-Key: $PATENTGREP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "q": {"_gte": {"patent_date": "2026-01-01"}},
    "f": ["patent_id", "patent_title"],
    "o": {"size": 100}
  }'
import os, requests

resp = requests.post(
    "https://api.patentgrep.com/api/v1/patent/",
    headers={"X-Api-Key": os.environ["PATENTGREP_KEY"]},
    json={
          "q": {"_gte": {"patent_date": "2026-01-01"}},
          "f": ["patent_id", "patent_title"],
          "o": {"size": 100}
        },
)
resp.raise_for_status()
data = resp.json()
print(data)
const res = await fetch("https://api.patentgrep.com/api/v1/patent/", {
  headers: {
    "X-Api-Key": process.env.PATENTGREP_KEY,
    "Content-Type": "application/json",
  },
  method: "POST",
  body: JSON.stringify({
    "q": {"_gte": {"patent_date": "2026-01-01"}},
    "f": ["patent_id", "patent_title"],
    "o": {"size": 100}
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const data = await res.json();
console.log(data);
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "q": {"_gte": {"patent_date": "2026-01-01"}},
	  "f": ["patent_id", "patent_title"],
	  "o": {"size": 100}
	}`)

	req, err := http.NewRequest(http.MethodPost, "https://api.patentgrep.com/api/v1/patent/", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-Api-Key", os.Getenv("PATENTGREP_KEY"))
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("%s: %s", res.Status, data))
	}
	fmt.Println(string(data))
}
require "json"
require "net/http"

uri = URI("https://api.patentgrep.com/api/v1/patent/")

req = Net::HTTP::Post.new(uri)
req["X-Api-Key"] = ENV.fetch("PATENTGREP_KEY")
req["Content-Type"] = "application/json"
req.body = <<~'JSON'
  {
    "q": {"_gte": {"patent_date": "2026-01-01"}},
    "f": ["patent_id", "patent_title"],
    "o": {"size": 100}
  }
JSON

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
raise "#{res.code}: #{res.body}" unless res.is_a?(Net::HTTPSuccess)
data = JSON.parse(res.body)
p data

GET and POST

Every endpoint takes POST with a JSON body, or GET with q, f, s and o as JSON-encoded query parameters. Most endpoints also look up one record by id, such as GET /api/v1/patent/12756070/.

curl -G https://api.patentgrep.com/api/v1/patent/ \
  -H "X-Api-Key: $PATENTGREP_KEY" \
  --data-urlencode 'q={"patent_id":"12756070"}' \
  --data-urlencode 'f=["patent_id","patent_title"]'
import os, requests

resp = requests.get(
    "https://api.patentgrep.com/api/v1/patent/",
    headers={"X-Api-Key": os.environ["PATENTGREP_KEY"]},
    params={"q": "{\"patent_id\":\"12756070\"}", "f": "[\"patent_id\",\"patent_title\"]"},
)
resp.raise_for_status()
data = resp.json()
print(data)
const params = new URLSearchParams({
  q: "{\"patent_id\":\"12756070\"}",
  f: "[\"patent_id\",\"patent_title\"]",
});
const res = await fetch(`https://api.patentgrep.com/api/v1/patent/?${params}`, {
  headers: {
    "X-Api-Key": process.env.PATENTGREP_KEY,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const data = await res.json();
console.log(data);
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
)

func main() {
	params := url.Values{}
	params.Add("q", `{"patent_id":"12756070"}`)
	params.Add("f", `["patent_id","patent_title"]`)

	req, err := http.NewRequest(http.MethodGet, "https://api.patentgrep.com/api/v1/patent/?"+params.Encode(), nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-Api-Key", os.Getenv("PATENTGREP_KEY"))

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("%s: %s", res.Status, data))
	}
	fmt.Println(string(data))
}
require "json"
require "net/http"

uri = URI("https://api.patentgrep.com/api/v1/patent/")
uri.query = URI.encode_www_form(q: "{\"patent_id\":\"12756070\"}", f: "[\"patent_id\",\"patent_title\"]")

req = Net::HTTP::Get.new(uri)
req["X-Api-Key"] = ENV.fetch("PATENTGREP_KEY")

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
raise "#{res.code}: #{res.body}" unless res.is_a?(Net::HTTPSuccess)
data = JSON.parse(res.body)
p data