epo_ops

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2026 License: MIT Imports: 22 Imported by: 0

README

EPO OPS Go Client

CI Go Reference Go Report Card

A Go client library for the European Patent Office's Open Patent Services (OPS) REST API v3.2, with OAuth2 authentication and typed responses.

Overview

This library provides an idiomatic Go interface to the EPO's Open Patent Services:

  • OAuth2 authentication with automatic token management and refresh on 401
  • Patent text retrieval: bibliographic data, claims, description, abstract, and fulltext
  • Patent search using CQL (Contextual Query Language), with optional constituents
  • INPADOC family retrieval, including biblio and legal variants
  • CPC/ECLA classification services (schema, statistics, mapping, media)
  • Patent image retrieval with TIFF to PNG conversion
  • Legal status retrieval with INPADOC legal event data
  • EPO Register access (biblio, events, procedural steps, unitary patent)
  • Patent number format conversion and validation
  • Quota tracking against the fair use policy
  • Typed errors plus automatic retry with exponential backoff

Installation

go get github.com/patent-dev/epo-ops

Getting access

The EPO OPS API requires a free developer account and an OAuth2 Consumer Key + Consumer Secret.

  1. Register at the EPO Developer Portal, choose the Non-paying access method, and submit the form. Wait for the confirmation email.

  2. Sign in at the portal and open My Apps.

  3. Click Add a new App to register an application and obtain its Consumer Key and Consumer Secret.

  4. Export them for the client / demo:

    export EPO_OPS_CONSUMER_KEY=...
    export EPO_OPS_CONSUMER_SECRET=...
    

Quick start

package main

import (
    "context"
    "fmt"
    "log"

    ops "github.com/patent-dev/epo-ops"
)

func main() {
    client, err := ops.NewClient(&ops.Config{
        ConsumerKey:    "your-consumer-key",
        ConsumerSecret: "your-consumer-secret",
    })
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    biblio, err := client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Title: %s\n", biblio.Titles["en"])
}

Usage

Client creation
// Defaults are filled in for any field left zero.
client, err := ops.NewClient(&ops.Config{
    ConsumerKey:    "your-key",
    ConsumerSecret: "your-secret",
})

// Custom configuration.
client, err := ops.NewClient(&ops.Config{
    ConsumerKey:    "your-key",
    ConsumerSecret: "your-secret",
    BaseURL:        "https://ops.epo.org/3.2/rest-services", // default
    MaxRetries:     3,                                       // default
    RetryDelay:     time.Second,                             // default
    Timeout:        30 * time.Second,                        // default
})
Option Type Default Description
ConsumerKey string required OAuth2 consumer key
ConsumerSecret string required OAuth2 consumer secret
BaseURL string https://ops.epo.org/3.2/rest-services API base URL
MaxRetries int 3 Maximum retry attempts
RetryDelay time.Duration 1s Base delay between retries
Timeout time.Duration 30s HTTP client timeout (increase for bulk classification endpoints)
Parsed vs raw API

Most methods return parsed Go structs for type-safe access. Each has a *Raw() variant that returns the original XML for custom parsing or storage. Parsed methods internally call their *Raw() counterpart and parse the result, so the two always agree.

// Parsed -> *BiblioData
biblio, err := client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1")
fmt.Printf("Title: %s\n", biblio.Titles["en"])

// Raw -> XML string
xmlData, err := client.GetBiblioRaw(ctx, "publication", "docdb", "EP.1000000.B1")
os.WriteFile("biblio.xml", []byte(xmlData), 0644)

Common parameters for published-data methods:

  • refType: "publication", "application", or "priority"
  • format: "docdb" or "epodoc"
  • number: docdb format "EP.1000000.B1", epodoc format "EP1000000"
Published data retrieval
// Bibliographic data -> *BiblioData
biblio, err := client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1")
fmt.Printf("Publication Date: %s\n", biblio.PublicationDate)
for _, applicant := range biblio.Applicants {
    fmt.Printf("Applicant: %s (%s)\n", applicant.Name, applicant.Country)
}

// Claims -> *ClaimsData
claims, err := client.GetClaims(ctx, "publication", "docdb", "EP.1000000.B1")

// Description -> *DescriptionData
description, err := client.GetDescription(ctx, "publication", "docdb", "EP.1000000.B1")

// Abstract -> *AbstractData
abstract, err := client.GetAbstract(ctx, "publication", "docdb", "EP.1000000.B1")

// Full text (biblio + abstract + description + claims) -> *FulltextData
fulltext, err := client.GetFulltext(ctx, "publication", "docdb", "EP.1000000.B1")

// Published equivalents (simple family) -> *EquivalentsData
equivalents, err := client.GetPublishedEquivalents(ctx, "publication", "docdb", "EP.1000000.B1")

Returns *SearchResultData with parsed results.

results, err := client.Search(ctx, "ti=battery", "1-25")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Total results: %d\n", results.TotalCount)
for _, r := range results.Results {
    fmt.Printf("  %s%s%s - %s\n", r.Country, r.DocNumber, r.Kind, r.Title)
}

// Search with a specific constituent.
results, err = client.SearchWithConstituent(ctx, "biblio", "pa=Siemens", "1-10")

// Raw XML access.
xmlData, err := client.SearchRaw(ctx, "ti=battery", "1-25")

CQL examples: ti=plastic (title), pa=Siemens (applicant), de (country code DE), ti=plastic and pa=Siemens (combined). Range format: "1-25" (default), "1-100", etc.

Family retrieval

Returns *FamilyData with parsed family information.

family, err := client.GetFamily(ctx, "publication", "docdb", "EP.1000000.B1")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Family ID: %s, members: %d\n", family.FamilyID, family.TotalCount)
for _, member := range family.Members {
    fmt.Printf("Member: %s %s %s (Date: %s)\n",
        member.Country, member.DocNumber, member.Kind, member.Date)
}

// Variants enriching the family with biblio or legal data.
family, err = client.GetFamilyWithBiblio(ctx, "publication", "docdb", "EP.1000000.B1")
family, err = client.GetFamilyWithLegal(ctx, "publication", "docdb", "EP.1000000.B1")

// Raw XML access.
xmlData, err := client.GetFamilyRaw(ctx, "publication", "docdb", "EP.1000000.B1")
Images and TIFF conversion

Patent images from EPO are typically TIFF. The tiffutil package converts them to PNG, handling CCITT Group 3/4 and LZW compression, the CMYK color model, and automatic landscape-to-portrait rotation.

import (
    ops "github.com/patent-dev/epo-ops"
    "github.com/patent-dev/epo-ops/tiffutil"
)

// Retrieve a patent image (image types: "FullDocument", "Drawing", "FirstPageClipping").
imageData, err := client.GetImage(ctx, "EP", "1000000", "B1", "Drawing", 1)
if err != nil {
    log.Fatal(err)
}

// Convert TIFF -> PNG (with automatic rotation for landscape images).
pngData, err := tiffutil.TIFFToPNG(imageData)
os.WriteFile("patent_drawing.png", pngData, 0644)

// Without rotation, or batch convert multiple pages.
pngData, err = tiffutil.TIFFToPNGNoRotate(imageData)
pngImages, err := tiffutil.BatchTIFFToPNG([][]byte{imageData})
// Legal status -> *LegalData
legal, err := client.GetLegal(ctx, "publication", "docdb", "EP.1000000.B1")
for _, event := range legal.LegalEvents {
    fmt.Printf("Event: %s (Code: %s, Country: %s)\n", event.Date, event.EventCode, event.Country)
}

// Register events -> *RegisterEventsData
regEvents, err := client.GetRegisterEvents(ctx, "publication", "epodoc", "EP1000000")

// EPO Register bibliographic data (raw XML).
registerBiblio, err := client.GetRegisterBiblioRaw(ctx, "publication", "epodoc", "EP1000000")
Number conversion
converted, err := client.ConvertPatentNumber(ctx, "publication", "docdb", "EP.1000000.B1", "epodoc")

Formats: original (US.(05/948,554).19781004), epodoc (US19780948554), docdb (US 19780948554).

Quota monitoring

The EPO OPS fair use policy limits non-paying users to 4 GB/week (paying users pay for more); see the fair use page. The client tracks quota usage from API response headers.

client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1")

quota := client.GetLastQuota()
if quota != nil {
    fmt.Printf("Status: %s\n", quota.Status) // "green", "yellow", "red", or "black"
    fmt.Printf("Individual: %.2f%%\n", quota.Individual.UsagePercent())
}
Retry logic

The client automatically retries failed requests with exponential backoff:

  • Retryable: 5xx errors, 408, timeouts, network errors
  • Non-retryable: 404, 400, authentication errors, quota exceeded
  • Token refresh: automatic on 401 errors
  • Backoff: exponential, base delay x (attempt + 1)

Tune it through MaxRetries and RetryDelay on the Config.

Error handling

The library returns typed errors. Use errors.As to inspect them:

biblio, err := client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1")
if err != nil {
    var notFound *ops.NotFoundError
    var quota *ops.QuotaExceededError
    switch {
    case errors.As(err, &notFound):
        log.Printf("patent not found: %v", notFound)
    case errors.As(err, &quota):
        log.Printf("fair use quota exceeded: %v", quota)
    default:
        log.Printf("error: %v", err)
    }
}

Available error types:

  • AuthError - authentication failures
  • NotFoundError - resource not found (404)
  • QuotaExceededError - fair use quota exceeded (429, 403)
  • ServiceUnavailableError - temporary service outage (503)
  • AmbiguousPatentError - multiple kind codes available
  • ValidationError - invalid input (number, format, date)
  • ConfigError - configuration issues

Testing

make test              # unit tests (mock HTTP server, race)
make test-integration  # integration tests against the real API, needs credentials
make lint

Integration tests require credentials in the environment:

export EPO_OPS_CONSUMER_KEY="your-key"
export EPO_OPS_CONSUMER_SECRET="your-secret"

See the demo/ directory for a complete example application exercising all features.

API specification

The typed client in generated/ is produced by oapi-codegen from an OpenAPI 3.0 specification kept in openapi.yaml. That spec was:

  • Converted from the official EPO OPS Swagger 2.0 specification (resources/ops.yaml)
  • Fixed up for OpenAPI 3.0 (OAuth2 flow set to clientCredentials, invalid parameter formats removed)
  • Extended with the Data Usage Statistics endpoint (/developers/me/stats/usage), which the official spec omits

