odp

package module
v1.6.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 8, 2026 License: MIT Imports: 18 Imported by: 0

README

USPTO Open Data Portal (ODP) Go Client

CI Go Reference Go Report Card

A Go client for the USPTO Open Data Portal (ODP) REST API, the Office Action APIs (DSAPI), and TSDR (Trademark Status & Document Retrieval).

Overview

  • Patent Application API (13 endpoints) - search, metadata, continuity, assignment, adjustment, attorney, foreign priority, transactions, documents.
  • Bulk Data API (3 endpoints) - product search and resumable file downloads with progress callbacks.
  • Petition API (3 endpoints) - petition decision search, retrieval, download.
  • PTAB API (19 endpoints) - trial proceedings, decisions, documents, appeal decisions, interference decisions.
  • Office Action APIs (8 endpoints) - text retrieval, citations, rejections, enriched citations, via the DSAPI Lucene/Solr pattern.
  • TSDR (7 wrapper methods) - trademark status and document retrieval on a separate server with its own key.
  • Patent number normalization - accepts application, grant, publication, and PCT formats; resolves grant/publication numbers to application numbers.
  • XML full text - parses ICE DTD 4.6/4.7 grant and application documents.
  • Retry logic with exponential backoff, Retry-After honoring, and configurable timeouts.
ODP releases & spec versions

USPTO bumps the portal version (currently 4.0) for any change to the ODP -- UI updates, new bulk datasets, ecosystem additions -- even when the underlying API specs don't change. Each swagger file carries its own info.version, and that's the contract this client binds to.

Spec file Version Surface
swagger.yaml 1.0.0 Patent Application, Bulk Data, Petition, PTAB
odp-common-base.yaml 1.0.0 Shared schemas
trial-proceedings.yaml 1.0.0 PTAB trial proceedings
trial-decisions.yaml 1.0.0 PTAB trial decisions
trial-documents.yaml 1.0.0 PTAB trial documents
trial-appeal-decisions.yaml 1.0.0 PTAB appeal decisions
trial-interferences.yaml 1.0.0 PTAB interference decisions
trial-common.yaml 1.1.0 Shared PTAB types
oa-text-retrieval.yaml 1.0.0 Office Action text
oa-citations.yaml 1.0.0 Office Action citations
oa-rejections.yaml 1.0.0 Office Action rejections
oa-enriched-citations.yaml 1.0.0 Office Action enriched citations
tsdr-swagger.json version 1 TSDR (separate server + key)

What this client implements from each ODP portal release:

