How ETags Work
When you fetch a resource, the response includes anETag header containing a content fingerprint:
Treat the ETag as an opaque string, including its
W/ prefix. Trademark detail uses a weak validator: it identifies equivalent trademark data while allowing the per-request request_id and content encoding to differ. Both 200 and 304 responses carry the same weak form. A previously issued strong form still works in If-None-Match; a matching response returns the canonical weak form.Meaningful changes to the detail data or requested projection invalidate the validator. Weak validators support conditional GETs, but do not promise byte-for-byte equality or support strong preconditions such as If-Match and If-Range. Use X-Request-Id for the current request’s correlation ID when a 304 reuses a cached body.If-None-Match. If the resource has not changed, you get a 304 Not Modified with no body, saving bandwidth and processing time:
Rate limiting is enforced before the route runs, based on the endpoint’s type and transport tier, not on the response status it eventually returns. A
304 Not Modified counts against your rate limit exactly the same as the 200 it would have returned. ETags save you bandwidth and latency, not rate-limit budget, so they are still worth using on hot reads, just don’t rely on them to raise your effective request ceiling.Endpoints That Support ETags
Cache-Control Headers
Every cacheable response includes aCache-Control header:
Conditional Request Flow
TypeScript
Caching Strategies for Trademark Data
Different types of trademark data have different change frequencies. Tailor your caching strategy accordingly.Reference Data (offices, jurisdictions, classifications)
These change only when Signa adds a new office or jurisdiction.- Strategy: Cache locally with a 24-hour TTL. Revalidate with ETags daily.
- Storage: In-memory or local file.
Individual Trademarks
Most trademark records change infrequently (a few times per year), but some change during active prosecution.- Strategy: Cache with the
max-agevalue from the response (typically 5 min). Revalidate with ETags after expiry. - Storage: In-memory cache (Redis, local Map) keyed by trademark ID.
Search Results
Search results are dynamic and depend on query parameters, so they are not ETag-cacheable.- Strategy: Client-side TTL cache keyed by the full query hash. A 30-60 second TTL works well for typeahead and repeated searches.
- Storage: In-memory only. Do not persist search result caches.
List Endpoints
Paginated lists may change as new records are added.- Strategy: Short TTL (60 s from
max-age). Revalidate with ETags. Note that the cursor itself provides consistency within a pagination session. - Storage: In-memory, keyed by the full URL including query parameters.
Cache Invalidation
Analytics freshness
Analytics reports use a 24-hour cache TTL as a backstop. Owner, attorney, firm, and entity updates invalidate affected reports through the search-indexer, so freshness is event-driven rather than sweep-based. InspectServer-Timing: cache;dur=0;desc="hit" (or desc="miss") to see whether a report was served from cache; this signal is not included in the response body.
ETags handle revalidation automatically: a conditional GET against the same resource returns 304 Not Modified when the record is unchanged, so your cache entry stays valid. As noted above, that request still counts against your rate limit like any other call to the endpoint, so revalidating on every read is a latency and bandwidth optimization, not a way to make more requests than your plan allows.
For records you display in hot UI surfaces, don’t wait for the next ETag check to notice a change: set a watch on those marks and invalidate the cache entry when the webhook fires. updated_at on the record tells you when Signa last wrote it, and provenance.source_data_date tells you which office publication it came from.