To regenerate after the spec changes, run make generate, which re-applies the conversion fixes (via the scripts in scripts/) and then runs the //go:generate directives in client.go.

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

  • epo-bdds - EPO Bulk Data Distribution Service client (DOCDB, INPADOC, EP full text)
  • uspto-odp - USPTO Open Data Portal client (patents, PTAB, TSDR, 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 epo_ops provides a Go client for the European Patent Office's Open Patent Services (OPS) API v3.2.

This library provides an idiomatic Go interface to interact with the EPO's Open Patent Services, allowing you to retrieve patent bibliographic data, claims, descriptions, search for patents, get patent family information, download images, and more.

Example usage:

config := &ops.Config{
    ConsumerKey:    "your-consumer-key",
    ConsumerSecret: "your-consumer-secret",
}

client, err := ops.NewClient(config)
if err != nil {
    log.Fatal(err)
}

ctx := context.Background()
biblio, err := client.GetBiblio(ctx, "publication", "docdb", "EP1000000")
if err != nil {
    log.Fatal(err)
}

Index

Examples

Constants

View Source
const (
	RefTypePublication = "publication"
	RefTypeApplication = "application"
	RefTypePriority    = "priority"
)

Reference types for API requests

View Source
const (
	FormatDocDB    = "docdb"
	FormatEPODOC   = "epodoc"
	FormatOriginal = "original"
)

Number formats for API requests

View Source
const (
	ImageTypeThumbnail = "thumbnail" // Drawings only
	ImageTypeFullImage = "fullimage" // Full document with all sections
	ImageTypeFirstPage = "firstpage" // First page clipping (requires kind="PA")
)

Image types for GetImage (lowercase per EPO OPS specification)

View Source
const (
	ConstituentBiblio    = "biblio"
	ConstituentAbstract  = "abstract"
	ConstituentFullCycle = "full-cycle"
)

Search constituents

View Source
const (
	EndpointBiblio      = "biblio"
	EndpointFulltext    = "fulltext"
	EndpointClaims      = "claims"
	EndpointDescription = "description"
	EndpointAbstract    = "abstract"
	EndpointFamily      = "family"
	EndpointLegal       = "legal"
	EndpointRegister    = "register"
	EndpointSearch      = "search"
	EndpointImages      = "images"
)

Endpoint types for Accept header selection

Variables

This section is empty.

Functions

func GetEmbeddedXSD

func GetEmbeddedXSD(name string) (string, bool)

GetEmbeddedXSD returns the embedded XSD schema content by name. This allows users to access schemas for custom validation if needed.

Available schemas: "exchange-documents", "fulltext-documents", "ops_legal", "ops", "cpc"

func NormalizeToDocdb

func NormalizeToDocdb(number string) (string, error)

NormalizeToDocdb converts a patent number to DOCDB format (CC.number.KC).

This function accepts patent numbers in various formats and normalizes them to the DOCDB format required by most EPO OPS API endpoints.

Supported input formats:

  • EPODOC format: "EP1000000B1", "US5551212A", "WO2023123456A1"
  • DOCDB format: "EP.1000000.B1" (returns unchanged if valid)
  • With spaces: "EP 1000000 B1" (spaces removed before processing)

Examples:

  • "EP2884620A2" -> "EP.2884620.A2"
  • "EP.2884620.A2" -> "EP.2884620.A2" (already DOCDB)
  • "US5551212A" -> "US.5551212.A"
  • "EP 1000000 B1" -> "EP.1000000.B1"

Returns an error if:

  • The input is empty
  • The input cannot be parsed as a valid patent number
  • The input is in DOCDB format but invalid

func ValidateBulkNumbers added in v1.0.0

func ValidateBulkNumbers(numbers []string, format string) error

ValidateBulkNumbers validates a slice of patent numbers for bulk operations. This helper reduces code duplication across GetXMultiple methods.

Parameters:

  • numbers: Slice of patent numbers to validate
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)

Returns error if:

  • numbers slice is empty
  • numbers slice has more than 100 entries
  • any individual number fails format validation

func ValidateDate

func ValidateDate(date string) error

ValidateDate validates a date string in YYYYMMDD format.

Examples of valid dates:

  • 20231015 (October 15, 2023)
  • 19990101 (January 1, 1999)

Note: This only validates the format, not whether the date is valid (e.g., it accepts 20231399 which is not a real date). Empty string is accepted (date is optional in many API calls).

func ValidateDocdbFormat

func ValidateDocdbFormat(number string) error

ValidateDocdbFormat validates the docdb format: CC.number.KC (kind code optional)

Examples of valid docdb format:

  • EP.1000000.B1
  • US.5551212.A
  • WO.2023123456.A1
  • US.7654321. (without kind code)

Format rules:

  • Two-letter country code in uppercase
  • Dot separator
  • Numeric document number
  • Dot separator
  • Optional kind code: letter + optional digit

func ValidateEpodocFormat

func ValidateEpodocFormat(number string) error

ValidateEpodocFormat validates the epodoc format: CCnumber[KC]

Examples of valid epodoc format:

  • EP1000000B1
  • EP1000000 (kind code optional)
  • US5551212A
  • WO2023123456A1

Format rules:

  • Two-letter country code in uppercase
  • Numeric document number
  • Optional kind code: letter + optional digit

func ValidateFormat

func ValidateFormat(format, number string) error

ValidateFormat validates a patent number based on the specified format.

Parameters:

  • format: One of "docdb", "epodoc", or "original" (from constants)
  • number: The patent number to validate

Returns a ValidationError if the format is invalid or the number doesn't match the format rules.

func ValidateOriginalFormat

func ValidateOriginalFormat(number string) error

ValidateOriginalFormat validates the original format (flexible).

The "original" format is the format as provided by the patent authority, which can vary significantly. This validation is permissive and only checks that the number is non-empty and within reasonable length limits.

Examples of valid original format:

  • EP 1000000 B1 (with spaces)
  • US5,551,212 (with commas)
  • WO/2023/123456
  • Any format used by patent authorities

func ValidatePatentNumber

func ValidatePatentNumber(number string) error

ValidatePatentNumber performs basic validation on a patent number string. Returns an error if the patent number is invalid.

Validation rules:

  • Must not be empty
  • Length must not exceed 50 characters
  • Must contain only ASCII letters, digits, and the separators space, dash, dot, and slash

Note: This is a permissive validation. Invalid patent numbers will be rejected by the EPO API with appropriate error messages.

func ValidateRefType

func ValidateRefType(refType string) error

ValidateRefType validates a reference type parameter.

Valid reference types:

  • "publication" - Published patent documents
  • "application" - Patent applications
  • "priority" - Priority documents

func ValidateTimeRange

func ValidateTimeRange(timeRange string) error

ValidateTimeRange validates a time range string for the Usage Statistics API.

Valid formats:

  • Single date: "dd/mm/yyyy" (e.g., "01/01/2024")
  • Date range: "dd/mm/yyyy~dd/mm/yyyy" (e.g., "01/01/2024~07/01/2024")

Returns an error if the format is invalid.

Types

type Abstract added in v1.4.0

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

Abstract is one <abstract> constituent.

func (Abstract) Text added in v1.4.0

func (a Abstract) Text() string

Text joins the abstract paragraphs into a single trimmed string.

type AbstractData

type AbstractData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	Country      string
	DocNumber    string
	Kind         string
	Language     string
	Text         string
}

AbstractData represents parsed patent abstract

func ParseAbstract

func ParseAbstract(xmlData string) (*AbstractData, error)

ParseAbstract parses abstract XML into structured data

type Agent added in v1.4.0

type Agent struct {
	Sequence string `xml:"sequence,attr"`
	RepType  string `xml:"rep-type,attr"`
	Name     string `xml:"addressbook>name"`
}

Agent is one representative/agent.

type AmbiguousPatentError

type AmbiguousPatentError struct {
	Country   string
	Number    string
	KindCodes []string
	Message   string
}

AmbiguousPatentError represents a situation where a patent number has multiple kind codes available (A1, B1, etc.) and the user must choose a specific one.

func (*AmbiguousPatentError) Error

func (e *AmbiguousPatentError) Error() string

type Applicant added in v1.4.0

type Applicant struct {
	Sequence   string `xml:"sequence,attr"`
	DataFormat string `xml:"data-format,attr"`
	Name       string `xml:"applicant-name>name"`
	Residence  string `xml:"residence>country"`
}

Applicant / Inventor / Agent are repeated once per data-format (docdb, epodoc).

type ApplicationReference added in v1.0.0

type ApplicationReference struct {
	Country           string
	DocNumber         string // docdb-standardised application number
	Kind              string
	Date              string
	DocID             string
	OriginalDocNumber string // application number as supplied by the originating office (document-id-type="original"); the key national offices look up by
}

ApplicationReference represents the application reference for a family member

type AuthError

type AuthError struct {
	StatusCode int
	Message    string
}

AuthError represents an authentication error.

func (*AuthError) Error

func (e *AuthError) Error() string

type Authenticator

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

Authenticator handles OAuth2 authentication for the EPO OPS API.

func NewAuthenticator

func NewAuthenticator(consumerKey, consumerSecret string, httpClient *http.Client) *Authenticator

NewAuthenticator creates a new Authenticator.

func (*Authenticator) ClearToken

func (a *Authenticator) ClearToken()

ClearToken clears the cached token, forcing a refresh on next request.

func (*Authenticator) GetToken

func (a *Authenticator) GetToken(ctx context.Context) (string, error)

GetToken returns a valid access token, refreshing it if necessary.

type BiblioData

type BiblioData struct {
	XMLName         xml.Name `xml:"world-patent-data"`
	PatentNumber    string
	Country         string
	DocNumber       string
	Kind            string
	PublicationDate string
	FamilyID        string
	Titles          map[string]string // lang -> title
	Applicants      []Party
	Inventors       []Party
	IPCClasses      []string
	CPCClasses      []CPCClass
}

BiblioData represents parsed bibliographic data

func ParseBiblio

func ParseBiblio(xmlData string) (*BiblioData, error)

ParseBiblio parses bibliographic XML into structured data

type BibliographicData added in v1.4.0

type BibliographicData struct {
	PublicationRefs       []Reference              `xml:"publication-reference"`
	ApplicationRefs       []Reference              `xml:"application-reference"`
	Titles                []Title                  `xml:"invention-title"`
	Applicants            []Applicant              `xml:"parties>applicants>applicant"`
	Inventors             []Inventor               `xml:"parties>inventors>inventor"`
	Agents                []Agent                  `xml:"parties>agents>agent"`
	IPCR                  []string                 `xml:"classifications-ipcr>classification-ipcr>text"`
	IPC                   []string                 `xml:"classification-ipc>text"`
	National              []NationalClassification `xml:"classification-national"`
	CPC                   []PatentClassification   `xml:"patent-classifications>patent-classification"`
	Priorities            []Priority               `xml:"priority-claims>priority-claim"`
	Citations             []Citation               `xml:"references-cited>citation"`
	Designations          DesignationOfStates      `xml:"designation-of-states"`
	LanguageOfFiling      string                   `xml:"language-of-filing"`
	LanguageOfPublication string                   `xml:"language-of-publication"`
}

BibliographicData is the full bibliographic-data subtree.

type CPCClass

type CPCClass struct {
	Section   string
	Class     string
	Subclass  string
	MainGroup string
	Subgroup  string
	Full      string // Combined representation (e.g., "H04W 84/20")
}

CPCClass represents a Cooperative Patent Classification

type Citation added in v1.4.0

type Citation struct {
	Sequence     string   `xml:"sequence,attr"`
	CitedPhase   string   `xml:"cited-phase,attr"`
	CitedBy      string   `xml:"cited-by,attr"`
	Categories   []string `xml:"category"`
	RelClaimsAll []string `xml:"rel-claims"`
	RelPassages  []string `xml:"rel-passage>passage"`
	Patcit       *Patcit  `xml:"patcit"`
	Nplcit       *Nplcit  `xml:"nplcit"`
}

Citation is one references-cited/citation: a cited document with its search category (X / Y / A ...), the claims it was applied to, and the relevant passages.

A single cited document can carry MORE THAN ONE <category>/<rel-claims> pair when it was applied with different relevance to different claim sets (e.g. category Y against claims 1-12,15 AND category A against claims 13,14). Categories and RelClaims are therefore slices that keep every occurrence; the Category() and RelClaims() helpers return the first for the common single-category case.

func (Citation) Category added in v1.4.0

func (c Citation) Category() string

Category returns the citation's first (often only) search category, or "".

func (Citation) RelClaims added in v1.4.0

func (c Citation) RelClaims() string

RelClaims returns the claim range for the citation's first category, or "".

type Claim

type Claim struct {
	Number int
	Text   string
}

Claim represents a single patent claim

type ClaimsData

type ClaimsData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	Country      string
	DocNumber    string
	Kind         string
	Language     string
	Claims       []Claim
}

ClaimsData represents parsed patent claims

func ParseClaims

func ParseClaims(xmlData string) (*ClaimsData, error)

ParseClaims parses claims XML into structured data

type ClassificationChild added in v1.0.0

type ClassificationChild struct {
	Symbol      string
	Title       string
	Level       int
	HasChildren bool // True when the symbol has descendants that are not included in this response.
}

ClassificationChild represents a child classification item

type ClassificationData added in v1.0.0

type ClassificationData struct {
	Symbol      string
	Title       string
	Level       int
	SchemeType  string
	HasChildren bool // True when the symbol has descendants that are not included in this response.
	Children    []ClassificationChild
	Ancestors   []ClassificationChild
}

ClassificationData represents parsed CPC classification schema data

func ParseClassificationSchema added in v1.0.0

func ParseClassificationSchema(xmlData string) (*ClassificationData, error)

ParseClassificationSchema parses EPO classification schema XML into a ClassificationData struct.

type Client

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

Client is the main EPO OPS API client.

func NewClient

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

NewClient creates a new EPO OPS API client.

Example
package main

import (
	"fmt"

	ops "github.com/patent-dev/epo-ops"
)

func main() {
	client, err := ops.NewClient(&ops.Config{
		ConsumerKey:    "your-consumer-key",
		ConsumerSecret: "your-consumer-secret",
	})
	if err != nil {
		panic(err)
	}
	// With a valid client, call e.g. client.GetBiblio(ctx, "publication", "docdb", "EP.1000000.B1").
	fmt.Println(client != nil)
}
Output:
true

func (*Client) ConvertPatentNumber

func (c *Client) ConvertPatentNumber(ctx context.Context, refType, inputFormat, number, outputFormat string) (*NumberConversionData, error)

ConvertPatentNumber converts a patent number between formats and returns parsed data.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • inputFormat: Input format ("original", "epodoc", "docdb")
  • number: Patent number in input format
  • outputFormat: Output format ("original", "epodoc", "docdb")

Returns parsed NumberConversionData with Country, DocNumber, Kind, and Date fields.

func (*Client) ConvertPatentNumberMultipleRaw added in v1.0.0

func (c *Client) ConvertPatentNumberMultipleRaw(ctx context.Context, refType, inputFormat string, numbers []string, outputFormat string) (string, error)

ConvertPatentNumberMultipleRaw converts multiple patent numbers from one format to another. Uses POST endpoint for efficient batch conversion of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • inputFormat: Input format ("original", "epodoc", "docdb")
  • numbers: Slice of patent numbers in input format (max 100)
  • outputFormat: Output format ("original", "epodoc", "docdb")

Returns XML containing converted patent numbers for all requested patents.

func (*Client) ConvertPatentNumberRaw added in v1.0.0

func (c *Client) ConvertPatentNumberRaw(ctx context.Context, refType, inputFormat, number, outputFormat string) (string, error)

ConvertPatentNumberRaw converts a patent number from one format to another and returns the raw XML response.

func (*Client) GetAbstract

func (c *Client) GetAbstract(ctx context.Context, refType, format, number string) (*AbstractData, error)

GetAbstract retrieves and parses the abstract for a patent.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns parsed abstract data. For raw XML, use GetAbstractRaw().

func (*Client) GetAbstractMultiple

func (c *Client) GetAbstractMultiple(ctx context.Context, refType, format string, numbers []string) (string, error)

GetAbstractMultiple retrieves abstracts for multiple patents (bulk operation). Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML string containing abstracts for all requested patents.

Note: Returns raw XML. See GetBiblioMultiple() documentation for notes on return type inconsistency.

func (*Client) GetAbstractRaw

func (c *Client) GetAbstractRaw(ctx context.Context, refType, format, number string) (string, error)

GetAbstractRaw retrieves the abstract for a patent as raw XML.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns the abstract as an XML string.

func (*Client) GetBiblio

func (c *Client) GetBiblio(ctx context.Context, refType, format, number string) (*BiblioData, error)

GetBiblio retrieves and parses bibliographic data for a patent.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns parsed bibliographic data. For raw XML, use GetBiblioRaw().

func (*Client) GetBiblioMultiple

func (c *Client) GetBiblioMultiple(ctx context.Context, refType, format string, numbers []string) (string, error)

GetBiblioMultiple retrieves bibliographic data for multiple patents (bulk operation). Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML string containing bibliographic data for all requested patents.

Note: This method returns raw XML instead of parsed structs for historical reasons. Some *Multiple() methods return parsed structs (GetDescriptionMultiple, GetFulltextMultiple) while others return XML (GetBiblioMultiple, GetClaimsMultiple, GetAbstractMultiple). This inconsistency is technical debt to be addressed in a future major version. For now, callers can parse the XML using ParseBiblio() if needed.

func (*Client) GetBiblioRaw

func (c *Client) GetBiblioRaw(ctx context.Context, refType, format, number string) (string, error)

GetBiblioRaw retrieves bibliographic data for a patent as raw XML.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns the bibliographic data as an XML string.

func (*Client) GetClaims

func (c *Client) GetClaims(ctx context.Context, refType, format, number string) (*ClaimsData, error)

GetClaims retrieves and parses claims for a patent.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns parsed claims data. For raw XML, use GetClaimsRaw().

func (*Client) GetClaimsMultiple

func (c *Client) GetClaimsMultiple(ctx context.Context, refType, format string, numbers []string) (string, error)

GetClaimsMultiple retrieves claims for multiple patents (bulk operation). Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML containing claims for all requested patents.

Note: Returns raw XML. See GetBiblioMultiple() documentation for notes on return type inconsistency.

func (*Client) GetClaimsRaw

func (c *Client) GetClaimsRaw(ctx context.Context, refType, format, number string) (string, error)

GetClaimsRaw retrieves claims for a patent as raw XML.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000B1")

Returns the claims as an XML string.

func (*Client) GetClassificationMappingRaw added in v1.0.0

func (c *Client) GetClassificationMappingRaw(ctx context.Context, inputFormat, class, subclass, outputFormat string, additional bool) (string, error)

GetClassificationMappingRaw converts between CPC and ECLA classification formats.

This method maps classification codes between the Cooperative Patent Classification (CPC) and European Classification (ECLA) systems. This is useful when working with patents that use different classification systems.

Parameters:

  • inputFormat: Format of the input classification ("cpc" or "ecla")
  • class: Classification class code (e.g., "A01D2085")
  • subclass: Classification subclass code (e.g., "8")
  • outputFormat: Desired output format ("cpc" or "ecla")
  • additional: If true, include additional/invention information

Returns XML containing:

  • Mapped classification codes
  • Mapping relationships
  • Classification descriptions

Example:

// Convert ECLA to CPC
mapping, err := client.GetClassificationMapping(ctx, "ecla", "A01D2085", "8", "cpc", false)
if err != nil {
    log.Fatal(err)
}

// Convert CPC to ECLA with additional information
mapping, err := client.GetClassificationMapping(ctx, "cpc", "H04W84", "18", "ecla", true)

func (*Client) GetClassificationMedia

func (c *Client) GetClassificationMedia(ctx context.Context, mediaName string, asAttachment bool) ([]byte, error)

GetClassificationMedia retrieves media files (images/diagrams) for CPC classifications.

The CPC classification system includes illustrative diagrams and images to help understand classification concepts. This method downloads these media files.

Parameters:

  • mediaName: Name of the media resource (e.g., "1000.gif", "5000.png")
  • Media names are referenced in classification schema XML
  • Common formats: GIF, PNG, JPG
  • asAttachment: If true, sets Content-Disposition to attachment (forces download)
  • false (default): inline display
  • true: download as attachment

Returns binary image data that can be saved to a file or displayed.

Example:

// Download a classification diagram
imageData, err := client.GetClassificationMedia(ctx, "1000.gif", false)
if err != nil {
    log.Fatal(err)
}

// Save to file
err = os.WriteFile("classification-1000.gif", imageData, 0644)

func (*Client) GetClassificationSchema

func (c *Client) GetClassificationSchema(ctx context.Context, class string, ancestors, navigation bool) (*ClassificationData, error)

GetClassificationSchema retrieves and parses CPC classification schema hierarchy.

Parameters:

  • class: CPC classification symbol (e.g., "A01B", "H04W84/18")
  • ancestors: If true, include ancestor classifications in the hierarchy
  • navigation: If true, include navigation links to related classifications

Returns parsed ClassificationData with Symbol, Title, Level, SchemeType, and Children.

func (*Client) GetClassificationSchemaMultipleRaw added in v1.0.0

func (c *Client) GetClassificationSchemaMultipleRaw(ctx context.Context, classes []string) (string, error)

GetClassificationSchemaMultipleRaw retrieves CPC classification schemas for multiple classifications.

This method uses the POST endpoint to retrieve classification data for multiple classification symbols in a single request.

Parameters:

  • classes: Slice of CPC classification symbols (max 100)
  • Each can be in any supported format: "A01", "A01B", "H04W84/18"

Returns XML containing classification hierarchies for all requested symbols.

Example:

classes := []string{"A01B", "H04W", "G06F17/30"}
schemas, err := client.GetClassificationSchemaMultiple(ctx, classes)

func (*Client) GetClassificationSchemaRaw added in v1.0.0

func (c *Client) GetClassificationSchemaRaw(ctx context.Context, class string, ancestors, navigation bool) (string, error)

GetClassificationSchemaRaw retrieves CPC classification schema hierarchy as raw XML.

Parameters:

  • class: CPC classification symbol (e.g., "A01B", "H04W84/18")
  • ancestors: If true, include ancestor classifications in the hierarchy
  • navigation: If true, include navigation links to related classifications

Returns raw XML response.

func (*Client) GetClassificationSchemaSubclassRaw added in v1.0.0

func (c *Client) GetClassificationSchemaSubclassRaw(ctx context.Context, class, subclass string, ancestors, navigation bool) (string, error)

GetClassificationSchemaSubclassRaw retrieves CPC classification schema for a specific subclass.

This is a more specific version of GetClassificationSchema that retrieves classification hierarchy for a specific class/subclass combination.

Parameters:

  • class: CPC class identifier (e.g., "A01B1")
  • subclass: CPC subclass identifier (e.g., "00")
  • ancestors: If true, include ancestor classifications in the hierarchy
  • navigation: If true, include navigation links to related classifications

Returns XML containing the subclass classification hierarchy.

Example:

// Get specific subclass hierarchy
schema, err := client.GetClassificationSchemaSubclass(ctx, "A01B1", "00", false, false)

func (*Client) GetClassificationStatisticsRaw added in v1.0.0

func (c *Client) GetClassificationStatisticsRaw(ctx context.Context, query string) (string, error)

GetClassificationStatisticsRaw searches for CPC classification statistics.

This method retrieves statistical information about patent counts across CPC classification codes. It allows searching for classification codes and returns the number of patents in each classification.

Parameters:

  • query: Search query for classification codes
  • Can be a keyword (e.g., "plastic", "wireless")
  • Can be a classification code (e.g., "H04W", "A01B")
  • Can use wildcard patterns

Returns XML or JSON containing:

  • Classification codes matching the query
  • Patent counts for each classification
  • Classification titles and descriptions

The response format depends on the Accept header sent by the client. By default, XML is returned.

Example:

// Search for statistics on "wireless" classifications
stats, err := client.GetClassificationStatistics(ctx, "wireless")
if err != nil {
    log.Fatal(err)
}

// Search for specific classification
stats, err := client.GetClassificationStatistics(ctx, "H04W")

func (*Client) GetDescription

func (c *Client) GetDescription(ctx context.Context, refType, format, number string) (*DescriptionData, error)

GetDescription retrieves the description for a patent.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns the description as an XML string.

func (*Client) GetDescriptionMultiple

func (c *Client) GetDescriptionMultiple(ctx context.Context, refType, format string, numbers []string) (*DescriptionData, error)

GetDescriptionMultiple retrieves descriptions for multiple patents (bulk operation).

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns parsed description data including paragraphs for all requested patents.

func (*Client) GetDescriptionRaw added in v1.0.0

func (c *Client) GetDescriptionRaw(ctx context.Context, refType, format, number string) (string, error)

GetDescriptionRaw retrieves patent description as raw XML. For parsed data, use GetDescription() instead.

func (*Client) GetExchangeDocuments added in v1.4.0

func (c *Client) GetExchangeDocuments(ctx context.Context, refType, format, number string) ([]ExchangeDocument, error)

GetExchangeDocuments retrieves bibliographic data and parses the full exchange-document(s). It is the comprehensive counterpart to GetBiblio (which returns the lighter BiblioData): it captures application/publication references in every format, parties incl. agents, classifications, priorities, citations and designations. Works for any published-data or family response.

func (*Client) GetFamily

func (c *Client) GetFamily(ctx context.Context, refType, format, number string) (*FamilyData, error)

GetFamily retrieves the INPADOC patent family for a given patent.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns parsed family data containing all family members with their bibliographic details.

INPADOC (International Patent Documentation) family includes all patents related through priority claims.

func (*Client) GetFamilyRaw added in v1.0.0

func (c *Client) GetFamilyRaw(ctx context.Context, refType, format, number string) (string, error)

GetFamilyRaw retrieves the INPADOC patent family as raw XML. For parsed data, use GetFamily() instead.

func (*Client) GetFamilyWithBiblio

func (c *Client) GetFamilyWithBiblio(ctx context.Context, refType, format, number string) (*FamilyData, error)

GetFamilyWithBiblio retrieves the INPADOC patent family with bibliographic data.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns parsed family data with bibliographic details for all family members.

func (*Client) GetFamilyWithBiblioMultiple

func (c *Client) GetFamilyWithBiblioMultiple(ctx context.Context, refType, format string, numbers []string) (*FamilyData, error)

GetFamilyWithBiblioMultiple retrieves INPADOC patent family with bibliographic data for multiple patents.

This method uses the POST endpoint to retrieve family data with bibliographic information for multiple patent numbers in a single request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns parsed family data with bibliographic details for all requested patents.

func (*Client) GetFamilyWithLegal

func (c *Client) GetFamilyWithLegal(ctx context.Context, refType, format, number string) (*FamilyData, error)

GetFamilyWithLegal retrieves the INPADOC patent family with legal status data.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns parsed family data with legal status events for all family members.

func (*Client) GetFamilyWithLegalMultiple

func (c *Client) GetFamilyWithLegalMultiple(ctx context.Context, refType, format string, numbers []string) (*FamilyData, error)

GetFamilyWithLegalMultiple retrieves INPADOC patent family with legal status data for multiple patents.

This method uses the POST endpoint to retrieve family data with legal status for multiple patent numbers in a single request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns parsed family data with legal status events for all requested patents.

func (*Client) GetFullCycleMultiple

func (c *Client) GetFullCycleMultiple(ctx context.Context, refType, format string, numbers []string) (string, error)

GetFullCycleMultiple retrieves full cycle data for multiple patents (bulk operation). Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Full cycle data includes the complete publication history and bibliographic evolution of a patent across different publication stages (e.g., A1, A2, B1, B2).

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML containing full cycle data for all requested patents.

func (*Client) GetFulltext

func (c *Client) GetFulltext(ctx context.Context, refType, format, number string) (*FulltextData, error)

GetFulltext retrieves the full text (biblio, abstract, description, claims) for a patent.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns parsed fulltext data including biblio, abstract, description, and claims.

func (*Client) GetFulltextMultiple

func (c *Client) GetFulltextMultiple(ctx context.Context, refType, format string, numbers []string) (*FulltextData, error)

GetFulltextMultiple retrieves fulltext data for multiple patents (bulk operation).

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns parsed fulltext data including biblio, abstract, description, and claims for all requested patents.

func (*Client) GetFulltextRaw added in v1.0.0

func (c *Client) GetFulltextRaw(ctx context.Context, refType, format, number string) (string, error)

GetFulltextRaw retrieves full text as raw XML. For parsed data, use GetFulltext() instead.

func (*Client) GetImage

func (c *Client) GetImage(ctx context.Context, country, number, kind, imageType string, page int) ([]byte, error)

GetImage retrieves a patent image (drawing page).

Parameters:

  • country: Two-letter country code (e.g., "EP", "US", "WO")
  • number: Patent number without country code (e.g., "2400812")
  • kind: Kind code (e.g., "A1", "B1")
  • imageType: Image type - use ImageTypeFullImage constant
  • page: Page number (1-based, e.g., 1)

Returns the image data as bytes (typically TIFF format).

Example:

imageData, err := client.GetImage(ctx, "EP", "2400812", "A1", ops.ImageTypeFullImage, 1)

Note: EPO typically returns images in TIFF format. Use tiffutil.TIFFToPNG() to convert to PNG format.

func (*Client) GetImageInquiry

func (c *Client) GetImageInquiry(ctx context.Context, refType, format, number string) (*ImageInquiry, error)

GetImageInquiry retrieves metadata about available images for a patent.

This method queries what images are available without downloading them. Use this to discover:

  • How many pages of drawings exist
  • What image formats are available (TIFF, PDF, PNG)
  • Document types (Drawing, FullDocument, FirstPageClipping)

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • number: Patent number (e.g., "EP1000000")

Returns an ImageInquiry struct with available image metadata.

Example:

inquiry, err := client.GetImageInquiry(ctx, ops.RefTypePublication, "docdb", "EP1000000")
if err != nil {
    log.Fatal(err)
}