Portal release Date Changes affecting this client
3.0 2025-11-21 Initial PTAB datasets via ODP -- wrapped (19 endpoints).
3.2 2026-01-16 Office Action Weekly Archives surfaced as bulk product OACT -- accessible via the existing SearchBulkProducts / GetBulkProduct wrappers. PTAB RSS feed not wrapped (separate host, no API key).
3.3 2026-03-04 Trademark (TM) Decisions & Proceedings reachable only through the portal SPA at data.uspto.gov/ui/trademark/tm-decisions-api/, using cookie + WAF-token auth. No public API spec. Not wrapped; will revisit if USPTO publishes one.
3.4 2026-03-13 PatentsView bulk products surfaced via the existing bulk-data wrappers.
3.5 2026-03-24 Office Action APIs migrated to ODP -- wrapped (8 endpoints). The OA wrappers use the ODP host (Config.OABaseURL default https://api.uspto.gov).
3.6 2026-04-10 US PCT numbers standardized to 15-char (PCTUS...); display form is 17-char with slashes -- fully supported. Patent Assignments API: countryOrStateCode deprecated, location consolidated under geographicRegionCode -- handled with fallback. Daily/yearly bulk file resumption is dataset coverage, no client change.
4.0 (latest) Portal-level changes; the API specs in this repo are still 1.0.x. If 4.0 ever introduces a path or schema change, drop the new swagger files into swagger/ and run go run ./cmd/gen; the coverage test catches anything that goes silently unwrapped.

Installation

go get github.com/patent-dev/uspto-odp

Getting access

The ODP API requires a free MyUSPTO (USPTO.gov) account and an ODP API key issued from data.uspto.gov. Key issuance involves identity verification: your USPTO.gov account must be linked to a validated ID.me identity. The same key covers the Patent, PTAB, Petition, Bulk Data, and Office Action APIs and is sent in the X-API-Key header. TSDR uses a separate key (see TSDR).

  1. Sign in at MyODP, or create a USPTO.gov account from the sign-in page if you don't have one.

  2. Verify your identity with ID.me and link it to your USPTO.gov account (required before a key can be issued).

  3. Request an API key from the Getting Started page and copy it.

  4. Export it for the client and demo:

    export USPTO_API_KEY=...
    # optional, for TSDR (https://account.uspto.gov/profile/api-manager):
    export USPTO_TSDR_API_KEY=...
    

Unused ODP keys are deleted after 90 days of inactivity.

Quick start

config := odp.DefaultConfig()
config.APIKey = os.Getenv("USPTO_API_KEY")
client, err := odp.NewClient(config)
if err != nil {
    log.Fatal(err)
}

ctx := context.Background()
results, err := client.SearchPatents(ctx, "artificial intelligence", 0, 10)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Found %d patents\n", *results.Count)

Usage

All ODP API endpoints are wrapped, plus the Office Action and TSDR APIs (53 wrapper methods total).

Patent Application API (13 endpoints)
// Core Patent Data
SearchPatents(ctx, query string, offset, limit int) (*PatentDataResponse, error)
GetPatent(ctx, patentNumber string) (*PatentDataResponse, error)  // Accepts any patent number format
GetPatentMetaData(ctx, applicationNumber string) (*MetaDataResponse, error)

// Patent Details
GetPatentAdjustment(ctx, applicationNumber string) (*AdjustmentResponse, error)
GetPatentContinuity(ctx, applicationNumber string) (*ContinuityResponse, error)
GetPatentDocuments(ctx, applicationNumber string) (*DocumentBag, error)
GetPatentAssignment(ctx, applicationNumber string) (*AssignmentResponse, error)
GetPatentAssociatedDocuments(ctx, applicationNumber string) (*AssociatedDocumentsResponse, error)
GetPatentAttorney(ctx, applicationNumber string) (*RecordAttorney, error)
GetPatentForeignPriority(ctx, applicationNumber string) (*ForeignPriorityResponse, error)
GetPatentTransactions(ctx, applicationNumber string) (*TransactionsResponse, error)

// Downloads & Utilities
SearchPatentsDownload(ctx, req PatentDownloadRequest) ([]byte, error)
GetStatusCodes(ctx) (*StatusCodeSearchResponse, error)
Bulk Data API (3 endpoints)
SearchBulkProducts(ctx, query string, offset, limit int) (*BdssResponseBag, error)
GetBulkProduct(ctx, productID string) (*BdssResponseProductBag, error)

// File download methods (use FileDownloadURI directly):
DownloadBulkFile(ctx, fileDownloadURI string, w io.Writer) error
DownloadBulkFileWithProgress(ctx, fileDownloadURI string, w io.Writer,
    progress func(bytesComplete, bytesTotal int64)) error
product, err := client.GetBulkProduct(ctx, "PTGRXML")
files := *product.BulkDataProductBag[0].ProductFileBag.FileDataBag

for _, file := range files {
    if file.FileName != nil && strings.Contains(*file.FileName, "ipg250923.zip") {
        if file.FileDownloadURI != nil {
            err := client.DownloadBulkFileWithProgress(ctx, *file.FileDownloadURI, outputFile,
                func(bytesComplete, bytesTotal int64) {
                    percent := float64(bytesComplete) * 100 / float64(bytesTotal)
                    fmt.Printf("\rProgress: %.1f%%", percent)
                })
        }
        break
    }
}
Petition API (3 endpoints)
SearchPetitions(ctx, query string, offset, limit int) (*PetitionDecisionResponseBag, error)
GetPetitionDecision(ctx, recordID string, includeDocuments bool) (*PetitionDecisionIdentifierResponseBag, error)
SearchPetitionsDownload(ctx, req PetitionDecisionDownloadRequest) ([]byte, error)
PTAB (Patent Trial and Appeal Board) API (19 endpoints)
// Trial Proceedings (IPR, PGR, CBM)
SearchTrialProceedings(ctx, query string, offset, limit int) (*ProceedingDataResponse, error)
GetTrialProceeding(ctx, trialNumber string) (*ProceedingDataResponse, error)
SearchTrialProceedingsDownload(ctx, req DownloadRequest) ([]byte, error)

// Trial Decisions
SearchTrialDecisions(ctx, query string, offset, limit int) (*DecisionDataResponse, error)
GetTrialDecision(ctx, documentIdentifier string) (*DecisionDataResponse, error)
GetTrialDecisionsByTrialNumber(ctx, trialNumber string) (*DecisionDataResponse, error)
SearchTrialDecisionsDownload(ctx, req DownloadRequest) ([]byte, error)

// Trial Documents
SearchTrialDocuments(ctx, query string, offset, limit int) (*DocumentDataResponse, error)
GetTrialDocument(ctx, documentIdentifier string) (*DocumentDataResponse, error)
GetTrialDocumentsByTrialNumber(ctx, trialNumber string) (*DocumentDataResponse, error)
SearchTrialDocumentsDownload(ctx, req DownloadRequest) ([]byte, error)

// Appeal Decisions
SearchAppealDecisions(ctx, query string, offset, limit int) (*AppealDecisionDataResponse, error)
GetAppealDecision(ctx, documentIdentifier string) (*AppealDecisionDataResponse, error)
GetAppealDecisionsByAppealNumber(ctx, appealNumber string) (*AppealDecisionDataResponse, error)
SearchAppealDecisionsDownload(ctx, req DownloadRequest) ([]byte, error)

// Interference Decisions
SearchInterferenceDecisions(ctx, query string, offset, limit int) (*InterferenceDecisionDataResponse, error)
GetInterferenceDecision(ctx, documentIdentifier string) (*InterferenceDecisionDataResponse, error)
GetInterferenceDecisionsByNumber(ctx, interferenceNumber string) (*InterferenceDecisionDataResponse, error)
SearchInterferenceDecisionsDownload(ctx, req PatentDownloadRequest) ([]byte, error)
Office Action APIs (8 endpoints)

These use the DSAPI pattern (form-encoded POST with Lucene/Solr queries). Same API key as the main ODP API.

// Office Action Text Retrieval
SearchOfficeActions(ctx, criteria string, start, rows int) (*DSAPIResponse, error)
GetOfficeActionFields(ctx) (*DSAPIFieldsResponse, error)

// Office Action Citations (Forms PTO-892 & PTO-1449)
SearchOfficeActionCitations(ctx, criteria string, start, rows int) (*DSAPIResponse, error)
GetOfficeActionCitationFields(ctx) (*DSAPIFieldsResponse, error)

// Office Action Rejections (101, 102, 103, 112, DP)
SearchOfficeActionRejections(ctx, criteria string, start, rows int) (*DSAPIResponse, error)
GetOfficeActionRejectionFields(ctx) (*DSAPIFieldsResponse, error)

// Enriched Citations (AI/ML extracted from office actions)
SearchEnrichedCitations(ctx, criteria string, start, rows int) (*DSAPIResponse, error)
GetEnrichedCitationFields(ctx) (*DSAPIFieldsResponse, error)

Office Action APIs use Lucene query syntax:

// Search by patent application number
result, err := client.SearchOfficeActionRejections(ctx, "patentApplicationNumber:12190351", 0, 10)

// Search with boolean operators
result, err := client.SearchOfficeActions(ctx, "hasRej103:1 AND groupArtUnitNumber:1713", 0, 10)

// Get available fields
fields, err := client.GetOfficeActionRejectionFields(ctx)
fmt.Printf("Searchable fields: %v\n", fields.Fields)
TSDR (Trademark Status & Document Retrieval) API

Separate server (tsdrapi.uspto.gov) and API key. Requires TSDRAPIKey in config, sent in the USPTO-API-KEY header.

config := odp.DefaultConfig()
config.APIKey = "your-odp-key"
config.TSDRAPIKey = "your-tsdr-key"  // from https://account.uspto.gov/profile/api-manager
client, err := odp.NewClient(config)

// Get trademark case status (raw XML response)
xmlResp, err := client.GetTrademarkStatus(ctx, "97123456")

// Get trademark case status (JSON via content negotiation)
status, err := client.GetTrademarkStatusJSON(ctx, "97123456")
fmt.Printf("Trademarks: %d\n", len(status.Trademarks))

// Get document list (XML)
docs, err := client.GetTrademarkDocumentsXML(ctx, "97123456")

// Get info about a specific document (XML) - docID format: {TypeCode}{YYYYMMDD}
info, err := client.GetTrademarkDocumentInfo(ctx, "97123456", "NOA20230322")

// Download a document as PDF
var buf bytes.Buffer
client.DownloadTrademarkDocument(ctx, "97123456", "NOA20230322", &buf)

// Get last update time
update, err := client.GetTrademarkLastUpdate(ctx, "97123456")

// Multi-status lookup
result, err := client.GetTrademarkMultiStatus(ctx, "sn", []string{"97123456", "97654321"})
Patent number normalization

The library handles various patent number formats and automatically resolves them to application numbers:

// GetPatent accepts any patent number format
doc, err := client.GetPatent(ctx, "US 11,646,472 B2")  // Grant number
doc, err := client.GetPatent(ctx, "17/248,024")        // Application number
doc, err := client.GetPatent(ctx, "US20250087686A1")   // Publication number

// For other methods, resolve to application number first
appNumber, err := client.ResolvePatentNumber(ctx, "US 11,646,472 B2")
// appNumber = "17248024" (the actual application number)

// Low-level normalization (formatting only, doesn't resolve)
pn, err := odp.NormalizePatentNumber("US 11,646,472 B2")
fmt.Println(pn.Type)                  // PatentNumberTypeGrant
fmt.Println(pn.Normalized)            // "11646472" (normalized, not application number!)
fmt.Println(pn.FormatAsGrant())       // "11,646,472"

Note: Grant and publication numbers are not the same as application numbers. The library uses the search API to resolve grant/publication numbers to their corresponding application numbers.

Supported formats:

  • Applications: 17248024, 17/248,024, US 17/248,024
  • Grants: 11646472, 11,646,472, US 11,646,472 B2
  • Publications: 20250087686, US20250087686A1 (kind code preserved when supplied: A2, A9, ...)
  • PCT: PCTUS2025058371 (15-char API form), PCT/US2025/058371 (17-char display), PCTUS0719317 (12-char legacy). Use pn.FormatAsPCT() for the display form.

Note: 8-digit numbers (like 11646472) are ambiguous - they could be either grant or application numbers. Use formatting (commas, kind codes) to disambiguate.

XML full text retrieval

Parse full patent text (ICE DTD 4.6/4.7):

doc, err := client.GetPatentXML(ctx, "US 11,646,472 B2")

title := doc.GetTitle()
abstract := doc.GetAbstract().ExtractAbstractText()
claims := doc.GetClaims().ExtractAllClaimsTextFormatted()
description := doc.GetDescription().ExtractDescriptionText()

Advanced usage:

// Get XML URL and type
xmlURL, docType, err := client.GetXMLURLForApplication(ctx, "17248024")

// Download with type hint
doc, err := client.DownloadXMLWithType(ctx, xmlURL, docType)

// Parse raw XML
data := []byte(/* XML content */)
doc, err = odp.ParseGrantXML(data)  // or ParseApplicationXML
Configuration
config := &odp.Config{
    BaseURL:    "https://api.uspto.gov", // Default
    APIKey:     "your-api-key",
    UserAgent:  "YourApp/1.0",
    MaxRetries: 3,                       // Retry failed requests
    RetryDelay: 1 * time.Second,         // Base backoff between retries
    Timeout:    30 * time.Second,        // Request timeout
    MaxRetryAfter: 60 * time.Second,     // Longest Retry-After the client will honor

    // Office Action DSAPI host (defaults to the ODP host)
    OABaseURL:  "https://api.uspto.gov", // Default (Office Action endpoints on the ODP host)

    // TSDR (optional - separate server and API key)
    TSDRAPIKey: "your-tsdr-key",         // From https://account.uspto.gov/profile/api-manager
    TSDRBaseURL: "https://tsdrapi.uspto.gov", // Default
}

client, err := odp.NewClient(config)

DefaultConfig() fills in sane defaults; override only the fields you need.

Error handling

Non-2xx responses surface as *APIError, carrying the status code, a message, and a truncated response body for debugging. Use errors.As to inspect them:

results, err := client.SearchPatents(ctx, query, 0, 10)
if err != nil {
    var apiErr *odp.APIError
    if errors.As(err, &apiErr) {
        fmt.Println("status:", apiErr.StatusCode)
        fmt.Println("detail:", apiErr.Detail()) // message + server body
        if apiErr.IsRetryable() {               // 429 or 5xx
            // back off and retry, or let the client's own retry handle it
        }
    }
    return err
}

On HTTP 429 the client honors the Retry-After header (capped by Config.MaxRetryAfter, default 60s) instead of its exponential backoff. When the server asks for a longer wait than the cap, the request fails with a non-retryable *APIError so the caller decides rather than the client blocking.

Testing

make test    # unit tests with the race detector
make lint    # gofmt + go vet

Integration tests require USPTO_API_KEY (and optionally USPTO_TSDR_API_KEY):

export USPTO_API_KEY=your-odp-key
export USPTO_TSDR_API_KEY=your-tsdr-key  # from https://account.uspto.gov/profile/api-manager

make test-integration

Swagger processing

Source files

The USPTO ODP API specification is distributed as multiple YAML files with $ref references between them. The originals are downloaded from USPTO ODP Swagger and stored in swagger/:

swagger/
  swagger.yaml                  # Main ODP API spec (Patent, Bulk, Petition)
  odp-common-base.yaml          # Shared type definitions
  trial-proceedings.yaml        # PTAB trial proceedings
  trial-decisions.yaml          # PTAB trial decisions
  trial-documents.yaml          # PTAB trial documents
  trial-appeal-decisions.yaml   # PTAB appeal decisions
  trial-interferences.yaml      # PTAB interference decisions
  trial-common.yaml             # Shared PTAB types
  oa-text-retrieval.yaml        # Office Action Text Retrieval
  oa-citations.yaml             # Office Action Citations
  oa-rejections.yaml            # Office Action Rejections
  oa-enriched-citations.yaml    # Enriched Citations
  tsdr-swagger.json             # TSDR (Trademark) API

Do not edit files in swagger/ - these are the original USPTO specifications.

Code generation

The cmd/gen tool (pure Go, no external dependencies) bundles and fixes the specs:

go run ./cmd/gen
  1. Bundles ODP + PTAB YAML, resolving $ref -> swagger_fixed.yaml -> generated/
  2. Bundles the 4 Office Action specs -> swagger_oa_fixed.yaml -> generated/oa/
  3. Copies the TSDR spec -> swagger_tsdr_fixed.json -> generated/tsdr/
  4. Applies fixes for mismatches between the specs and actual API responses
Fixes applied

The USPTO swagger has several mismatches with actual API responses:

Type corrections:

  • frameNumber, reelNumber: string -> integer (API returns numbers)
  • documentNumber: string -> integer (PTAB API returns numbers)
  • Error response code: integer -> string (API returns "404", not 404)

Structure fixes:

  • petitionIssueConsideredTextBag: array of objects -> array of strings
  • correspondenceAddress: array -> object (Assignment API returns an object)
  • DecisionData.statuteAndRuleBag, issueTypeBag: string -> array
  • GetPatentAssignment.assignmentBag: single object -> array

Field-name fixes:

  • InterferenceDecisionRecord.decisionDocumentData -> documentData
  • DecisionDataResponse.patentTrialDecisionDataBag -> patentTrialDocumentDataBag (the trial-decisions search returns the array under patentTrialDocumentDataBag; without the fix the slice silently unmarshals to nil while count parses fine)

Format fixes:

  • Removed format: date-time from fields returning non-RFC3339 values (e.g. lastModifiedDateTime returns "2025-11-26T23:58:00" without a timezone)
  • Removed format: date from fields that return datetimes or non-ISO dates (e.g. fileReleaseDate returns "2025-09-23 00:57:53")

Endpoint fixes:

  • Removed /api/v1/patent/applications/text-to-search (defined but has no operations)

Office Action (DSAPI) fixes:

  • Removed phantom path parameters (dataset, version declared in: path but the paths are static)
  • Made operationId values unique across the four bundled specs (all four used identical IDs)
  • The Office Action APIs are served from the ODP host (https://api.uspto.gov, the route Office Action APIs to ODP migration) under /api/v1/patent/oa/...; override the host with Config.OABaseURL if needed.

TSDR fixes:

  • Fixed the protocol-relative server URL (//tsdrapi.uspto.gov/ -> https://tsdrapi.uspto.gov)
  • GetDocumentInfoXml / GetCaseDocsInfoXml return 406 with Accept: application/json (content negotiation is unsupported despite XML/JSON paths in the spec)
  • Removed format: date-time / format: date from 64 fields - the API returns inconsistent date formats that break time.Time parsing in generated code

Upstream bugs worked around:

  • trial-appeal-decisions.yaml: appelantData -> appellantData, realPartyName -> realPartyInInterestName, techCenterNumber -> technologyCenterNumber, requestorData -> thirdPartyRequesterData, documentTypeCategory -> documentTypeDescriptionText, downloadURI -> fileDownloadURI
  • trial-common.yaml: downloadURI -> fileDownloadURI, statuteAndRuleBag / issueTypeBag string -> array, documentNumber string -> integer

Part of the patent.dev open-source patent data ecosystem:

  • epo-ops - EPO Open Patent Services client (bibliographic, full text, families, legal status, images)
  • epo-bdds - EPO Bulk Data Distribution Service client (DOCDB, INPADOC, EP full text)
  • dpma-connect-plus - DPMA Connect Plus client (patents, designs, trademarks)

The bulk-file-loader uses these libraries for automated patent data downloads.

License

MIT - Funktionslust GmbH / patent.dev.

Documentation

Overview

Package odp provides a Go client for the USPTO Open Data Portal (ODP), covering patent and trademark application data, the Office Action APIs, and TSDR (Trademark Status & Document Retrieval).

Index

Examples

Constants

View Source
const DefaultMaxRetryAfter = 60 * time.Second

DefaultMaxRetryAfter is the cap applied when Config.MaxRetryAfter is zero.

View Source
const DefaultOABaseURL = "https://api.uspto.gov"

DefaultOABaseURL is the ODP host serving the Office Action APIs.

View Source
const DefaultUserAgent = "uspto-odp/" + Version + " (patent.dev; +https://github.com/patent-dev/uspto-odp)"

DefaultUserAgent identifies this library in outbound requests. The product token is the library name so the request is grepable in USPTO logs by either the library or the project that maintains it. Consumers are encouraged to prepend their own identity, e.g. "MyApp/2.3 uspto-odp/1.5".

View Source
const Version = "1.6.10"

Version is the library version. Bumped per release; surfaces through the default User-Agent.

Variables

This section is empty.

Functions

func DSAPIApplicationCriteria added in v1.4.0

func DSAPIApplicationCriteria(appNum string) string

DSAPIApplicationCriteria builds a Lucene criteria string for querying by application number. Returns "*:*" (match all) for empty input.

func Int32Ptr

func Int32Ptr(i int32) *int32

Int32Ptr returns a pointer to an int32

func IntPtr

func IntPtr(i int) *int

IntPtr returns a pointer to an int

func NormalizeDSAPIApplicationNumber added in v1.4.0

func NormalizeDSAPIApplicationNumber(appNum string) string

NormalizeDSAPIApplicationNumber normalizes a US application number for use in DSAPI Lucene queries. The DSAPI expects digits only (e.g., "17248024"). Accepts formats like "17/248,024", "US17/248,024", "US 17248024", "17248024". Returns empty string for empty input.

func StringPtr

func StringPtr(s string) *string

StringPtr returns a pointer to a string

Types

type APIError added in v1.2.1

type APIError struct {
	StatusCode int
	Message    string
	Body       string // server response body for debugging
	// RetryAfter, when non-zero, is the duration the server asked the client
	// to wait before retrying (parsed from the Retry-After header).
	RetryAfter time.Duration
	// Empty is set when the server returned a success status with no body. USPTO
	// services (notably TSDR) do this when degraded; it is treated as transient.
	Empty bool
}

APIError represents an error returned by the USPTO API with status code

func (*APIError) Detail added in v1.4.0

func (e *APIError) Detail() string

Detail returns the error message with the server response body, if available.

func (*APIError) Error added in v1.2.1

func (e *APIError) Error() string

func (*APIError) IsRetryable added in v1.2.1

func (e *APIError) IsRetryable() bool

IsRetryable returns true for transient conditions: HTTP 429, 5xx, or an empty body on a success status (a degraded-service symptom that often clears on a retry). The Retry-After cap is a *client* policy, enforced by retryableRequest, not by the error itself.

type Abstract added in v1.1.0

type Abstract struct {
	ID         string      `xml:"id,attr"`
	Lang       string      `xml:"lang,attr"`
	Paragraphs []Paragraph `xml:"p"`
}

Abstract represents the patent abstract

func (*Abstract) ExtractAbstractText added in v1.1.0

func (a *Abstract) ExtractAbstractText() string

ExtractAbstractText extracts full text from the abstract

type AdjustmentResponse added in v1.3.0

type AdjustmentResponse struct {
	ApplicationNumber   string
	TotalAdjustmentDays int
	ADelays             int
	BDelays             int
	CDelays             int
}

AdjustmentResponse contains patent term adjustment data.

type AmbiguousPatentNumberError added in v1.6.2

type AmbiguousPatentNumberError struct {
	Input      string
	Candidates []PatentCandidate
}

AmbiguousPatentNumberError is returned when a bare number resolves to both a grant and a different application. It carries the candidates so the caller can ask the user which one they meant instead of guessing.

func (*AmbiguousPatentNumberError) Error added in v1.6.2

type Applicant added in v1.5.0

type Applicant struct {
	ApplicantNameText        string
	FirstName                string
	MiddleName               string
	LastName                 string
	NamePrefix               string
	NameSuffix               string
	PreferredName            string
	CountryCode              string
	CorrespondenceAddressBag []CorrespondenceAddress
}

Applicant identifies a party listed as an applicant on the application.

type Assignee added in v1.5.0

type Assignee struct {
	Name             string
	City             string
	GeographicRegion string
	PostalCode       string
	CountryName      string
}

Assignee is the receiving party on an assignment recordation. The USPTO schema carries the assignee's mailing address; ExecutionDate is not part of the assignee record.

type AssignmentEntry added in v1.3.0

type AssignmentEntry struct {
	Assignors           []Assignor
	Assignees           []Assignee
	RecordedDate        string
	Conveyance          string
	ReelFrame           string
	MailedDate          string
	ReceivedDate        string
	DocumentLocationURI string
}

AssignmentEntry represents a single patent assignment record.

type AssignmentResponse added in v1.3.0

type AssignmentResponse struct {
	ApplicationNumber string
	Assignments       []AssignmentEntry
}

AssignmentResponse contains patent assignment/ownership data.

type Assignor added in v1.5.0

type Assignor struct {
	Name          string
	ExecutionDate string
}

Assignor is a transferring party on an assignment recordation. The USPTO schema only carries name + execution date for assignors (no address).

type AssociatedDocumentsResponse added in v1.4.0

type AssociatedDocumentsResponse struct {
	ApplicationNumber     string
	GrantDocumentMetaData *generated.GrantFileMetaData
	PgpubDocumentMetaData *generated.PGPubFileMetaData
}

AssociatedDocumentsResponse contains patent grant and publication XML file metadata.

type Bibliography added in v1.1.0

type Bibliography struct {
	PublicationReference *DocumentID `xml:"publication-reference>document-id"`
	ApplicationReference *DocumentID `xml:"application-reference>document-id"`
	InventionTitle       []Text      `xml:"invention-title"`
}

Bibliography contains bibliographic data

type Bold added in v1.1.0

type Bold struct {
	Text string `xml:",chardata"`
}

Bold represents bold text

type Claim added in v1.1.0

type Claim struct {
	ID        string      `xml:"id,attr"`
	Num       string      `xml:"num,attr"`
	ClaimText []ClaimText `xml:"claim-text"`
}

Claim represents a single claim with possibly nested claim-text

func (*Claim) ExtractClaimText added in v1.1.0

func (c *Claim) ExtractClaimText() string

ExtractClaimText returns the full text of a claim with internal runs of whitespace collapsed to single spaces. Inline references (<claim-ref>) and nested claim-text are already flattened into each top-level ClaimText.Text during parsing, so no recursion is needed here.

type ClaimText added in v1.1.0

type ClaimText struct {
	ID           string
	Text         string
	NestedClaims []ClaimText
}

ClaimText represents the text of a claim, including any nested <claim-text>.

A <claim-text> element mixes character data with inline child elements - most importantly <claim-ref>, which carries a dependent claim's reference to its parent (e.g. "claim 1" in "The system according to <claim-ref>claim 1</claim-ref>, ..."). Go's struct-tag ",chardata" mapping concatenates only the character data directly under the element and silently drops the text of child elements, which would render that claim as "The system according to , ...". ClaimText is therefore parsed with a custom UnmarshalXML (see below) that walks tokens in document order.

Text holds the fully flattened text of this element and all of its descendants (inline references and nested claim-text included). NestedClaims preserves the structural tree for callers that need the hierarchy.

func (*ClaimText) UnmarshalXML added in v1.6.2

func (ct *ClaimText) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML flattens a <claim-text> element into its complete, in-document-order text. It is the encoding/xml equivalent of itertext(): character data, the inner text of inline elements such as <claim-ref> and <figref>, and the text of nested <claim-text> are concatenated in the order they appear. Whitespace is preserved here as-is; callers collapse it at extraction time (see Claim.ExtractClaimText).

type Claims added in v1.1.0

type Claims struct {
	ID        string  `xml:"id,attr"`
	Lang      string  `xml:"lang,attr"`
	ClaimList []Claim `xml:"claim"`
}

Claims represents the claims section

func (*Claims) ExtractAllClaimsText added in v1.1.0

func (c *Claims) ExtractAllClaimsText() []string

ExtractAllClaimsText extracts text from all claims

func (*Claims) ExtractAllClaimsTextFormatted added in v1.1.0

func (c *Claims) ExtractAllClaimsTextFormatted() string

ExtractAllClaimsTextFormatted returns formatted claim text with claim numbers

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the main USPTO ODP API client

func NewClient

func NewClient(config *Config) (*Client, error)

NewClient creates a new USPTO ODP API client

Example
package main

import (
	"fmt"

	odp "github.com/patent-dev/uspto-odp"
)

func main() {
	// The same API key covers the Patent, PTAB, Petition, Bulk Data, and
	// Office Action APIs; TSDR uses a separate key when set.
	config := odp.DefaultConfig()
	config.APIKey = "your-api-key"

	client, err := odp.NewClient(config)
	if err != nil {
		panic(err)
	}
	fmt.Println(client != nil)
}
Output:
true

func (*Client) DownloadBulkFile added in v1.0.0

func (c *Client) DownloadBulkFile(ctx context.Context, fileDownloadURI string, w io.Writer) error

DownloadBulkFile downloads a file directly using the FileDownloadURI from the API response

func (*Client) DownloadBulkFileWithProgress added in v1.0.0

func (c *Client) DownloadBulkFileWithProgress(ctx context.Context, fileDownloadURI string, w io.Writer, progress func(bytesComplete int64, bytesTotal int64)) error

DownloadBulkFileWithProgress downloads a bulk dataset file using its FileDownloadURI, reporting progress through the optional callback. See streamDownload for the retry and mid-stream-failure semantics.

func (*Client) DownloadPatentDocument added in v1.6.3

func (c *Client) DownloadPatentDocument(ctx context.Context, downloadURL string, w io.Writer) error

DownloadPatentDocument streams a patent file-wrapper document to w. downloadURL is a DownloadOptionBag.DownloadUrl returned by GetPatentDocuments (the documents are served as PDF). Covers applicant remarks, claim amendments, IDS, examiner's amendments, and the rest of the file wrapper.

func (*Client) DownloadTrademarkDocument added in v1.4.0

func (c *Client) DownloadTrademarkDocument(ctx context.Context, serialNumber, docID string, w io.Writer) error

DownloadTrademarkDocument downloads a trademark document as PDF. When retries are enabled, the entire document is buffered in memory before writing to w, so partial writes from transient failures don't corrupt the output. The final copy to w is not retried - if w fails (e.g., closed file), the data is lost.

func (*Client) DownloadXML added in v1.1.0

func (c *Client) DownloadXML(ctx context.Context, url string) (*XMLDocument, error)

DownloadXML downloads and parses an XML document from a given URL. The URL must be a FileLocationURI from the USPTO API (see GetXMLURLForApplication); arbitrary hosts are rejected so the API key is never sent elsewhere. If you know the document type, use DownloadXMLWithType for better performance

func (*Client) DownloadXMLWithType added in v1.1.0

func (c *Client) DownloadXMLWithType(ctx context.Context, url string, expectedType DocumentType) (*XMLDocument, error)

DownloadXMLWithType downloads and parses an XML document with a known type hint. The URL is validated like the other authenticated download paths (it must be a FileLocationURI under the configured host) and fetched through streamDownload, so typed errors, Retry-After handling, and retries all apply.

func (*Client) GetAppealDecision added in v1.2.0

func (c *Client) GetAppealDecision(ctx context.Context, documentIdentifier string) (*generated.AppealDecisionDataResponse, error)

GetAppealDecision retrieves a specific PTAB appeal decision by document identifier

func (*Client) GetAppealDecisionsByAppealNumber added in v1.2.0

func (c *Client) GetAppealDecisionsByAppealNumber(ctx context.Context, appealNumber string) (*generated.AppealDecisionDataResponse, error)

GetAppealDecisionsByAppealNumber retrieves all decisions for a specific appeal number

func (*Client) GetBulkProduct added in v1.0.0

func (c *Client) GetBulkProduct(ctx context.Context, productID string) (*generated.BdssResponseProductBag, error)

GetBulkProduct retrieves a specific bulk data product

func (*Client) GetEnrichedCitationFields added in v1.4.0

func (c *Client) GetEnrichedCitationFields(ctx context.Context) (*DSAPIFieldsResponse, error)

GetEnrichedCitationFields returns the list of searchable fields for the Enriched Citation API.

func (*Client) GetInterferenceDecision added in v1.2.0

func (c *Client) GetInterferenceDecision(ctx context.Context, documentIdentifier string) (*generated.InterferenceDecisionDataResponse, error)

GetInterferenceDecision retrieves a specific PTAB interference decision by document identifier

func (*Client) GetInterferenceDecisionsByNumber added in v1.2.0

func (c *Client) GetInterferenceDecisionsByNumber(ctx context.Context, interferenceNumber string) (*generated.InterferenceDecisionDataResponse, error)

GetInterferenceDecisionsByNumber retrieves all decisions for a specific interference number

func (*Client) GetOfficeActionCitationFields added in v1.4.0

func (c *Client) GetOfficeActionCitationFields(ctx context.Context) (*DSAPIFieldsResponse, error)

GetOfficeActionCitationFields returns the list of searchable fields for the OA Citations API.

func (*Client) GetOfficeActionFields added in v1.4.0

func (c *Client) GetOfficeActionFields(ctx context.Context) (*DSAPIFieldsResponse, error)

GetOfficeActionFields returns the list of searchable fields for the Office Action Text API.

func (*Client) GetOfficeActionRejectionFields added in v1.4.0

func (c *Client) GetOfficeActionRejectionFields(ctx context.Context) (*DSAPIFieldsResponse, error)

GetOfficeActionRejectionFields returns the list of searchable fields for the OA Rejections API.

func (*Client) GetPatent added in v1.0.0

func (c *Client) GetPatent(ctx context.Context, patentNumber string) (*generated.PatentDataResponse, error)

GetPatent retrieves patent data by application, grant, or publication number. It resolves leniently (no grant-vs-application ambiguity probing) because it is commonly called with an already-resolved application number; callers that need to disambiguate raw user input should call ResolvePatentNumber first.

func (*Client) GetPatentAdjustment added in v1.0.0

func (c *Client) GetPatentAdjustment(ctx context.Context, applicationNumber string) (*AdjustmentResponse, error)

GetPatentAdjustment retrieves patent term adjustment data.

func (*Client) GetPatentAssignment added in v1.0.0

func (c *Client) GetPatentAssignment(ctx context.Context, applicationNumber string) (*AssignmentResponse, error)

GetPatentAssignment retrieves patent assignment data.

func (*Client) GetPatentAssociatedDocuments added in v1.0.0

func (c *Client) GetPatentAssociatedDocuments(ctx context.Context, applicationNumber string) (*AssociatedDocumentsResponse, error)

GetPatentAssociatedDocuments retrieves patent grant and publication XML file metadata.

func (*Client) GetPatentAttorney added in v1.0.0

func (c *Client) GetPatentAttorney(ctx context.Context, applicationNumber string) (*generated.RecordAttorney, error)

GetPatentAttorney retrieves patent attorney information.

func (*Client) GetPatentContinuity added in v1.0.0

func (c *Client) GetPatentContinuity(ctx context.Context, applicationNumber string) (*ContinuityResponse, error)

GetPatentContinuity retrieves patent continuity data.

func (*Client) GetPatentDocuments added in v1.0.0

func (c *Client) GetPatentDocuments(ctx context.Context, applicationNumber string) (*generated.DocumentBag, error)

GetPatentDocuments retrieves patent documents list

func (*Client) GetPatentForeignPriority added in v1.0.0

func (c *Client) GetPatentForeignPriority(ctx context.Context, applicationNumber string) (*ForeignPriorityResponse, error)

GetPatentForeignPriority retrieves foreign priority data.

func (*Client) GetPatentMetaData added in v1.0.0

func (c *Client) GetPatentMetaData(ctx context.Context, applicationNumber string) (*MetaDataResponse, error)

GetPatentMetaData retrieves patent metadata (status, filing date, examiner, classification, etc.).

func (*Client) GetPatentTransactions added in v1.0.0

func (c *Client) GetPatentTransactions(ctx context.Context, applicationNumber string) (*TransactionsResponse, error)

GetPatentTransactions retrieves patent transaction history.

func (*Client) GetPatentXML added in v1.1.0

func (c *Client) GetPatentXML(ctx context.Context, patentNumber string) (*XMLDocument, error)

GetPatentXML retrieves and parses the XML document for a patent Accepts application numbers, grant numbers, or publication numbers

func (*Client) GetPetitionDecision added in v1.0.0

func (c *Client) GetPetitionDecision(ctx context.Context, recordID string, includeDocuments bool) (*generated.PetitionDecisionIdentifierResponseBag, error)

GetPetitionDecision retrieves a specific petition decision.

includeDocuments=true asks the API to attach the decision's documents as documentBag on each record. As of 2026-08-08 the live API returns HTTP 500 for every record when the parameter is true (USPTO defect, reproduced across old and new records); pass false and fetch the decision PDFs through the application's file wrapper (GetPatentDocuments, document code PETDEC) until USPTO fixes the endpoint.

func (*Client) GetStatusCodes added in v1.0.0

func (c *Client) GetStatusCodes(ctx context.Context) (*generated.StatusCodeSearchResponse, error)

GetStatusCodes retrieves all patent status codes

func (*Client) GetTrademarkDocumentInfo added in v1.4.0

func (c *Client) GetTrademarkDocumentInfo(ctx context.Context, serialNumber, docID string) ([]byte, error)

GetTrademarkDocumentInfo retrieves info about a specific document within a trademark case. The docID format is {DocumentTypeCode}{YYYYMMDD}, e.g., "NOA20230322". Obtain valid type codes and dates from the GetTrademarkDocumentsXML listing. Returns raw XML because this endpoint does not support JSON content negotiation.

func (*Client) GetTrademarkDocumentsXML added in v1.4.0

func (c *Client) GetTrademarkDocumentsXML(ctx context.Context, serialNumber string) ([]byte, error)

GetTrademarkDocumentsXML retrieves the document list for a trademark case as raw XML.

func (*Client) GetTrademarkLastUpdate added in v1.4.0

func (c *Client) GetTrademarkLastUpdate(ctx context.Context, serialNumber string) (*tsdrgen.CaseUpdateInfoList, error)

GetTrademarkLastUpdate retrieves the last update time for a trademark case.

func (*Client) GetTrademarkMultiStatus added in v1.4.0

func (c *Client) GetTrademarkMultiStatus(ctx context.Context, pType string, numbers []string) (*tsdrgen.TransactionBag, error)

GetTrademarkMultiStatus retrieves status for multiple trademarks by type. Type can be "sn" (serial number), "rn" (registration number), or "in" (international number).

func (*Client) GetTrademarkStatus added in v1.4.0

func (c *Client) GetTrademarkStatus(ctx context.Context, serialNumber string) (*tsdrgen.LoadXMLResponse, error)

GetTrademarkStatus retrieves the full trademark case status for a serial number. The serial number must be 8 digits (e.g., "97123456"). Returns the raw XML response wrapper from the generated client.

func (*Client) GetTrademarkStatusJSON added in v1.4.0

func (c *Client) GetTrademarkStatusJSON(ctx context.Context, serialNumber string) (*TSDRStatusResponse, error)

GetTrademarkStatusJSON retrieves trademark case status as parsed JSON. Uses content negotiation to request JSON instead of the default XML.

func (*Client) GetTrialDecision added in v1.2.0

func (c *Client) GetTrialDecision(ctx context.Context, documentIdentifier string) (*generated.DecisionDataResponse, error)

GetTrialDecision retrieves a specific PTAB trial decision by document identifier

func (*Client) GetTrialDecisionsByTrialNumber added in v1.2.0

func (c *Client) GetTrialDecisionsByTrialNumber(ctx context.Context, trialNumber string) (*generated.DecisionDataResponse, error)

GetTrialDecisionsByTrialNumber retrieves all decisions for a specific trial number

func (*Client) GetTrialDocument added in v1.2.0

func (c *Client) GetTrialDocument(ctx context.Context, documentIdentifier string) (*generated.DocumentDataResponse, error)

GetTrialDocument retrieves a specific PTAB trial document by document identifier

func (*Client) GetTrialDocumentsByTrialNumber added in v1.2.0

func (c *Client) GetTrialDocumentsByTrialNumber(ctx context.Context, trialNumber string) (*generated.DocumentDataResponse, error)

GetTrialDocumentsByTrialNumber retrieves all documents for a specific trial number

func (*Client) GetTrialProceeding added in v1.2.0

func (c *Client) GetTrialProceeding(ctx context.Context, trialNumber string) (*generated.ProceedingDataResponse, error)

GetTrialProceeding retrieves a specific PTAB trial proceeding by trial number

func (*Client) GetXMLURLForApplication added in v1.1.0

func (c *Client) GetXMLURLForApplication(ctx context.Context, patentNumber string) (string, DocumentType, error)

GetXMLURLForApplication retrieves the XML URL and document type for a patent. Checks grant metadata first, then pre-grant publication (pgpub) metadata.

func (*Client) ResolvePatentNumber added in v1.1.0

func (c *Client) ResolvePatentNumber(ctx context.Context, patentNumber string) (string, error)

ResolvePatentNumber resolves any patent number format (application, grant, or publication) to its application number, searching the USPTO API when necessary. A bare 8-digit number with no kind code is ambiguous (grant vs application); this entry point probes both interpretations and returns an *AmbiguousPatentNumberError when they differ, so a caller acting on user input can surface a "did you mean" choice. Call this with raw user input. To resolve a number you already know to be an application number, see resolveApplicationNumberLenient.

func (*Client) SearchAppealDecisions added in v1.2.0

func (c *Client) SearchAppealDecisions(ctx context.Context, query string, offset, limit int) (*generated.AppealDecisionDataResponse, error)

SearchAppealDecisions searches PTAB appeal decisions

func (*Client) SearchAppealDecisionsDownload added in v1.2.0

func (c *Client) SearchAppealDecisionsDownload(ctx context.Context, req generated.DownloadRequest) ([]byte, error)

SearchAppealDecisionsDownload downloads appeal decisions search results

func (*Client) SearchBulkProducts added in v1.0.0

func (c *Client) SearchBulkProducts(ctx context.Context, query string, offset, limit int) (*generated.BdssResponseBag, error)

SearchBulkProducts searches for bulk data products

func (*Client) SearchEnrichedCitations added in v1.4.0

func (c *Client) SearchEnrichedCitations(ctx context.Context, criteria string, start, rows int) (*DSAPIResponse, error)

SearchEnrichedCitations searches enriched citation metadata records. Uses AI/ML to extract statutes, rejected claims, prior art references from office actions.

func (*Client) SearchInterferenceDecisions added in v1.2.0

func (c *Client) SearchInterferenceDecisions(ctx context.Context, query string, offset, limit int) (*generated.InterferenceDecisionDataResponse, error)

SearchInterferenceDecisions searches PTAB interference decisions

func (*Client) SearchInterferenceDecisionsDownload added in v1.2.0

func (c *Client) SearchInterferenceDecisionsDownload(ctx context.Context, req generated.PatentDownloadRequest) ([]byte, error)

SearchInterferenceDecisionsDownload downloads interference decisions search results

func (*Client) SearchOfficeActionCitations added in v1.4.0

func (c *Client) SearchOfficeActionCitations(ctx context.Context, criteria string, start, rows int) (*DSAPIResponse, error)

SearchOfficeActionCitations searches office action citation records. Data covers Office Actions mailed from June 1, 2018 to 180 days prior to current date.

func (*Client) SearchOfficeActionRejections added in v1.4.0

func (c *Client) SearchOfficeActionRejections(ctx context.Context, criteria string, start, rows int) (*DSAPIResponse, error)

SearchOfficeActionRejections searches office action rejection records. Includes rejection types (101, 102, 103, 112, double patenting) and patent eligibility indicators.

func (*Client) SearchOfficeActions added in v1.4.0

func (c *Client) SearchOfficeActions(ctx context.Context, criteria string, start, rows int) (*DSAPIResponse, error)

SearchOfficeActions searches office action full-text records using Lucene query syntax. Criteria uses Lucene syntax (e.g., "patentApplicationNumber:16123456"). Use "*:*" or empty string to match all records.

func (*Client) SearchPatents added in v1.0.0

func (c *Client) SearchPatents(ctx context.Context, query string, offset, limit int) (*generated.PatentDataResponse, error)

SearchPatents searches for patent applications. It is the simple form of SearchPatentsWithOptions (query + pagination, no sort or field projection).

func (*Client) SearchPatentsDownload added in v1.0.0

func (c *Client) SearchPatentsDownload(ctx context.Context, req generated.PatentDownloadRequest) ([]byte, error)

SearchPatentsDownload downloads patent search results

func (*Client) SearchPatentsWithOptions added in v1.6.6

func (c *Client) SearchPatentsWithOptions(ctx context.Context, query string, offset, limit int, opts *PatentSearchOptions) (*generated.PatentDataResponse, error)

SearchPatentsWithOptions searches for patent applications with optional sort and field-projection refinements. A nil opts behaves exactly like SearchPatents.

func (*Client) SearchPetitions added in v1.0.0

func (c *Client) SearchPetitions(ctx context.Context, query string, offset, limit int) (*generated.PetitionDecisionResponseBag, error)

SearchPetitions searches for petition decisions

func (*Client) SearchPetitionsDownload added in v1.0.0

func (c *Client) SearchPetitionsDownload(ctx context.Context, req generated.PetitionDecisionDownloadRequest) ([]byte, error)

SearchPetitionsDownload downloads petition search results

func (*Client) SearchTrialDecisions added in v1.2.0

func (c *Client) SearchTrialDecisions(ctx context.Context, query string, offset, limit int) (*generated.DecisionDataResponse, error)

SearchTrialDecisions searches PTAB trial decisions

func (*Client) SearchTrialDecisionsDownload added in v1.2.0

func (c *Client) SearchTrialDecisionsDownload(ctx context.Context, req generated.DownloadRequest) ([]byte, error)

SearchTrialDecisionsDownload downloads trial decisions search results

func (*Client) SearchTrialDocuments added in v1.2.0

func (c *Client) SearchTrialDocuments(ctx context.Context, query string, offset, limit int) (*generated.DocumentDataResponse, error)

SearchTrialDocuments searches PTAB trial documents

func (*Client) SearchTrialDocumentsDownload added in v1.2.0

func (c *Client) SearchTrialDocumentsDownload(ctx context.Context, req generated.DownloadRequest) ([]byte, error)

SearchTrialDocumentsDownload downloads trial documents search results

func (*Client) SearchTrialProceedings added in v1.2.0

func (c *Client) SearchTrialProceedings(ctx context.Context, query string, offset, limit int) (*generated.ProceedingDataResponse, error)

SearchTrialProceedings searches PTAB trial proceedings

func (*Client) SearchTrialProceedingsDownload added in v1.2.0

func (c *Client) SearchTrialProceedingsDownload(ctx context.Context, req generated.DownloadRequest) ([]byte, error)

SearchTrialProceedingsDownload downloads trial proceedings search results

type Config

type Config struct {
	BaseURL    string
	APIKey     string
	UserAgent  string
	MaxRetries int
	RetryDelay time.Duration // base backoff between retries
	Timeout    time.Duration // request timeout for the underlying http.Client

	// MaxRetryAfter is the longest Retry-After the client will honor. If the
	// server requests a longer wait, the resulting *APIError reports
	// IsRetryable=false so the caller can decide. Zero means "use the
	// DefaultMaxRetryAfter constant".
	MaxRetryAfter time.Duration

	// OABaseURL is the host serving the Office Action APIs. Defaults to
	// the ODP host (https://api.uspto.gov); override to point elsewhere.
	OABaseURL string

	// TSDR (Trademark Status & Document Retrieval) - separate server + API key
	TSDRBaseURL string // defaults to "https://tsdrapi.uspto.gov"
	TSDRAPIKey  string // from https://account.uspto.gov/profile/api-manager
}

Config holds client configuration. Note: Timeout applies to all APIs (ODP, OA, TSDR) uniformly. If TSDR document downloads need a longer timeout, create a separate Client with a higher Timeout. For streaming file downloads (bulk datasets, XML documents, file-wrapper documents) Timeout bounds only the wait for response headers - not the body transfer - so large downloads are not cut off mid-stream. Use the context to bound the total transfer time.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns default configuration

type ContinuityChild added in v1.3.0

type ContinuityChild struct {
	ApplicationNumber string
	PatentNumber      string
	FilingDate        string
	Status            string
	RelationshipType  string
}

ContinuityChild represents a child application in a continuity chain.

type ContinuityParent added in v1.3.0

type ContinuityParent struct {
	ApplicationNumber string
	PatentNumber      string
	FilingDate        string
	Status            string
	RelationshipType  string
}

ContinuityParent represents a parent application in a continuity chain.

type ContinuityResponse added in v1.3.0

type ContinuityResponse struct {
	ApplicationNumber string
	Parents           []ContinuityParent
	Children          []ContinuityChild
}

ContinuityResponse contains patent continuity data (parent/child application chain).

type CorrespondenceAddress added in v1.5.0

type CorrespondenceAddress struct {
	NameLineOne           string
	NameLineTwo           string
	CityName              string
	CountryCode           string
	CountryName           string
	GeographicRegionCode  string
	GeographicRegionName  string
	PostalAddressCategory string
}

CorrespondenceAddress represents a single mailing-address record on an applicant or inventor.

type DSAPIFieldsResponse added in v1.4.0

type DSAPIFieldsResponse struct {
	APIKey              string   `json:"apiKey"`
	APIVersionNumber    string   `json:"apiVersionNumber"`
	APIURL              string   `json:"apiUrl"`
	APIDocumentationURL string   `json:"apiDocumentationUrl"`
	APIStatus           string   `json:"apiStatus"`
	FieldCount          int      `json:"fieldCount"`
	Fields              []string `json:"fields"`
	// LastDataUpdatedDate is the dataset's last-update timestamp. The API returns
	// a non-ISO datetime string (e.g. "2020-03-12 11:19:05.0"), kept as a string.
	LastDataUpdatedDate string `json:"lastDataUpdatedDate"`
}

DSAPIFieldsResponse is the response from a DSAPI /fields endpoint.

type DSAPIResponse added in v1.4.0

type DSAPIResponse struct {
	Response DSAPIResult `json:"response"`
}

DSAPIResponse is the response envelope from Office Action DSAPI endpoints. The DSAPI uses Solr/Lucene with dynamic schemas - each dataset (text, citations, rejections, enriched) has different fields per document. The Docs field uses []map[string]any because the field set is not fixed at compile time. Use the /fields endpoints (e.g., GetOfficeActionFields) to discover available fields.

type DSAPIResult added in v1.4.0

type DSAPIResult struct {
	NumFound int              `json:"numFound"`
	Start    int              `json:"start"`
	Docs     []map[string]any `json:"docs"`
}

DSAPIResult holds the search results from a DSAPI query.

type Description added in v1.1.0

type Description struct {
	ID         string      `xml:"id,attr"`
	Lang       string      `xml:"lang,attr"`
	Headings   []Heading   `xml:"heading"`
	Paragraphs []Paragraph `xml:"p"`
}

Description represents the detailed description section

func (*Description) ExtractDescriptionText added in v1.1.0

func (d *Description) ExtractDescriptionText() string

ExtractDescriptionText extracts full text from the description

type DocumentID added in v1.1.0

type DocumentID struct {
	Country   string `xml:"country"`
	DocNumber string `xml:"doc-number"`
	Kind      string `xml:"kind"`
	Date      string `xml:"date"`
}

DocumentID represents document identification

type DocumentType added in v1.1.0

type DocumentType int

DocumentType identifies the type of XML document

const (
	DocumentTypeUnknown DocumentType = iota
	DocumentTypeGrant
	DocumentTypeApplication
)

Document type values.

type DrawingsInfo added in v1.1.0

type DrawingsInfo struct {
	ID      string   `xml:"id,attr"`
	Figures []Figure `xml:"figure"`
}

DrawingsInfo contains drawing/figure information

type EntityStatus added in v1.5.0

type EntityStatus struct {
	BusinessEntityStatusCategory string
	SmallEntityStatusIndicator   *bool
}

EntityStatus indicates the applicant's fee-entity status.

type Figure added in v1.1.0

type Figure struct {
	ID  string `xml:"id,attr"`
	Img Image  `xml:"img"`
}

Figure represents a drawing figure

type ForeignPriorityClaim added in v1.5.0

type ForeignPriorityClaim struct {
	ApplicationNumber string
	FilingDate        string
	IPOfficeName      string
}

ForeignPriorityClaim represents a single foreign priority claim.

type ForeignPriorityResponse added in v1.5.0

type ForeignPriorityResponse struct {
	ApplicationNumber string
	Claims            []ForeignPriorityClaim
}

ForeignPriorityResponse contains foreign priority claims for an application.

type Heading added in v1.1.0

type Heading struct {
	ID    string `xml:"id,attr"`
	Level string `xml:"level,attr"`
	Text  string `xml:",chardata"`
}

Heading represents a section heading

type Image added in v1.1.0

type Image struct {
	ID         string `xml:"id,attr"`
	He         string `xml:"he,attr"`
	Wi         string `xml:"wi,attr"`
	File       string `xml:"file,attr"`
	Alt        string `xml:"alt,attr"`
	ImgContent string `xml:"img-content,attr"`
	ImgFormat  string `xml:"img-format,attr"`
}

Image represents an image reference

type Inventor added in v1.5.0

type Inventor struct {
	InventorNameText         string
	FirstName                string
	MiddleName               string
	LastName                 string
	NamePrefix               string
	NameSuffix               string
	PreferredName            string
	CountryCode              string
	CorrespondenceAddressBag []CorrespondenceAddress
}

Inventor identifies a party listed as an inventor on the application.

type Italic added in v1.1.0

type Italic struct {
	Text string `xml:",chardata"`
}

Italic represents italic text

type MetaDataResponse added in v1.5.0

type MetaDataResponse struct {
	ApplicationNumber                        string
	ApplicationConfirmationNumber            *int
	PatentNumber                             string
	InventionTitle                           string
	FilingDate                               string
	GrantDate                                string
	EffectiveFilingDate                      string
	EarliestPublicationNumber                string
	EarliestPublicationDate                  string
	ApplicationStatusCode                    *int
	ApplicationStatusDescriptionText         string
	ApplicationStatusDate                    string
	ApplicationTypeCategory                  string
	ApplicationTypeCode                      string
	ApplicationTypeLabelName                 string
	ExaminerNameText                         string
	GroupArtUnitNumber                       string
	DocketNumber                             string
	CustomerNumber                           *int
	FirstApplicantName                       string
	FirstInventorName                        string
	FirstInventorToFileIndicator             string
	NationalStageIndicator                   *bool
	PctPublicationNumber                     string
	PctPublicationDate                       string
	InternationalRegistrationNumber          string
	InternationalRegistrationPublicationDate string
	CpcClassificationBag                     []string
	PublicationCategoryBag                   []string
	PublicationDateBag                       []string
	PublicationSequenceNumberBag             []string
	UspcSymbolText                           string
	Class                                    string
	Subclass                                 string
	EntityStatus                             *EntityStatus
	Applicants                               []Applicant
	Inventors                                []Inventor
}

MetaDataResponse contains the full patent application meta-data response. MetaDataResponse pointer fields use *T (rather than T) when the API distinguishes "field absent" from the zero value -- for status codes, confirmation numbers, indicators. nil means USPTO did not return the field for this application.

type Paragraph added in v1.1.0

type Paragraph struct {
	ID   string `xml:"id,attr"`
	Num  string `xml:"num,attr"`
	Text string `xml:",chardata"`
	// Support for nested elements
	Sub []Sub    `xml:"sub"`
	Sup []Sup    `xml:"sup"`
	I   []Italic `xml:"i"`
	B   []Bold   `xml:"b"`
}

Paragraph represents a text paragraph with possible nested elements

type PatentApplication added in v1.1.0

type PatentApplication struct {
	XMLName      xml.Name      `xml:"us-patent-application"`
	Lang         string        `xml:"lang,attr"`
	DTDVersion   string        `xml:"dtd-version,attr"`
	File         string        `xml:"file,attr"`
	Status       string        `xml:"status,attr"`
	ID           string        `xml:"id,attr"`
	Country      string        `xml:"country,attr"`
	DateProduced string        `xml:"date-produced,attr"`
	DatePubl     string        `xml:"date-publ,attr"`
	Bibliography *Bibliography `xml:"us-bibliographic-data-application"`
	Abstract     *Abstract     `xml:"abstract"`
	DrawingsInfo *DrawingsInfo `xml:"drawings"`
	Description  *Description  `xml:"description"`
	Claims       *Claims       `xml:"claims"`
}

PatentApplication represents a patent application XML document (ICE DTD 4.6)

type PatentCandidate added in v1.6.2

type PatentCandidate struct {
	Type              PatentNumberType // PatentNumberTypeGrant or PatentNumberTypeApplication
	Number            string           // the bare digits as entered
	ApplicationNumber string           // application number this interpretation resolves to
	Title             string           // invention title, for a "did you mean" prompt
}

PatentCandidate describes one interpretation of an ambiguous bare patent number, resolved far enough to show the caller what it points at.

type PatentGrant added in v1.1.0

type PatentGrant struct {
	XMLName      xml.Name      `xml:"us-patent-grant"`
	Lang         string        `xml:"lang,attr"`
	DTDVersion   string        `xml:"dtd-version,attr"`
	File         string        `xml:"file,attr"`
	Status       string        `xml:"status,attr"`
	ID           string        `xml:"id,attr"`
	Country      string        `xml:"country,attr"`
	DateProduced string        `xml:"date-produced,attr"`
	DatePubl     string        `xml:"date-publ,attr"`
	Bibliography *Bibliography `xml:"us-bibliographic-data-grant"`
	Abstract     *Abstract     `xml:"abstract"`
	DrawingsInfo *DrawingsInfo `xml:"drawings"`
	Description  *Description  `xml:"description"`
	Claims       *Claims       `xml:"claims"`
}

PatentGrant represents a patent grant XML document (ICE DTD 4.7)

type PatentNumber added in v1.1.0

type PatentNumber struct {
	Original      string           // Original input
	Normalized    string           // Normalized format (digits only, or PCT API form)
	ApplicationNo string           // Application number if derivable
	Type          PatentNumberType // Type of number
	Country       string           // Country code (usually "US")
	// KindCode is the suffix when supplied by the caller (e.g., "A1", "A2",
	// "B2"). For publication numbers it is threaded through resolution to
	// preserve republished kinds. For grant numbers it is captured for
	// display only -- USPTO's search API ignores grant kind codes when
	// resolving to an application number.
	KindCode string
	// Ambiguous is true when the input was a bare number that could be either a
	// grant or an application (an 8-digit value with no kind code, slash, or
	// comma to disambiguate). Resolution probes both interpretations rather than
	// silently assuming one. See Client.ResolvePatentNumber.
	Ambiguous bool
}

PatentNumber represents a normalized patent number

func NormalizePatentNumber added in v1.1.0

func NormalizePatentNumber(input string) (*PatentNumber, error)

NormalizePatentNumber normalizes various patent number formats to application numbers Accepts formats like:

  • Application: "17248024", "17/248,024", "17/248024"
  • Grant: "11646472", "11,646,472", "US 11,646,472 B2"
  • Publication: "20250087686", "US20250087686A1", "US 2025/0087686 A1"
  • PCT: "PCTUS2025058371" (15-char API form), "PCT/US2025/058371" (17-char display), "PCTUS0719317" (12-char legacy)
Example
package main

import (
	"fmt"

	odp "github.com/patent-dev/uspto-odp"
)

func main() {
	// Patent numbers are normalized offline; resolving a grant or publication
	// number to its application number needs a client call.
	pn, err := odp.NormalizePatentNumber("US 11,646,472 B2")
	if err != nil {
		panic(err)
	}
	fmt.Println(pn.Normalized)
	fmt.Println(pn.FormatAsGrant())
}
Output:
11646472
11,646,472

func (*PatentNumber) FormatAsApplication added in v1.1.0

func (pn *PatentNumber) FormatAsApplication() string

FormatAsApplication formats number as application (e.g., 17/248,024)

func (*PatentNumber) FormatAsGrant added in v1.1.0

func (pn *PatentNumber) FormatAsGrant() string

FormatAsGrant formats number as grant (e.g., 11,646,472)

func (*PatentNumber) FormatAsPCT added in v1.5.0

func (pn *PatentNumber) FormatAsPCT() string

FormatAsPCT formats a PCT number for display (e.g., PCT/US2025/058371). 15-char API form -> 17-char display form. 12-char legacy form is returned unchanged (no canonical display form).

func (*PatentNumber) FormatAsPublication added in v1.1.0

func (pn *PatentNumber) FormatAsPublication() string

FormatAsPublication formats number as publication (e.g., 2025/0087686)

func (*PatentNumber) String added in v1.1.0

func (pn *PatentNumber) String() string

String returns a human-readable representation

func (*PatentNumber) ToApplicationNumber added in v1.1.0

func (pn *PatentNumber) ToApplicationNumber() string

ToApplicationNumber converts a patent number to application number format For application and PCT numbers, returns as-is. For grant/publication numbers, returns the normalized number which can be used with the API.

type PatentNumberType added in v1.1.0

type PatentNumberType int

PatentNumberType indicates the type of patent number

const (
	PatentNumberTypeUnknown PatentNumberType = iota
	PatentNumberTypeApplication
	PatentNumberTypeGrant
	PatentNumberTypePublication
	PatentNumberTypePCT
)

Patent number type values.

type PatentSearchFilter added in v1.6.7

type PatentSearchFilter struct {
	Field  string
	Values []string
}

PatentSearchFilter is a server-side term filter: a document field constrained to one or more exact values (OR-ed within the field, AND-ed across filters).

type PatentSearchOptions added in v1.6.6

type PatentSearchOptions struct {
	Sort         []PatentSearchSort
	Fields       []string
	Filters      []PatentSearchFilter
	RangeFilters []PatentSearchRange
}

PatentSearchOptions carries the optional refinements for SearchPatentsWithOptions on top of the query and pagination: sort keys, a response field projection, and the server-side term/range filters the ODP search endpoint supports (faceted filtering and date/number windows).

type PatentSearchRange added in v1.6.7

type PatentSearchRange struct {
	Field string
	From  string
	To    string
}

PatentSearchRange is a server-side range filter on a date/number field. An empty From or To leaves that bound open.

type PatentSearchSort added in v1.6.6

type PatentSearchSort struct {
	Field string
	Order string
}

PatentSearchSort is one sort key for a patent search: a document field and an optional order ("Asc"/"Desc", case-insensitive; empty applies the API default).

type Sub added in v1.1.0

type Sub struct {
	Text string `xml:",chardata"`
}

Sub represents subscript text

type Sup added in v1.1.0

type Sup struct {
	Text string `xml:",chardata"`
}

Sup represents superscript text

type TSDRStatusResponse added in v1.4.0

type TSDRStatusResponse struct {
	Trademarks []map[string]any `json:"trademarks"`
}

TSDRStatusResponse is the JSON response from the TSDR case status endpoint. The status endpoint uses content negotiation (Accept: application/json) to return JSON instead of the default XML. The response structure does not match the generated XML-based types, so this wrapper provides a typed envelope while the inner trademark data uses dynamic maps matching the API's JSON schema.

type Text added in v1.1.0

type Text struct {
	ID   string `xml:"id,attr"`
	Lang string `xml:"lang,attr"`
	Text string `xml:",chardata"`
}

Text represents simple text with language attribute

type TransactionEvent added in v1.3.0

type TransactionEvent struct {
	Date        string
	Code        string
	Description string
}

TransactionEvent represents a single patent transaction event.

type TransactionsResponse added in v1.3.0

type TransactionsResponse struct {
	ApplicationNumber string
	Events            []TransactionEvent
}

TransactionsResponse contains patent transaction history.

type XMLDocument added in v1.1.0

type XMLDocument struct {
	// Grant fields (us-patent-grant)
	Grant *PatentGrant `xml:"us-patent-grant"`
	// Application fields (us-patent-application)
	Application *PatentApplication `xml:"us-patent-application"`
}

XMLDocument represents either a patent grant or application XML document

func ParseApplicationXML added in v1.1.0

func ParseApplicationXML(data []byte) (*XMLDocument, error)

ParseApplicationXML parses patent application XML data (us-patent-application)

func ParseGrantXML added in v1.1.0

func ParseGrantXML(data []byte) (*XMLDocument, error)

ParseGrantXML parses patent grant XML data (us-patent-grant)

func ParseXML added in v1.1.0

func ParseXML(data []byte) (*XMLDocument, error)

ParseXML parses XML data and auto-detects the document type

func ParseXMLWithType added in v1.1.0

func ParseXMLWithType(data []byte, expectedType DocumentType) (*XMLDocument, error)

ParseXMLWithType parses XML data with a known document type hint

func (*XMLDocument) GetAbstract added in v1.1.0

func (d *XMLDocument) GetAbstract() *Abstract

GetAbstract returns the abstract section

func (*XMLDocument) GetClaims added in v1.1.0

func (d *XMLDocument) GetClaims() *Claims

GetClaims returns the claims section

func (*XMLDocument) GetDescription added in v1.1.0

func (d *XMLDocument) GetDescription() *Description

GetDescription returns the description section

func (*XMLDocument) GetDocumentType added in v1.1.0

func (d *XMLDocument) GetDocumentType() DocumentType

GetDocumentType returns the type of document (grant or application)

func (*XMLDocument) GetTitle added in v1.1.0

func (d *XMLDocument) GetTitle() string

GetTitle returns the invention title from either grant or application

Directories

Path Synopsis
cmd
gen command
Command gen processes USPTO ODP swagger files and generates Go code.
Command gen processes USPTO ODP swagger files and generates Go code.
Package generated provides primitives to interact with the openapi HTTP API.
Package generated provides primitives to interact with the openapi HTTP API.
oa
Package oa provides primitives to interact with the openapi HTTP API.
Package oa provides primitives to interact with the openapi HTTP API.
tsdr
Package tsdr provides primitives to interact with the openapi HTTP API.
Package tsdr provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL