Choosing GET or POST
The trademarks endpoint is exposed under bothGET /v1/trademarks and POST /v1/trademarks. Both methods call the same service and return the same response shape. Pick whichever fits your call site.
Everything (filters, strategies, pagination,
highlights, include_total, sort, aggregations) works identically on both. On GET, aggregations is a comma-separated list and aggregations_only a boolean query parameter; on POST they live under options.
For the full parameter reference, see Search Trademarks. The sections below show concrete usage patterns you can copy into your own code.
Search Strategies
By default, every search runsexact and fuzzy strategies simultaneously and merges the results. For comprehensive clearance searches, use all four:
Only the strategies you pass run.
strategies=exact returns whole-mark matches only; it never returns a longer mark that merely contains the query. Whole-mark matching folds lookalike characters (homoglyphs), so strategies=exact for timber also returns TIMB3R, labeled homoglyph; match=exact does not. match_explanation.strategies_matched reports finer labels (normalized, phrase, synonym, identifier, …), and each one belongs to a strategy listed in search_meta.strategies_used.
strategies applies to the default match=similar mode only. The deterministic modes (match=exact, starts_with, ends_with, contains) take no strategies and return 400 validation_error if you send them.
You can restrict which strategies are used by passing the strategies array (on POST) or a comma-separated strategies= parameter (on GET):
strategies, exact and fuzzy are used. For comprehensive trademark clearance searches, pass all four strategies explicitly: exact,phonetic,fuzzy,prefix.
There is no user-controllable
fuzziness parameter. Fuzzy matching always uses AUTO internally, which adjusts edit distance based on the length of the query term.Checking many exact spellings at once
When you already have the list of spellings to check (every one-letter variant of a word, a batch of candidate names), send them asq_any instead of one match=exact request per term. One request returns every mark that exactly equals any term, each hit tagged with matched_terms, and one page costs the same as any search page. See Several exact terms.
cURL (GET)
Filtering
Narrow results with filters. OnPOST, filters are nested under a filters object. On GET, they are flat query parameters using comma-separated values for arrays and flat underscore operators for date ranges.
Office codes are uppercase WIPO ST.3 two-letter codes:
US (USPTO), EM (EUIPO), WO (WIPO), CA, SG, SE, CH, FR, AU, NO. Legacy lowercase codes (uspto, euipo, …) are accepted on requests permanently, and EU is accepted as an alias for EM. Responses always use the ST.3 form. Office display acronyms (e.g. IPA, IGE-IPI, INPI) are not an accepted input vocabulary — acronyms are not unique across offices; use ST.3 or legacy codes.
You can use both together for a range:
"filing_date": { "gte": "2020-01-01", "lt": "2025-01-01" } (POST) or filing_date_gte=2020-01-01&filing_date_lt=2025-01-01 (GET).
Aggregations
Aggregations work on both methods:?aggregations=office_code,status_stage on GET, or options.aggregations on POST. Bucket lists are top-N per field (for example 50 offices, 45 Nice classes, 250 owner countries); the document counts inside each bucket are not capped at 10,000 the way total_count is. An aggregation request is billed as one search page whether or not it returns documents. Available aggregation fields:
"aggregations_only": true to options.
How filters apply to aggregations
By default every aggregation counts the same set as the results:q, the match mode, and every filter. For a single-valued field such as office_code or status_stage, the buckets add up to total_count (multi-valued fields such as nice_classes or owner_id can add up to more, because one mark lands in several buckets). aggregations_only=true follows the same rule.
For a drill-down sidebar, set aggregation_mode=exclude_own_filter (options.aggregation_mode on POST). Each aggregation then applies every filter except its own: with offices=US&nice_classes=25, the office_code buckets ignore offices but still respect nice_classes, so the sidebar can show how many marks the other offices would add. The results and total_count still respect every filter.
Response Scoring
Search results include arelevance_score field, which is a normalized score from 0 to 100 (higher is more relevant). Results are sorted by relevance score in descending order by default. If you specify an explicit sort, relevance scoring is disabled and relevance_score is null.
Picking classes to filter on
If you do not know which Nice classes a query should be scoped to, send the description toPOST /v1/classifications/suggest
and feed the returned class_number values into nice_classes. It takes free
text (“men’s running shoes, cushioned sole”) and returns ranked classes with a
confidence and a rationale, so you can show the user why a class was picked.
Ambiguous input comes back with ambiguous: true and a clarifying question
instead of a guess.
Suggest
GET /v1/trademarks/suggest is an internal typeahead. It is not part of the published
OpenAPI spec and its shape can change without notice. Use GET /v1/trademarks for search.