// Then download the actual images
for _, instance := range inquiry.DocumentInstances {
    fmt.Printf("Found %s with %d pages\n", instance.Description, instance.NumberOfPages)
    for page := 1; page <= instance.NumberOfPages; page++ {
        img, _ := client.GetImage(ctx, "EP", "1000000", "B1", "fullimage", page)
        // Process image...
    }
}

func (*Client) GetImagePOST

func (c *Client) GetImagePOST(ctx context.Context, page int, identifier string) ([]byte, error)

GetImagePOST retrieves a patent image using POST method (keeps document identifier encrypted in body). This is identical to GetImage but uses POST instead of GET, keeping the document identifier in the encrypted request body rather than the URL. Both methods return one page at a time.

Parameters:

  • page: Page number to retrieve (1-based, e.g., 1)
  • identifier: Document identifier in format "CC/NNNNNNNN/KC/TYPE" (e.g., "EP/1000000/A1/fullimage", "EP/2400812/A1/drawing")

Returns the binary image data (TIFF, PDF, or PNG format) for the specified page.

Note: Despite the POST method, this does NOT retrieve multiple pages at once. Use the page parameter to iterate through pages one at a time.

Example:

// Get first page of full document
data, err := client.GetImagePOST(ctx, 1, "EP/1000000/A1/fullimage")

func (*Client) GetLastQuota

func (c *Client) GetLastQuota() *QuotaInfo

GetLastQuota returns the last quota information from API responses. Returns nil if no API calls have been made yet.

Quota tracking helps monitor fair use limits (4GB/week for non-paying users). The returned QuotaInfo includes:

  • Status: "green" (<50%), "yellow" (50-75%), "red" (>75%), "black" (blocked)
  • Individual: Quota for individual users
  • Registered: Quota for registered/paying users
  • Images: Separate quota for image downloads

func (*Client) GetLegal

func (c *Client) GetLegal(ctx context.Context, refType, format, number string) (*LegalData, error)

GetLegal retrieves parsed legal status data for a patent.

func (*Client) GetLegalMultiple

func (c *Client) GetLegalMultiple(ctx context.Context, refType, format string, numbers []string) (*LegalData, error)

GetLegalMultiple retrieves legal status data for multiple patents (bulk operation). Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns parsed legal status data for all requested patents.

func (*Client) GetLegalRaw added in v1.0.0

func (c *Client) GetLegalRaw(ctx context.Context, refType, format, number string) (string, error)

GetLegalRaw retrieves legal status data as raw XML. For parsed data, use GetLegal() instead.

func (*Client) GetPublishedEquivalents

func (c *Client) GetPublishedEquivalents(ctx context.Context, refType, format, number string) (*EquivalentsData, error)

GetPublishedEquivalents retrieves equivalent publications for a patent (simple family).

This returns the "simple family" - equivalent publications of the same invention (same priority claim). This is different from the INPADOC family which includes extended family members.

Parameters:

  • refType: Reference type (RefTypePublication, RefTypeApplication, or RefTypePriority)
  • format: Number format ("epodoc" or "docdb")
  • number: Patent number in specified format

Returns XML or JSON with equivalent publications.

Example:

equivalents, err := client.GetPublishedEquivalents(ctx, epo_ops.RefTypePublication, "epodoc", "EP1000000")

func (*Client) GetPublishedEquivalentsMultiple

func (c *Client) GetPublishedEquivalentsMultiple(ctx context.Context, refType, format string, numbers []string) (*EquivalentsData, error)

GetPublishedEquivalentsMultiple retrieves equivalent publications for multiple patents.

This method uses the POST endpoint to retrieve simple family data for multiple patent numbers in a single request.

Parameters:

  • refType: Reference type (RefTypePublication, RefTypeApplication, or RefTypePriority)
  • format: Number format ("epodoc" or "docdb")
  • numbers: Slice of patent numbers (max 100)

Returns parsed equivalents data for all requested patents.

func (*Client) GetPublishedEquivalentsRaw added in v1.0.0

func (c *Client) GetPublishedEquivalentsRaw(ctx context.Context, refType, format, number string) (string, error)

GetPublishedEquivalentsRaw retrieves equivalent publications as raw XML. For parsed data, use GetPublishedEquivalents() instead.

func (*Client) GetRegister added in v1.4.0

func (c *Client) GetRegister(ctx context.Context, refType, format, number string) ([]RegisterDocument, error)

GetRegister retrieves the full EP Register record (bibliographic data, EP patent statuses, term of grant, opposition) for a patent. Use GetRegisterEvents for the lighter events-only view.

func (*Client) GetRegisterBiblioMultipleRaw added in v1.0.0

func (c *Client) GetRegisterBiblioMultipleRaw(ctx context.Context, refType, format string, numbers []string) (string, error)

GetRegisterBiblioMultipleRaw retrieves bibliographic data from the EPO Register for multiple patents. Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML containing EPO Register bibliographic data for all requested patents.

func (*Client) GetRegisterBiblioRaw added in v1.0.0

func (c *Client) GetRegisterBiblioRaw(ctx context.Context, refType, format, number string) (string, error)

GetRegisterBiblioRaw retrieves bibliographic data from the EPO Register.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns EPO Register bibliographic data as XML.

Note: The EPO Register contains more detailed and up-to-date information than the standard bibliographic service.

func (*Client) GetRegisterEvents

func (c *Client) GetRegisterEvents(ctx context.Context, refType, format, number string) (*RegisterEventsData, error)

GetRegisterEvents retrieves and parses procedural events from the EPO Register. Returns a parsed RegisterEventsData struct with patent statuses and dossier events.

func (*Client) GetRegisterEventsMultipleRaw added in v1.0.0

func (c *Client) GetRegisterEventsMultipleRaw(ctx context.Context, refType, format string, numbers []string) (string, error)

GetRegisterEventsMultipleRaw retrieves procedural events from the EPO Register for multiple patents. Uses POST endpoint for efficient batch retrieval of up to 100 patents in one request.

Parameters:

  • refType: Reference type (e.g., RefTypePublication, RefTypeApplication, RefTypePriority)
  • format: Number format (e.g., FormatDocDB, FormatEPODOC)
  • numbers: Slice of patent numbers (max 100)

Returns XML containing EPO Register events for all requested patents.

func (*Client) GetRegisterEventsRaw added in v1.0.0

func (c *Client) GetRegisterEventsRaw(ctx context.Context, refType, format, number string) (string, error)

GetRegisterEventsRaw retrieves procedural events from the EPO Register as raw XML.

Parameters:

  • refType: Reference type (e.g., "publication", "application", "priority")
  • format: Number format (e.g., "docdb", "epodoc")
  • number: Patent number (e.g., "EP1000000")

Returns EPO Register events as XML.

func (*Client) GetRegisterProceduralSteps

func (c *Client) GetRegisterProceduralSteps(ctx context.Context, refType, format, number string) ([]RegisterDocument, error)

GetRegisterProceduralSteps retrieves the EP Register procedural-step log (typed).

func (*Client) GetRegisterProceduralStepsMultipleRaw added in v1.0.0

func (c *Client) GetRegisterProceduralStepsMultipleRaw(ctx context.Context, refType, _ string, numbers []string) (string, error)

GetRegisterProceduralStepsMultipleRaw retrieves procedural steps for multiple patent numbers.

This method uses the POST endpoint to retrieve procedural step data for multiple patent numbers in a single request.

Parameters:

  • refType: Reference type ("publication" or "application")
  • format: Number format ("epodoc" only)
  • numbers: Slice of patent numbers (max 100)

Returns XML containing procedural steps for all requested patents.

Example:

numbers := []string{"EP1000000", "EP1000001", "EP1000002"}
steps, err := client.GetRegisterProceduralStepsMultiple(ctx, "publication", "epodoc", numbers)

func (*Client) GetRegisterProceduralStepsRaw added in v1.0.0

func (c *Client) GetRegisterProceduralStepsRaw(ctx context.Context, refType, _, number string) (string, error)

GetRegisterProceduralStepsRaw retrieves procedural steps from the EPO Register.

Procedural steps provide detailed information about the procedural history of a patent application, including milestones, deadlines, and administrative actions.

Parameters:

  • refType: Reference type ("publication" or "application")
  • format: Number format ("epodoc" only)
  • number: Patent number (e.g., "EP1000000")

Returns XML containing:

  • Procedural step history
  • Step dates and descriptions
  • Administrative actions
  • Milestone information

Example:

// Get procedural steps for a publication
steps, err := client.GetRegisterProceduralSteps(ctx, "publication", "epodoc", "EP1000000")
if err != nil {
    log.Fatal(err)
}

func (*Client) GetRegisterUNIP

func (c *Client) GetRegisterUNIP(ctx context.Context, refType, format, number string) ([]RegisterDocument, error)

GetRegisterUNIP retrieves the Unitary Patent register record (typed).

func (*Client) GetRegisterUNIPMultipleRaw added in v1.0.0

func (c *Client) GetRegisterUNIPMultipleRaw(ctx context.Context, refType, format string, numbers []string) (string, error)

GetRegisterUNIPMultipleRaw retrieves unitary patent package (UPP) information for multiple patents.

Parameters:

  • refType: Reference type (RefTypePublication or RefTypeApplication)
  • format: Number format (must be "epodoc")
  • numbers: List of patent numbers (max 100)

Returns XML or JSON with unitary patent information for all requested patents.

Example:

numbers := []string{"EP3000000", "EP3000001"}
unip, err := client.GetRegisterUNIPMultiple(ctx, epo_ops.RefTypePublication, "epodoc", numbers)

func (*Client) GetRegisterUNIPRaw added in v1.0.0

func (c *Client) GetRegisterUNIPRaw(ctx context.Context, refType, _, number string) (string, error)

GetRegisterUNIPRaw retrieves unitary patent package (UPP) information from the EPO Register.

Parameters:

  • refType: Reference type (RefTypePublication or RefTypeApplication)
  • format: Number format (must be "epodoc")
  • number: Patent number in specified format

Returns XML or JSON with unitary patent information including:

  • Unified Patent Court opt-out status
  • Unitary effect registration
  • Participating member states

Example:

unip, err := client.GetRegisterUNIP(ctx, epo_ops.RefTypePublication, "epodoc", "EP3000000")

func (*Client) GetUsageStats

