List Goods & Services
curl --request GET \
--url https://api.signa.so/v1/goods-services \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/goods-services"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/goods-services', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.signa.so/v1/goods-services",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signa.so/v1/goods-services"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signa.so/v1/goods-services")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/goods-services")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "list",
"data": [
{
"term": "3D animation software",
"term_key": "3d animation software",
"class_number": 9,
"taxonomy_path": "8729051",
"is_harmonised": true,
"accepted_offices": ["EUIPO"],
"source": "tmclass",
"language": "en"
}
],
"has_more": true,
"pagination": { "cursor": "3d animation software" }
}
Goods & Services
List Goods & Services
Browse and search accepted goods & services terms across one Nice class or all 45
GET
/
v1
/
goods-services
List Goods & Services
curl --request GET \
--url https://api.signa.so/v1/goods-services \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/goods-services"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/goods-services', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.signa.so/v1/goods-services",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signa.so/v1/goods-services"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signa.so/v1/goods-services")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/goods-services")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "list",
"data": [
{
"term": "3D animation software",
"term_key": "3d animation software",
"class_number": 9,
"taxonomy_path": "8729051",
"is_harmonised": true,
"accepted_offices": ["EUIPO"],
"source": "tmclass",
"language": "en"
}
],
"has_more": true,
"pagination": { "cursor": "3d animation software" }
}
Overview
Browse and search 96,000+ pre-approved goods & services descriptions from the Harmonised Database (HDB) and the USPTO ID Manual. Use this to power goods/services autocomplete in filing tools (passclass to scope results to a single Nice class), or to discover which classes accept a particular term (pass q without class for a cross-class search).
For background on how office acceptance works and the data sources behind this endpoint, see the Classifications & Goods/Services guide.
At least one of
q or class must be provided. For semantic class discovery from a natural-language business description (e.g. “SaaS tool for HR teams”), use Suggest Classifications. For a drafted goods/services specification with filing-ready wording per class, use Suggest Goods & Services.Query Parameters
string
Substring search across term text (2-200 characters). Optional if
class is set. Returns 400 validation_error if neither q nor class is provided.integer
Nice class number (1-45). Optional if
q is set. Returns 400 if outside the 1-45 range, or 404 if the class number is in range but not loaded in reference data.string
default:"en"
Language code (e.g.
en, de, fr, es, it, ja).boolean
default:"false"
When
true, only return terms on the TMClass harmonised list.integer
default:"20"
Max results (1-100).
string
Pagination cursor from
pagination.cursor of the previous page.Response
This endpoint is publicly cacheable, so the response never includesrequest_id.
string
Always
list.object[]
Array of term records ordered by term key.
string
The term text.
string
Stable normalized key for the term.
integer
Nice class this term is filed under (1-45). Present on every result so cross-class searches render without follow-up fetches.
string | null
TMClass taxonomy path identifier, when available.
boolean
Whether the term is on the harmonised list.
string[]
Offices that accept this term (e.g.
USPTO, EUIPO).string
Source catalog (e.g.
tmclass, uspto_idm).string
Language code.
boolean
Whether more pages are available.
{
"object": "list",
"data": [
{
"term": "3D animation software",
"term_key": "3d animation software",
"class_number": 9,
"taxonomy_path": "8729051",
"is_harmonised": true,
"accepted_offices": ["EUIPO"],
"source": "tmclass",
"language": "en"
}
],
"has_more": true,
"pagination": { "cursor": "3d animation software" }
}
Code Examples
Scoped autocomplete (user already picked a class)
curl -G "https://api.signa.so/v1/goods-services" \
-H "Authorization: Bearer sig_YOUR_KEY" \
--data-urlencode "q=mobile applications" \
--data-urlencode "class=9" \
--data-urlencode "harmonised_only=true" \
--data-urlencode "limit=10"
import { Signa } from "@signa-so/sdk";
const signa = new Signa({ api_key: process.env.SIGNA_API_KEY });
const terms = await signa.goodsServices.list({
q: "mobile applications",
class: 9,
harmonised_only: true,
limit: 10,
});
Cross-class discovery (which classes accept this term?)
Pass onlyq (omit class) and inspect class_number on each result to see which classes contain the wording.
curl -G "https://api.signa.so/v1/goods-services" \
-H "Authorization: Bearer sig_YOUR_KEY" \
--data-urlencode "q=poster" \
--data-urlencode "limit=25"
const matches = await signa.goodsServices.list({ q: "poster", limit: 25 });
for (const t of matches.data) {
console.log(`Class ${t.class_number}: ${t.term}`);
}
Browse all terms in a class
Pass onlyclass (omit q) to page through the full list of accepted wording for one class.
TypeScript
let page = await signa.goodsServices.list({ class: 25, limit: 50 });
for (const t of page.data) console.log(t.term);
while (page.has_more) {
page = await page.getNextPage();
for (const t of page.data) console.log(t.term);
}
Errors
| Status | Type | Description |
|---|---|---|
| 400 | validation_error | Neither q nor class provided, q shorter than 2 characters, or class outside the 1-45 range |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | API key lacks trademarks:read scope |
| 404 | not_found | class is in range but not loaded in reference data |
Related Endpoints
- Suggest Goods & Services, drafts a filing-ready specification from a description
- Suggest Classifications, lighter tier, classes only
- Retrieve Classification
- List Classifications