@signa-so/sdk package is a typed, ergonomic client for the Signa API: full types for every endpoint and response, automatic pagination, built-in retries, and typed error classes.
The SDK is designed for server-side use. A Signa API key grants full access to your org’s data; putting one in browser code exposes it to every visitor. Proxy requests through your own backend instead.
Install
Configure
api_key, the client reads SIGNA_API_KEY from the environment:
Resources
The client organizes the API into resource namespaces. The main ones:Search and list trademarks
search() takes the POST body: q, similarity, structured filters under filters, exclusions under exclude, and options for aggregations, totals, and partial results:
relevance_score orders the results and is not a likelihood of confusion. match.tier and match.via say how close the hit is and which channels found it. See Response.
list() takes the flat GET keys. Filters are top-level params, not nested:
Presets
Presets holds the two common channel sets. Spread one into list() or search():
similarity, q runs the default channels: identical, fuzzy, embedded, and lookalike.
List parameters
Onlist(), the mark_text_* filters and the *_not exclusions take arrays. The SDK sends them as repeated keys (mark_text_is=nike&mark_text_is=mike), never comma-joined, so a comma inside a mark is safe. Values within one key match any; different keys and q must all match. When the query string passes 2 KB, list() sends the same search as a POST.
SignaList, see Pagination below.
Retrieve and batch
Pagination
Every list and search method returns aSignaList<T>, which supports three consumption patterns. The first page is fetched eagerly; later pages are fetched lazily.
Async iteration, the simplest approach:
toArray(). It never returns a short array silently. It throws SignaTruncatedError, whose items carry what was collected, in two cases:
reason: 'client_limit': nolimitwas passed and the list holds more than 10,000 items. Pass{ limit }for at most that many items, or{ limit: Infinity }for all of them.reason: 'server_window': the API ended a trademark search at its 10,000-row search window while more rows match, before yourlimitwas reached. The signal is the API’sresult_window_reachedwarning on the last page; counts alone never maketoArray()throw. Narrow the query with filters.
for await and getNextPage() never throw for this; they stop where the API stops (has_more: false).
getNextPage() returns an empty list (not an error) once there are no more pages. Every SignaList exposes data, has_more, request_id, and, on search responses, search_meta and aggregations. There is no public pagination field on the list itself, use has_more and getNextPage() to drive pagination rather than reaching for a cursor directly.
Error handling
All errors extendSignaError. API errors (4xx/5xx) extend SignaAPIError and carry a typed subclass per status code:
instanceof to handle specific error types:
SignaAPIError carries the structured error body plus the request ID:
Automatic retries
An explicit
retryable: false in the server’s error body overrides the status-based rule: a deterministic failure like the watch preview’s 504 timeout is not retried, since a blind retry would re-run the same over-budget work. Retries use exponential backoff with jitter.