func (c *Client) GetUsageStats(ctx context.Context, timeRange string) (*UsageStats, error)

GetUsageStats retrieves usage statistics from the EPO OPS Data Usage API.

The Data Usage API provides historical usage data for quota monitoring and analysis. Usage statistics are updated within 10 minutes of each hour and aligned on midnight UTC/GMT boundaries. This API does not count against quotas.

Parameters:

  • timeRange: Time range in one of two formats:
  • Single date: "dd/mm/yyyy" (e.g., "01/01/2024")
  • Date range: "dd/mm/yyyy~dd/mm/yyyy" (e.g., "01/01/2024~07/01/2024")

Returns:

  • UsageStats containing usage entries with timestamps, response sizes, and message counts
  • error if the time range format is invalid or the request fails

Example:

// Get usage for a specific date
stats, err := client.GetUsageStats(ctx, "01/01/2024")
if err != nil {
    log.Fatal(err)
}

// Get usage for a date range
stats, err := client.GetUsageStats(ctx, "01/01/2024~07/01/2024")
for _, entry := range stats.Entries {
    fmt.Printf("Time: %d, Size: %d bytes, Messages: %d\n",
        entry.Timestamp, entry.TotalResponseSize, entry.MessageCount)
}

func (*Client) Search

func (c *Client) Search(ctx context.Context, query string, rangeStr string) (*SearchResultData, error)

Search performs a bibliographic search using CQL (Contextual Query Language).

Parameters:

  • query: CQL query string (e.g., "ti=plastic", "pa=Siemens and de")
  • rangeStr: Optional range in format "1-25" (default: "1-25")

Returns the search results as XML containing matching patents.

Example queries:

  • "ti=plastic" - Title contains "plastic"
  • "pa=Siemens" - Applicant is Siemens
  • "de" - Country code DE
  • "ti=plastic and pa=Siemens" - Combined search

See OPS documentation for full CQL syntax.

func (*Client) SearchRaw added in v1.0.0

func (c *Client) SearchRaw(ctx context.Context, query string, rangeStr string) (string, error)

SearchRaw performs a bibliographic search and returns raw XML. For parsed data, use Search() instead.

func (*Client) SearchRegister

func (c *Client) SearchRegister(ctx context.Context, query, rangeSpec string) (string, error)

SearchRegister searches the EPO Register for patents matching a query.

Parameters:

  • query: Search query (e.g., "ti=plastic", "applicant=google")
  • rangeSpec: Optional range specification (e.g., "1-25", "26-50"). Empty string uses default (1-25).

The query parameter supports various search fields including:

  • ti (title), ab (abstract), ta (title and abstract)
  • applicant, inventor
  • pn (publication number), an (application number)
  • pd (publication date), ad (application date)
  • cl (classification)

Returns XML or JSON with matching register entries including bibliographic data.

Example:

results, err := client.SearchRegister(ctx, "ti=battery AND applicant=tesla", "1-100")

func (*Client) SearchRegisterWithConstituent

func (c *Client) SearchRegisterWithConstituent(ctx context.Context, constituent, query, rangeSpec string) (string, error)

SearchRegisterWithConstituent searches the EPO Register and returns specific constituent data.

Parameters:

  • constituent: The type of data to return ("biblio", "events", "procedural-steps", "upp")
  • query: Search query (e.g., "ti=plastic", "applicant=google")
  • rangeSpec: Optional range specification (e.g., "1-25"). Empty string uses default (1-25).

Constituents:

  • "biblio": Bibliographic data
  • "events": Legal events
  • "procedural-steps": Procedural step information
  • "upp": Unified Patent Package data

Returns XML or JSON with matching register entries for the specified constituent.

Example:

// Search for patents and get legal events
events, err := client.SearchRegisterWithConstituent(ctx, "events", "applicant=tesla", "1-50")

func (*Client) SearchWithConstituent

func (c *Client) SearchWithConstituent(ctx context.Context, constituent, query string, rangeStr string) (*SearchResultData, error)

SearchWithConstituent performs a bibliographic search with specific constituent.

Parameters:

  • constituent: The constituent to retrieve (e.g., "biblio", "abstract", "full-cycle")
  • query: CQL query string
  • rangeStr: Optional range in format "1-25"

Returns parsed search results with the requested constituent data.

type Config

type Config struct {
	// BaseURL is the base URL for the OPS API.
	// Default: "https://ops.epo.org/3.2/rest-services"
	BaseURL string

	// AuthURL is the OAuth2 token endpoint URL.
	// Default: "https://ops.epo.org/3.2/auth/accesstoken"
	// This field is primarily for testing purposes.
	AuthURL string

	// ConsumerKey is the OAuth2 consumer key (required).
	ConsumerKey string

	// ConsumerSecret is the OAuth2 consumer secret (required).
	ConsumerSecret string

	// MaxRetries is the maximum number of retries for failed requests.
	// Default: 3
	MaxRetries int

	// RetryDelay is the base delay between retries.
	// Default: 1 second
	RetryDelay time.Duration

	// Timeout is the HTTP client timeout.
	// Default: 30 seconds
	Timeout time.Duration
}

Config holds configuration for the EPO OPS client.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a Config with default values.

type ConfigError

type ConfigError struct {
	Message string
}

ConfigError represents a configuration error.

func (*ConfigError) Error

func (e *ConfigError) Error() string

type DataValidationError added in v1.0.0

type DataValidationError struct {
	Parser       string // e.g., "ParseFamily", "ParseLegal"
	MissingField string // Name of the missing or invalid field
	Message      string // Description of what's wrong
}

DataValidationError represents an error when parsed data is incomplete or invalid. This occurs when XML unmarshaling succeeds but the resulting data structure is missing required fields or contains invalid values.

func (*DataValidationError) Error added in v1.0.0

func (e *DataValidationError) Error() string

type DescriptionData added in v1.0.0

type DescriptionData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	Country      string
	DocNumber    string
	Kind         string
	Language     string
	Paragraphs   []Paragraph
}

DescriptionData represents parsed description data

func ParseDescription added in v1.0.0

func ParseDescription(xmlData string) (*DescriptionData, error)

ParseDescription parses description XML into structured data

type DesignationOfStates added in v1.4.0

type DesignationOfStates struct {
	EPCContracting []string `xml:"designation-epc>contracting-states>country"`
	EPCExtension   []string `xml:"designation-epc>extension-states>country"`
	PCTRegional    []string `xml:"designation-pct>regional>country"`
	PCTNational    []string `xml:"designation-pct>national>country"`
	Contracting    []string `xml:"contracting-states>country"`
}

DesignationOfStates captures designated contracting/extension/validation states.

type DocumentID added in v1.4.0

type DocumentID struct {
	Type      string `xml:"document-id-type,attr"`
	Country   string `xml:"country"`
	DocNumber string `xml:"doc-number"`
	Kind      string `xml:"kind"`
	Name      string `xml:"name"`
	Date      string `xml:"date"`
}

DocumentID is one <document-id> within a reference, citation or priority claim.

type DocumentInstance

type DocumentInstance struct {
	// Description is a human-readable description of the document type
	// Examples: "Drawing", "FullDocument", "FirstPageClipping"
	Description string

	// Link is the URL to retrieve this document instance
	Link string

	// NumberOfPages is the total number of pages in this document instance
	NumberOfPages int

	// Formats lists the available formats for this document instance
	// Examples: ["pdf", "tiff"], ["application/pdf", "image/tiff"]
	Formats []string

	// DocType is the internal document type identifier
	// Examples: "Drawing", "FullDocument"
	DocType string
}

DocumentInstance represents a single document type available for a patent. For example, a patent might have separate instances for drawings and full document.

type EPStatus added in v1.4.0

type EPStatus struct {
	ChangeDate string `xml:"change-date,attr"`
	Code       string `xml:"status-code,attr"`
	Text       string `xml:",chardata"`
}

EPStatus is one ep-patent-status entry (the register's own status timeline).

type EquivalentPatent added in v1.0.0

type EquivalentPatent struct {
	Country   string
	DocNumber string
	Kind      string
}

EquivalentPatent represents an equivalent patent

type EquivalentsData added in v1.0.0

type EquivalentsData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	Equivalents  []EquivalentPatent
}

EquivalentsData represents published equivalents inquiry results

func ParseEquivalents added in v1.0.0

func ParseEquivalents(xmlData string) (*EquivalentsData, error)

ParseEquivalents parses equivalents inquiry XML into structured data

type ExchangeDocument added in v1.4.0

type ExchangeDocument struct {
	DocID     string            `xml:"doc-id,attr"`
	System    string            `xml:"system,attr"`
	FamilyID  string            `xml:"family-id,attr"`
	Country   string            `xml:"country,attr"`
	DocNumber string            `xml:"doc-number,attr"`
	Kind      string            `xml:"kind,attr"`
	Status    string            `xml:"status,attr"`
	DatePubl  string            `xml:"date-publ,attr"`
	Biblio    BibliographicData `xml:"bibliographic-data"`
	Abstracts []Abstract        `xml:"abstract"`
}

ExchangeDocument is one <exchange-document> with its bibliographic data and abstracts.

func ParseExchangeDocuments added in v1.4.0

func ParseExchangeDocuments(xmlData string) ([]ExchangeDocument, error)

ParseExchangeDocuments extracts every <exchange-document> element from an OPS response, regardless of nesting (published-data, family, search). It is the comprehensive counterpart to the narrow per-endpoint parsers. A response with no exchange-document yields an empty slice and a nil error; only malformed XML returns an error.

func (ExchangeDocument) ApplicationNumber added in v1.4.0

func (e ExchangeDocument) ApplicationNumber(prefer ...string) string

ApplicationNumber returns the application number, preferring the originating-office ("original") number national offices look up by, then docdb.

func (ExchangeDocument) PublicationNumber added in v1.4.0

func (e ExchangeDocument) PublicationNumber(prefer ...string) string

PublicationNumber returns the publication number for the first preferred format (default docdb then epodoc).

func (ExchangeDocument) Title added in v1.4.0

func (e ExchangeDocument) Title(langs ...string) string

Title returns the invention title, preferring the given languages (default "en").

type FamilyData added in v1.0.0

type FamilyData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	FamilyID     string
	TotalCount   int
	Legal        bool
	Countries    []string // Unique country codes from all members, sorted alphabetically
	Members      []FamilyMember
}

FamilyData represents parsed patent family data

func ParseFamily added in v1.0.0

func ParseFamily(xmlData string) (*FamilyData, error)

ParseFamily parses patent family XML into structured data

type FamilyMember added in v1.0.0

type FamilyMember struct {
	FamilyID       string
	Country        string
	DocNumber      string
	Kind           string
	Date           string
	Title          string   // Invention title (populated from biblio data, English preferred)
	Applicants     []string // Applicant names (populated from biblio data, epodoc format)
	ApplicationRef ApplicationReference
	PriorityClaims []PriorityClaim
}

FamilyMember represents a single member of a patent family

type ForbiddenError added in v1.3.0

type ForbiddenError struct {
	StatusCode int
	Message    string
}

ForbiddenError represents an HTTP 403 response that is not a quota or rate limit condition (e.g. the account lacks access to the requested resource).

func (*ForbiddenError) Error added in v1.3.0

func (e *ForbiddenError) Error() string

type FulltextData added in v1.0.0

type FulltextData struct {
	XMLName     xml.Name `xml:"world-patent-data"`
	Country     string
	DocNumber   string
	Kind        string
	Language    string
	Status      string
	Biblio      *BiblioData
	Abstract    *AbstractData
	Description *DescriptionData
	Claims      *ClaimsData
}

FulltextData represents complete fulltext document data

func ParseFulltext added in v1.0.0

func ParseFulltext(xmlData string) (*FulltextData, error)

ParseFulltext parses fulltext XML into structured data by reusing existing parsers

type ImageInquiry

type ImageInquiry struct {
	// DocumentInstances contains the list of available document types and their metadata
	DocumentInstances []DocumentInstance
}

ImageInquiry represents the response from an image inquiry request. It contains information about available images for a patent document.

func ParseImageInquiry

func ParseImageInquiry(xmlData string) (*ImageInquiry, error)

ParseImageInquiry parses image inquiry XML into structured data.

This function processes the XML response from the EPO OPS Published Images Inquiry service and extracts information about available document instances (drawings, full document, etc.), their page counts, available formats, and download links.

Example XML structure:

<ops:world-patent-data>
  <ops:document-inquiry>
    <ops:inquiry-result>
      <ops:document-instance desc="Drawing" number-of-pages="5" doc-type="Drawing">
        <ops:document-instance-link href="..."/>
        <ops:document-format-options>
          <ops:document-format>application/pdf</ops:document-format>
          <ops:document-format>image/tiff</ops:document-format>
        </ops:document-format-options>
      </ops:document-instance>
    </ops:inquiry-result>
  </ops:document-inquiry>
</ops:world-patent-data>

type Inventor added in v1.4.0

type Inventor struct {
	Sequence   string `xml:"sequence,attr"`
	DataFormat string `xml:"data-format,attr"`
	Name       string `xml:"inventor-name>name"`
	Residence  string `xml:"residence>country"`
}

Inventor is one inventor party (repeated per data-format).

type LegalData added in v1.0.0

type LegalData struct {
	XMLName      xml.Name `xml:"world-patent-data"`
	PatentNumber string
	FamilyID     string
	LegalEvents  []LegalEvent
}

LegalData represents parsed legal event data

func ParseLegal added in v1.0.0

func ParseLegal(xmlData string) (*LegalData, error)

ParseLegal parses legal event XML into structured data

type LegalEvent added in v1.0.0

type LegalEvent struct {
	Code        string
	Description string
	Influence   string
	DateMigr    string
	Country     string            // Country code from L001EP field
	Date        string            // Gazette date from L007EP field
	EventCode   string            // Legal event code from L008EP field
	Fields      map[string]string // All L-code field values
}

LegalEvent represents a single legal event

type MilestoneDates added in v1.4.0

type MilestoneDates map[string]string

MilestoneDates maps register milestone names (e.g. request-for-examination, first-examination-report-despatched) to their dates, captured from dates-rights-effective. A map keeps the parser robust to the open-ended set of milestone elements.

func (*MilestoneDates) UnmarshalXML added in v1.4.0

func (m *MilestoneDates) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML records each child milestone element under its local name with its date.

type NationalClassification added in v1.4.0

type NationalClassification struct {
	Country string   `xml:"country"`
	Main    string   `xml:"main-classification"`
	Further []string `xml:"further-classification"`
	Text    []string `xml:"text"`
}

NationalClassification is a classification-national entry.

type NotFoundError

type NotFoundError struct {
	Resource string
	Message  string
}

NotFoundError represents a 404 error (document doesn't exist).

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

type NotImplementedError

type NotImplementedError struct {
	Message string
}

NotImplementedError represents a not-yet-implemented feature.

func (*NotImplementedError) Error

func (e *NotImplementedError) Error() string

type Nplcit added in v1.4.0

type Nplcit struct {
	Num  string `xml:"num,attr"`
	Text string `xml:"text"`
}

Nplcit is a cited non-patent-literature document.

type NumberConversionData added in v1.0.0

type NumberConversionData struct {
	InputFormat  string
	OutputFormat string
	Country      string
	DocNumber    string
	Kind         string
	Date         string
}

NumberConversionData represents parsed patent number conversion data

func ParseNumberConversion added in v1.0.0

func ParseNumberConversion(xmlData string) (*NumberConversionData, error)

ParseNumberConversion parses EPO number conversion XML into a NumberConversionData struct.

type OPSError

type OPSError struct {
	HTTPStatus int    // HTTP status code
	Code       string // EPO error code (e.g., "CLIENT.InvalidReference", "SERVER.EntityNotFound")
	Message    string // Human-readable error message
	MoreInfo   string // Optional URL with more information
}

OPSError represents a structured error response from EPO OPS API. The EPO OPS API returns errors in XML format with a code, message, and optional moreInfo URL.

func (*OPSError) Error

func (e *OPSError) Error() string

type OppositionData added in v1.4.0

type OppositionData struct {
	ChangeDate  string    `xml:"change-date,attr"`
	GazetteNum  string    `xml:"change-gazette-num,attr"`
	NotFiledTag *struct{} `xml:"opposition-not-filed"`
}

OppositionData captures opposition status (presence of an opposition-not-filed marker).

func (*OppositionData) NotFiled added in v1.4.0

func (o *OppositionData) NotFiled() bool

NotFiled reports whether the register states no opposition was filed.

type Paragraph added in v1.0.0

type Paragraph struct {
	ID   string
	Num  string
	Text string
}

Paragraph represents a description paragraph

type Party

type Party struct {
	Name    string
	Country string
}

Party represents an applicant or inventor

type Patcit added in v1.4.0

type Patcit struct {
	Num         string       `xml:"num,attr"`
	DnumType    string       `xml:"dnum-type,attr"`
	Text        string       `xml:"text"`
	DocumentIDs []DocumentID `xml:"document-id"`
}

Patcit is a cited patent document.

func (Patcit) Number added in v1.4.0

func (p Patcit) Number(prefer ...string) string

Number assembles the cited patent number for the first matching format.

type PatentClassification added in v1.4.0

type PatentClassification struct {
	Sequence string `xml:"sequence,attr"`
	Scheme   struct {
		Office string `xml:"office,attr"`
		Name   string `xml:"scheme,attr"`
	} `xml:"classification-scheme"`
	Section          string `xml:"section"`
	Class            string `xml:"class"`
	Subclass         string `xml:"subclass"`
	MainGroup        string `xml:"main-group"`
	Subgroup         string `xml:"subgroup"`
	Value            string `xml:"classification-value"`
	GeneratingOffice string `xml:"generating-office"`
}

PatentClassification is one CPC (or other unified-scheme) classification.

func (PatentClassification) Symbol added in v1.4.0

func (p PatentClassification) Symbol() string

Symbol renders the classification as e.g. "H04W84/20", or "" if unpopulated.

type PatentNumber

type PatentNumber struct {
	// Country is the two-letter country code (e.g., "EP", "US", "DE").
	// Empty if the input doesn't contain a valid country code.
	Country string

	// Number is the numeric/alphanumeric portion of the patent number.
	// Empty if no valid number portion is found.
	Number string

	// Kind is the kind code (e.g., "A1", "B1", "C").
	// Empty if the patent number is invalid.
	Kind string
}

PatentNumber represents the parsed components of a patent number.

func ParsePatentNumber

func ParsePatentNumber(number string) PatentNumber

ParsePatentNumber splits a patent number into its components: country code, number, and kind code.

Patent number format rules:

  • Minimum length: 4 characters (CCnK format)
  • First two characters (A-Z, a-z) are the country code (CC)
  • Followed by the number portion (n) - can start with A-Z, a-z and must contain at least one 0-9
  • Followed by REQUIRED kind code (K) - 1-2 chars, always starts with A-Z, a-z, always at the end

Examples:

  • "EP2400812A1" -> {Country: "EP", Number: "2400812", Kind: "A1"}
  • "DE123C" -> {Country: "DE", Number: "123", Kind: "C"}
  • "DE123C1" -> {Country: "DE", Number: "123", Kind: "C1"}
  • "USD123456S1" -> {Country: "US", Number: "D123456", Kind: "S1"}

Invalid examples (return empty PatentNumber):

  • "DE123" -> {Country: "", Number: "", Kind: ""} (missing kind code)
  • "123C" -> {Country: "", Number: "", Kind: ""} (no country code)
  • "D123C" -> {Country: "", Number: "", Kind: ""} (country code too short)
  • "DEC" -> {Country: "", Number: "", Kind: ""} (no number portion)

type PatentStatus added in v1.0.0

type PatentStatus struct {
	Date        string // Status change date (YYYYMMDD)
	Code        string // Status code (e.g., "7", "8")
	Description string // Human-readable description
}

PatentStatus represents a patent status entry from the EPO Register

type Priority added in v1.4.0

type Priority struct {
	Sequence    string       `xml:"sequence,attr"`
	Kind        string       `xml:"kind,attr"`
	DataFormat  string       `xml:"data-format,attr"`
	Active      string       `xml:"priority-active-indicator"`
	DocumentIDs []DocumentID `xml:"document-id"`
}

Priority is a priority-claims/priority-claim entry.

type PriorityClaim added in v1.0.0

type PriorityClaim struct {
	Country   string
	DocNumber string
	Kind      string
	Date      string
	Sequence  string
	Active    string
}

PriorityClaim represents a priority claim for a family member

type ProceduralStep added in v1.4.0

type ProceduralStep struct {
	ID    string   `xml:"id,attr"`
	Phase string   `xml:"procedure-step-phase,attr"`
	Code  string   `xml:"procedural-step-code"`
	Texts []string `xml:"procedural-step-text"`
	Date  string   `xml:"procedural-step-date>date"`
}

ProceduralStep is one procedural-data/procedural-step (the prosecution step log).

type QuotaExceededError

type QuotaExceededError struct {
	Message string
}

QuotaExceededError represents a fair use quota limit error.

func (*QuotaExceededError) Error

func (e *QuotaExceededError) Error() string

type QuotaInfo

type QuotaInfo struct {
	// Status indicates the overall quota status.
	// Possible values: "green" (<50%), "yellow" (50-75%), "red" (>75%), "black" (blocked)
	Status string

	// Individual quota for individual users (4GB/week for non-paying users)
	Individual QuotaMetric

	// Registered quota for registered users (>4GB/week for paying users)
	Registered QuotaMetric

	// Images quota (separate quota for image downloads)
	Images QuotaMetric

	// Raw header values for debugging
	ThrottlingControl string
	IndividualHeader  string
	RegisteredHeader  string
}

QuotaInfo contains quota information from EPO OPS API responses.

func ParseQuotaHeaders

func ParseQuotaHeaders(headers http.Header) *QuotaInfo

ParseQuotaHeaders extracts quota information from HTTP response headers.

EPO OPS returns quota information in these headers:

  • X-Throttling-Control: Overall status (e.g., "green", "yellow", "red", "black")
  • X-IndividualQuota: Individual quota in format "used=123,quota=456"
  • X-RegisteredQuota: Registered quota in format "used=123,quota=456"
  • X-ImagesQuota: Images quota in format "used=123,quota=456" (optional)

type QuotaMetric

type QuotaMetric struct {
	// Used is the amount of quota consumed
	Used int

	// Limit is the maximum quota allowed
	Limit int
}

QuotaMetric represents a quota metric with used and limit values.

func (*QuotaMetric) UsagePercent

func (q *QuotaMetric) UsagePercent() float64

UsagePercent calculates the usage percentage (0-100).

type Reference added in v1.4.0

type Reference struct {
	Sequence    string       `xml:"sequence,attr"`
	DataFormat  string       `xml:"data-format,attr"`
	DocID       string       `xml:"doc-id,attr"`
	DocumentIDs []DocumentID `xml:"document-id"`
}

Reference is a publication-reference or application-reference: one element carrying one document-id per available format.

func (Reference) ByType added in v1.4.0

func (r Reference) ByType(format string) string

ByType returns the doc-number for a given format (document-id-type), tolerating the bulk DOCDB serialization where the format lives on the reference's data-format attribute.

type RegisterBiblio added in v1.4.0

type RegisterBiblio struct {
	BibliographicData
	TermsOfGrant   []TermOfGrant   `xml:"term-of-grant"`
	Opposition     *OppositionData `xml:"opposition-data"`
	MilestoneDates MilestoneDates  `xml:"dates-rights-effective"`
	SearchReports  []SearchReport  `xml:"search-reports-information>search-report-information"`
}

RegisterBiblio is the register's bibliographic-data: the shared exchange fields (embedded) plus register-specific children (term of grant, opposition, milestone dates, search reports).

type RegisterDocument added in v1.4.0

type RegisterDocument struct {
	ID        string `xml:"id,attr"`
	Status    string `xml:"status,attr"`
	Lang      string `xml:"lang,attr"`
	Country   string `xml:"country,attr"`
	DocNumber string `xml:"doc-number,attr"`
	Kind      string `xml:"kind,attr"`

	Statuses        []EPStatus       `xml:"ep-patent-statuses>ep-patent-status"`
	Biblio          RegisterBiblio   `xml:"bibliographic-data"`
	ProceduralSteps []ProceduralStep `xml:"procedural-data>procedural-step"`
}

RegisterDocument is one EP Register record. Biblio carries the bibliographic data (references, parties, title, classifications, citations, designations, term of grant); the remaining fields are register-specific (statuses, procedural steps).

func ParseRegister added in v1.4.0

func ParseRegister(xmlData string) ([]RegisterDocument, error)

ParseRegister extracts every <register-document> from a register response (biblio, events, procedural-steps or unip constituent), capturing the full record rather than only events. A response with no register-document yields an empty slice and a nil error; only malformed XML returns an error.

type RegisterEvent added in v1.0.0

type RegisterEvent struct {
	ID          string // Event identifier (e.g., "EVT_434577438")
	Date        string // Event date (YYYYMMDD)
	EventCode   string // Event code (e.g., "0009250", "EPIDOSNIGR1")
	Description string // Human-readable description
	Category    string // Categorized: filing, publication, examination, grant, opposition, appeal, other
	GazetteNum  string // Gazette number (e.g., "2022/32"), empty if not available
	GazetteDate string // Gazette date (YYYYMMDD), empty if not available
}

RegisterEvent represents a single dossier event from the EPO Register

type RegisterEventsData added in v1.0.0

type RegisterEventsData struct {
	PatentNumber string
	Query        string
	Statuses     []PatentStatus
	Events       []RegisterEvent
}

RegisterEventsData represents parsed register events data

func ParseRegisterEvents added in v1.0.0

func ParseRegisterEvents(xmlData string) (*RegisterEventsData, error)

ParseRegisterEvents parses EPO Register events XML into a RegisterEventsData struct.

type SearchReport added in v1.4.0

type SearchReport struct {
	Country   string `xml:"search-report-publication>document-id>country"`
	DocNumber string `xml:"search-report-publication>document-id>doc-number"`
	Kind      string `xml:"search-report-publication>document-id>kind"`
	Date      string `xml:"search-report-publication>document-id>date"`
}

SearchReport references a search-report publication (search-reports-information entry).

type SearchResult added in v1.0.0

type SearchResult struct {
	System    string
	FamilyID  string
	Country   string
	DocNumber string
	Kind      string
	Title     string
}

SearchResult represents a single search result

type SearchResultData added in v1.0.0

type SearchResultData struct {
	XMLName    xml.Name `xml:"world-patent-data"`
	Query      string
	TotalCount int
	RangeBegin int
	RangeEnd   int
	Results    []SearchResult
}

SearchResultData represents search results with pagination

func ParseSearch added in v1.0.0

func ParseSearch(xmlData string) (*SearchResultData, error)

ParseSearch parses search result XML into structured data. Handles both formats: with constituents (exchange-documents) and without (publication-reference).

type ServiceUnavailableError

type ServiceUnavailableError struct {
	StatusCode int
	Message    string
	RetryAfter string // Optional Retry-After header value
}

ServiceUnavailableError represents a temporary service outage.

func (*ServiceUnavailableError) Error

func (e *ServiceUnavailableError) Error() string

type TermOfGrant added in v1.4.0

type TermOfGrant struct {
	ChangeDate        string   `xml:"change-date,attr"`
	GazetteNum        string   `xml:"change-gazette-num,attr"`
	LapsedInCountries []string `xml:"lapsed-in-country"`
}

TermOfGrant is a term-of-grant entry (lapse / term changes per country).

type Title added in v1.4.0

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

Title is one invention-title in a given language.

type UsageEntry

type UsageEntry struct {
	// Timestamp is the Unix timestamp (seconds since epoch) for this entry
	Timestamp int64

	// TotalResponseSize is the total size of API responses in bytes for this period
	TotalResponseSize int64

	// MessageCount is the number of API requests made during this period
	MessageCount int

	// Service identifies which OPS service was used (optional field)
	Service string
}

UsageEntry represents a single usage data point.

Each entry corresponds to an hour of usage, with data updated within 10 minutes of the hour boundary.

type UsageStats

type UsageStats struct {
	// TimeRange is the requested time range (dd/mm/yyyy or dd/mm/yyyy~dd/mm/yyyy)
	TimeRange string

	// Entries contains usage data points, typically one per hour
	Entries []UsageEntry
}

UsageStats represents usage statistics from the EPO OPS Data Usage API.

The Data Usage API endpoint (/3.2/developers/me/stats/usage) provides historical usage data for quota monitoring and analysis.

Usage statistics are updated within 10 minutes of each hour and aligned on midnight UTC/GMT boundaries. This API does not count against quotas.

Example usage:

// Get usage for a specific date
stats, err := client.GetUsageStats(ctx, "01/01/2024")

// Get usage for a date range
stats, err := client.GetUsageStats(ctx, "01/01/2024~07/01/2024")

type ValidationError

type ValidationError struct {
	Field   string // Field name that failed validation (e.g., "number", "format", "date")
	Format  string // Expected format (e.g., "docdb", "epodoc")
	Value   string // The invalid value provided
	Message string // Human-readable error message
}

ValidationError represents an input validation error. This is returned when user-provided input doesn't match the expected format.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type XMLParseError added in v1.0.0

type XMLParseError struct {
	Parser    string // e.g., "ParseFamily", "ParseLegal"
	Element   string // e.g., "family-member", "legal-event"
	XMLSample string // First 200 chars of problematic XML
	Cause     error  // Underlying error from xml.Unmarshal
}

XMLParseError represents an error during XML parsing. This error provides context about what failed during XML unmarshaling including the parser name, problematic element, and a sample of the XML.

func (*XMLParseError) Error added in v1.0.0

func (e *XMLParseError) Error() string

func (*XMLParseError) Unwrap added in v1.0.0

func (e *XMLParseError) Unwrap() error

Directories

Path Synopsis
Package cql parses and validates EPO OPS Contextual CQLQuery Language (CQL) search queries.
Package cql parses and validates EPO OPS Contextual CQLQuery Language (CQL) search queries.
Package generated provides primitives to interact with the openapi HTTP API.
Package generated provides primitives to interact with the openapi HTTP API.
Package tiffutil provides utilities for TIFF image handling, specifically for converting EPO patent TIFF images to PNG format.
Package tiffutil provides utilities for TIFF image handling, specifically for converting EPO patent TIFF images to PNG format.

Jump to

Keyboard shortcuts

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