Knockoff Data API v1
A background check for any brand, listing URL, or domain: who is behind it, whether that operator looks like a real company or a mass trademark filer, and the brand's off-platform footprint. Built on the full USPTO corpus (14M marks, refreshed nightly) plus the brand's own site, social, and verified storefront receipts.
Every answer is a set of deterministic facts with receipts (USPTO serial numbers you can verify on TSDR; verification receipts on every verified storefront). There is deliberately no 0–100 risk score: you compose your own policy from the variables.
Gate on state. The check-shaped endpoints (/merchants) answer with one enum you can branch on (verified, consistent, thin, contradicted, enforcement_linked) over a set of checks that each carry their own receipts. If state is contradicted or enforcement_linked, hold. Read the state reference →
Quickstart
Authenticate with a Bearer key on every request:
curl https://business.knockoff.co/api/v1/brands/tnfeeon \ -H "Authorization: Bearer kd_your_key"
{
"query": "tnfeeon",
"brand_key": "tnfeeon",
"state": "matched",
"mark_status": "live",
"owner_country": "CN",
"entity_age_months": 72,
"ownership_transfers": 0,
"operator_cluster": "Shenzhen Yibai Network Technology Co., Ltd.",
"operator_footprint": {
"owner_name": "Shenzhen Yibai Network Technology Co., Ltd.",
"owner_country": "CN",
"owner_type": "company",
"distinct_brands": 87,
"live_marks": 111,
"total_marks": 119,
"first_filed": "2018-01-05",
"last_filed": "2025-12-02",
"filing_span_years": 7.9,
"mill_filed": true,
"cluster": { "known": true, "size": 35, "basis": "human" },
"confidence": "exact_name",
"alias_count": 1,
"other_candidates": 0
},
"data_coverage": { "marks_matched": 1, "live_marks": 1, "match_basis": ["wordmark"] },
"receipts": [
{ "serial_number": "90070690", "mark_status": "live",
"tsdr_url": "https://tsdr.uspto.gov/#caseNumber=90070690&caseType=SERIAL_NO&searchType=statusSearch" }
]
}The brand has a live trademark, and its owner holds 87 distinct brands, filed through a high-volume filing attorney, in a human-reviewed operator cluster spanning 35 brands. Compare a real company: bombas returns 10 brands over 12.1 years, no mill. Same fields, opposite read. That contrast is the product.
Which endpoint?
Start from what you're holding. /brands, /batch, and /resolve return the same flat facts object, and /resolve adds everything that lives around the brand: the merchant, the seller, and how they relate. /merchants answers differently: in check shape, one state over a set of checks, because a storefront is judged as a whole rather than looked up as a string.
| You have | Call | You get back |
|---|---|---|
One brand string ("tnfeeon") | GET /brands/:key | The facts object: owner, footprint, receipts. |
A store domain ("brooklinen.com") or a store URL | GET /merchants/:domain | The check document: one state to gate on, over checks that each carry their own receipts. |
| A list of brands: a search page, a merchant book | POST /batch | The same facts for up to 100 brands, one call, input order. |
| Any URL — a listing, a store page, a bare domain | POST /resolve | One subject entry for each party the URL contains (platform, storefront, brand), with check documents where the identity is checkable, plus the storefront↔brand relationship. |
Rule of thumb: if you hold a URL, start at /resolve and let us do the parsing — it is the only call that can tell you the store and the brand are different parties. Reach for /brands and /batch only when you already hold clean brand strings. If the question is about one store and you have its domain rather than a URL, use /merchants.
Use it while you shop: Claude & ChatGPT
The API doubles as an MCP server, so any AI assistant that supports connectors can call it mid-conversation: paste a product link into Claude or ChatGPT and your assistant checks who is actually behind the brand and the seller before you buy. Your connector URL carries your API key in a filtered query parameter:
https://business.knockoff.co/mcp?token=kd_your_key
| Client | Setup |
|---|---|
| Claude (claude.ai or desktop) | Settings → Connectors → Add custom connector → paste your connector URL. |
| ChatGPT | Settings → Apps & Connectors → enable Developer mode → Create → paste your connector URL (no authentication, because the key is in the URL). |
| Claude Code / Cursor | Use the bare /mcp URL and send the key as a header instead (below). |
claude mcp add --transport http knockoff https://business.knockoff.co/mcp \ --header "Authorization: Bearer kd_your_key"
The server exposes four tools, mirroring the REST endpoints: lookup_brand (one brand string), check_merchant (one store domain, answered in check shape), batch_lookup (up to 100 at once), and resolve_listing, the one your assistant reaches for when you paste a listing URL: brand facts plus the merchant card, the seller of record, and whether that seller is the brand's operator. Responses are the same objects documented below, receipts included.
Prefer a skill to a connector? skill.md is an installable agent skill teaching Claude to call the API directly: save it as SKILL.md in a skills directory and export KNOCKOFF_API_KEY.
Endpoints
Facts for one brand string. The key is any raw brand name (vava, l.l.bean, Fjällräven). Normalization is ours.
Use it when one brand needs a decision right now: a checkout screen, a support ticket, an ad-review queue. One string in, the owner and their whole-register footprint out.
The background check on one storefront, in check shape. Pass a domain (brooklinen.com) or a full URL. We key on the registrable domain either way. The answer is {subject, state, summary, checks, issued_at, expires_at}: gate on state, read checks for the receipts behind it.
Use it when the thing in front of you is a store, not a brand string: onboarding a merchant, vetting a link a customer sent, deciding whether an unfamiliar shop is a real business.
The first check of a domain we have never seen returns the register's answer immediately and not_run on the storefront lanes (storefront enrichment has not landed yet); the domain's own site, RDAP record, and registry receipts land within minutes. That first document carries a 5-minute expires_at for exactly that reason, so call again rather than caching it.
Score up to 100 brands in one call. Body: {"brands": ["vava", "bombas", …]} → {"results": [...]} in input order. Each result carries the same fields as /brands, including presence.
Use it when you hold a list: every brand on a search results page, every merchant in tonight's onboarding queue, a whole portfolio screened overnight at 100 per call.
The front door. A URL is the only universal key in commerce — agents, extensions, analysts and shoppers all hold one, and none of them holds our brand keys. Body: one of brand, title, url (plus optional marketplace). Parses Amazon/Walmart/eBay/Etsy/Target listings and store pages, and any independent storefront.
One URL is several questions, so the answer splits it. subjects returns one entry per subject — the platform, the storefront, and the brand. Checkable entries use the same state / checks shape as /merchants, so you gate on each document separately. On a marketplace URL carrying a seller token the storefront subject is that third-party seller, not the marketplace: the seller is the counterparty, and Amazon is identified rather than checked. An Amazon or eBay display-store page names the store too, but leaves its document null because a store slug is not the seller-of-record identity.
relationship is the highest-value field on the whole API — is the party selling this the brand's operator (sells_direct), an unrelated third_party, the marketplace itself (platform_direct), or is there no_discoverable_chain between the store and the brand it is selling? That last value is an absence: it means we looked at the lanes in its checked list and found nothing joining the two. It is not a claim the goods are counterfeit.
Messy URLs are fine. Tracking parameters, mobile mirror hosts and shortened links are normalized before anything is parsed, and the response reports the url actually resolved plus every step in url_applied. A non-marketplace URL that names nothing else resolves through its own domain (source: "domain"), so "is figma.com legit" is a first-class query — and in that case there is no separate brand subject, because the store's own name is not an independent claim about it.
Use it when your input came off a page rather than out of a database. Beyond the subjects it carries the merchant card, the INFORM seller identity behind a marketplace listing, and on claim-making surfaces the authenticity read. If you're building a shopping agent or vetting listings, live here.
state & checks: the field you gate on
If state is contradicted or enforcement_linked, hold. That is the whole integration in one line. Everything else in the document exists to justify that field to whoever asks you why.
Two different fields are called state, and they are not interchangeable. This one is the check document's verdict on a whole subject (/merchants). The state in Response fields is the narrower trademark-register answer (matched / ambiguous / no_record) returned by /brands and /resolve. It appears here as the registration check.
{
"subject": { "type": "merchant", "query": "gleason.com", "key": "gleason.com" },
"state": "verified",
"summary": "gleason.com resolves to Gleason Works, The, corroborated by a
corporate registry record.",
"checks": {
"registration": {
"status": "verified",
"finding": "GLEASON WORKS, THE holds 3 live US trademarks on \"gleason\".",
"codes": ["registration.live_mark"],
"receipts": [{ "serial_number": "71290510", "tsdr_url": "…" }]
},
"operator": {
"status": "identified",
"finding": "… holds 19 distinct brands across 26 marks on the US register.",
"codes": ["operator.name_variants_folded"],
"receipts": [ … ]
},
"identity": {
"status": "verified",
"finding": "gleason.com names Gleason Works, The as its operator on its own site.",
"codes": ["identity.legal_entity_published", "identity.registry_corroborated"],
"receipts": [{ "source": "own_site", "quote": "…" }, { "source": "gleif", … }]
},
"enforcement": {
"status": "not_run",
"reason": "no enforcement corpus yet: …",
"codes": [], "receipts": []
},
"timeline": {
"status": "identified",
"finding": "gleason.com was registered 1995-08-14 (372 months ago) through …",
"codes": ["timeline.domain_registered"],
"receipts": [{ "source": "rdap", "registered_at": "1995-08-14" }]
}
},
"issued_at": "2026-08-05T17:25:23Z",
"expires_at": "2026-08-12T17:25:23Z"
}The five states
Derived deterministically from the checks, first match wins. No model, no weights, no score.
The subject is tied to a named enforcement action. Outranks every other check and should stop the workflow.
A check found a conflict: the subject's own claims do not agree with the record. This should also stop the workflow.
We can say who is behind this, and an independent record agrees. For a store, that takes evidence the store itself published: a legal entity on its own site that a corporate registry corroborates. A trademark match alone never verifies a store, because the register answers about a name and any domain can spell one. nike.store matches NIKE's wordmark and tells you nothing about who runs it.
Something was named (an owner, a legal entity) and nothing checked contradicts it. Short of corroboration, not a problem. A store whose domain matches a live trademark but which has not yet published an entity of its own lands here, and the summarysays plainly that nothing ties the two together.
Too little public identity evidence to say who operates this. Thin is not guilty. A real small business that never registered a trademark reads thin, and so does a store that opened last week. Weigh it against the rest of your own signals.
The check envelope
Every check carries the same keys, so a new evidence lane appears as a new code or a new check, never as a reshape that breaks your parser.
verified named and corroborated by an independent record. identified named, not corroborated. clear we looked and found nothing adverse; checked lists what we looked at. inconclusive we looked and cannot say (an ambiguous register is the common case). contradicted we found a conflict. not_run we did not look; reason says why.
One human sentence. Render it as-is; it is written to be read by a person or an agent without transformation.
Stable machine-readable fact identifiers (operator.mill_filed, identity.registry_corroborated). Write your policy against these, not against the prose. A code names a fact; it never carries a weight. If you want a score, compute it here: your risk policy, our evidence.
The verifiable source behind the finding: TSDR links for register facts, the quoted sentence and URL for a store's own claim, the registry record for a corroborated entity.
Why the check did not run. Telling you what we did not look at is deliberate: a check we could not run must never be mistaken for a check that came back clean. A not_run check still carries empty codes and receipts arrays, so you never have to nil-check them.
Freshness
expires_at is when to stop trusting this document. Normally 7 days: these facts move on the trademark register's clock and the enrichment lane's 30-day window. But the first check of a domain we have never seen expires in 5 minutes, because the storefront lanes are still running and the answer is about to change. Honor the field rather than assuming a fixed TTL.
Code registry
Every code a check can emit, and what it means. This is the product boundary: we ship typed facts, you write policy. A code names a fact, never a weight and never an opinion, so the list is append-only in spirit. Renaming one would break every policy written against it.
This table is generated from the same registry the API serializes, so it cannot drift from what you receive.
| Code | Means |
|---|---|
registration.live_mark | At least one live US trademark registration matches this name. |
registration.dead_marks_only | Every US trademark matching this name is dead; none is live today. |
registration.no_record | No US trademark matches this name. |
registration.multiple_owners | The matching marks are held by more than one owner, so no owner is claimed. |
registration.class_conditioned | The owner claim holds only for the queried Nice classes, not register-wide. |
registration.owner_dominance | The owner claim rests on a live-mark supermajority; every minority filer is disclosed. |
registration.ownership_transferred | The register records at least one sale of these marks to a different party. |
operator.mill_filed | The operator's filing pattern matches a trademark mill. |
operator.foreign_owner | The operator's address on the register is outside the United States. |
operator.published_cluster | The operator belongs to a published Knockoff operator cluster. |
operator.name_variants_folded | Several filing-name variants fold into one operator, so these counts are a total. |
operator.exact_name_floor | These counts come from a single filing name and are a floor, not a total. |
operator.domain_control_verified | The domain's operator proved control of it by a DNS record we re-check daily, and the corpus independently ties the domain to the mark's registered owner. Revoked the moment the record disappears; never purchasable. |
identity.legal_entity_published | The store publishes a legal entity name on its own site. |
identity.legal_entity_absent | The store publishes no legal entity name on its own site. |
identity.registry_corroborated | The published legal entity matches a corporate registry record. |
identity.inform_disclosure | The marketplace seller of record discloses a legal name under the INFORM Consumers Act. |
identity.register_corroborated | The disclosed seller name and country match a filer on the US trademark register. |
timeline.domain_registered | The domain's registration date is known from RDAP. |
Recipes
Four working patterns, one per team we serve. Every response below is real, pulled from the live API, receipts and all. The pattern is always the same: we hand you facts, you write the policy.
1 · Vet one brand at decision time
For checkout screens, support queues, ad review: anywhere a single unknown brand needs a yes/no now.
curl https://business.knockoff.co/api/v1/brands/vava \ -H "Authorization: Bearer kd_your_key"
Then branch on three fields:
state:no_recordmeans no US trademark at all; for a brand claiming to be established, that is itself the answer.operator_footprint.distinct_brands: a real company holds a handful of marks for its own products; 40+ unrelated brands is a disposable-brand operation.operator_footprint.owner_type+mill_filed: an individual holding many brands, filed through a mass-filing attorney, is the strongest pseudo-brand signature in the register.
Whatever you decide, receipts carries the TSDR links to justify it: to the customer, the auditor, or the lawyer.
2 · Score a whole search page, or a merchant book
For marketplaces and payment platforms screening in bulk: every brand on a results page, or a portfolio swept overnight at 100 brands per call.
curl -X POST https://business.knockoff.co/api/v1/batch \ -H "Authorization: Bearer kd_your_key" \ -H "Content-Type: application/json" \ -d '{"brands": ["bombas", "tnfeeon", "jxrev", "zzznotabrand"]}'
| Brand | state | Footprint | Read |
|---|---|---|---|
bombas | matched | US company · 10 brands · 2013→2025 · no mill | Real company. |
tnfeeon | matched | CN company · 87 brands · 2018→2025 · mill | Mass operator. |
jxrev | matched | CN individual · 8 brands · 4-month burst · mill | Spun-up brand swarm. |
zzznotabrand | no_record | null | No trademark at all. |
Every row has (or lacks) receipts you can check on TSDR. Where you set the line (20 brands? mill + individual?) is your policy; the variables are ours. Document KYB tells you the merchant's paperwork is real; this tells you whether the brands they sell belong to anyone who plans to be here next year.
3 · Rank what your shopping agent recommends
For AI shopping agents: your agent scraped a listing it's about to recommend. One resolve call answers who's behind the brand and who's behind the listing.
curl -X POST https://business.knockoff.co/api/v1/resolve \ -H "Authorization: Bearer kd_your_key" \ -H "Content-Type: application/json" \ -d '{"url": "https://www.amazon.com/Churboro/dp/B0EXAMPLE1?smid=AMO06BSLP8P1W"}'
{
"resolved_brand": "Churboro",
"source": "url",
"marketplace": "amazon",
"facts": {
"state": "matched",
"mark_status": "live",
"owner_country": "CN",
"entity_age_months": 59,
"operator_footprint": {
"owner_name": "Shenzhen Furuixue Trading Co., Ltd.",
"distinct_brands": 1,
"filing_span_years": 0.0,
"mill_filed": true, …
},
"receipts": [
{ "serial_number": "90883556", "mark_status": "live", "tsdr_url": "…" }
], …
},
"merchant": {
"domain": "amazon.com",
"seller": {
"seller_id": "AMO06BSLP8P1W",
"legal_name": "JIAXIN XU",
"country": "CN",
"corroborated": true,
"trademark_footprint": {
"owner_type": "individual",
"distinct_brands": 3,
"mill_filed": true, …
},
"join_basis": "entity_country", …
}, …
},
"relationship": {
"relationship": "third_party",
"basis": "entity_country",
"seller_entity": { "legal_name": "JIAXIN XU", … },
"brand_entity": { "owner_name": "Shenzhen Furuixue Trading Co., Ltd.", … }
},
"presence": { "status": "queued" }
}The read, field by field: the mark is real (mark_status: live), but the owner is a single-brand CN entity that filed once, through a mass-filing attorney, and the seller of record is a different CN individual holding 3 mill-filed brands of his own (relationship: third_party). Nothing here says “counterfeit”; everything here says “no real company is standing behind this listing.” Your agent ranks a 12-year US brand above this without ever guessing, and can show the TSDR receipt if the user asks why.
The same call on a real brand's listing comes back the opposite shape: hanes resolves to HBI Branded Apparel Enterprises (714 brands, filing since 1930, published cluster) with the same honest third_party when a reseller is the seller of record.
4 · Vet a marketplace seller
For marketplace trust & safety: a seller is onboarding, or a “new” one smells familiar. Resolve their storefront URL, no product needed.
curl -X POST https://business.knockoff.co/api/v1/resolve \ -H "Authorization: Bearer kd_your_key" \ -H "Content-Type: application/json" \ -d '{"url": "https://www.amazon.com/sp?seller=A2A9MTHG33B8AH"}'
{
"resolved_brand": null,
"marketplace": "amazon",
"merchant": {
"seller": {
"seller_id": "A2A9MTHG33B8AH",
"legal_name": "Boundless EC US LLC",
"country": "US",
"address_present": true,
"corroborated": true,
"entity": { "seller_count": 7, … },
"trademark_footprint": {
"owner_name": "BOUNDLESS EC US LLC",
"owner_type": "company",
"distinct_brands": 33,
"live_marks": 49,
"mill_filed": false, …
},
"join_basis": "entity_country"
}, …
}, …
}Three things your INFORM paperwork can't tell you, in one card: the disclosed identity was corroborated from two independent networks; the address behind this storefront hosts 7 seller accounts (entity.seller_count); and the entity itself holds 33 brands on the register, joined by distinctive entity name + matching country (join_basis: entity_country), never a bare name match. When a banned operator re-registers under a fresh storefront name, the address cluster and the trademark portfolio are what give them away.
An unknown seller returns the id with honest nulls: the miss is recorded, and coverage grows where demand actually is.
Response fields
These are the fields of the flat facts object returned by /brands, /batch, and /resolve. The check-shaped /merchants response is documented separately under state & checks. Note that its state is a different field from the one directly below.
matched the brand's marks trace to one distinct owner. ambiguous several distinct owners use this name; we state the marks but claim no owner. no_record no USPTO mark for this string (itself a signal).
live dead none best status among the matched marks.
Present only when a resolve call's title/URL carried product context. The brand is ambiguous register-wide (register_state), but exactly one owner holds its marks in the queried Nice classes, e.g. {"classes": ["021"], "context": "cookware", "register_state": "ambiguous"}. The verdict holds for those classes only: do not cache or reuse it as an unconditional answer for the brand.
One operator holds a calibrated supermajority of the brand's live marks (e.g. {"share": 0.818, "live_marks": 108, "of_live_marks": 132, "other_candidates": [...]}) and is reported as the owner (when the call carried product context, only if that operator also holds live marks in the queried classes). other_candidates discloses every minority filer by name and live-mark count; weigh them before treating the owner claim as exclusive.
The parties this URL is actually about, up to three, each as { type, query, key, document, not_checked }. document is either a full check document — gate on its own state — or explicitly null with a not_checked reason. Types: platform the marketplace or storefront platform, identified but not checked: the counterparty behind the URL is the storefront, so document is explicitly null and not_checked says why. merchant an independent store, keyed by its domain. seller a marketplace seller of record, keyed {marketplace}:{seller_id}; its identity check reads the seller's INFORM disclosure and reaches verified only when that disclosed name and country match a filer on the US register. storefront an Amazon/eBay display store, keyed {marketplace}:store:{slug}; identified but not checked because its display slug does not identify the seller of record. brand the brand the listing claims. The document key is always present so a parser can iterate without a key check.
A brand derived from the store's own domain gets no brand subject. Its name is the store's name, not an independent claim about what it sells, and a verified brand document beside a lookalike storefront would read as an endorsement no check performed.
The URL we actually resolved, and every hygiene step applied to yours. Tracking parameters and fragments are stripped, known marketplace mobile hosts are normalized, and links on known shortener domains are expanded. Identity-bearing parameters are never touched (seller, smid, variant). Read these when an answer surprises you: they name the exact string the grammars saw.
How the brand was resolved, in precedence order: brand the caller's explicit brand. storefront_vendor the store's own product JSON named its vendor. title leading-token heuristic on the scraped title. url a marketplace URL grammar's brand slug. domain nothing else named a brand on a non-marketplace URL, so the candidate is the domain itself (figma.com → figma), and a bare name-match by construction; the facts.state says what the register actually supports. none no brand resolved; merchant context only. (Distinct from presence.source, which names the presence block's own data provenance.)
The seller's identity card, beside the brand's facts. domain (the merchant's identity key), platform + platform_confidence (deterministic = a URL shape the platform doesn't let merchants change, e.g. Shopify's /products/{handle}?variant=; heuristic = a default path shape other platforms can collide with), trademark_footprint (the store name's own facts object), and identity_completeness, which card fields are filled, a coverage statement, never a judgment.
domain_age (months since the domain's RDAP registration date; young domains are the fly-by-night signal), legal_entity (the operating entity named on the site's own legal pages, always with its receipt: {"name", "source_url", "quote"}), and a confirmed platform_confidence are filled by async enrichment: the first resolve of a domain queues it (enrichment: "queued"), later resolves return the enriched card ("complete", or "failed"). Enriched fields may be up to 30 days old: a domain is never re-fetched inside that window.
registrations rides the legal entity: corporate-registry records whose legal name matches the entity named on the site's own pages. GLEIF (lei, jurisdiction, entity status) and SEC EDGAR (cik, ticker), each with a link and the name-match receipt in verification. The chain is own site → legal entity → registry; a registry record never attaches on a bare brand-name guess.
Present when the URL carries an Amazon seller token (/sp?seller=, or seller=/smid= on a product URL): the third-party seller behind the listing. legal_name, country, address_present, and registration_number_present come from the seller's INFORM Consumers Act disclosure as observed on-page (captured_at is the receipt; corroborated = the address was confirmed from ≥2 distinct networks). entity is the seller's shared-address cluster (how many storefronts operate from the same address).
trademark_footprint appears only when the legal name joins a trademark operator under the stated join_basis (entity_country = distinctive entity name + matching country; never a bare name match); it is the seller's own portfolio (distinct_brands, live_marks, mill_filed). An unknown seller returns the id with nulls: the miss is recorded and coverage grows with observation.
Is the party selling this the brand's operator? On a marketplace listing the party compared is the seller of record; on an independent store it is the store itself. sells_direct the seller's disclosed identity and the brand's resolved owner fold to the same entity (distinctive entity name + matching country, the same corroboration bar as join_basis: entity_country), or their registered aliases share a published operator cluster; the basis states entity_country or published_cluster. third_party both identities are comparable and the entities differ. platform_direct the marketplace itself is the seller of record (e.g. Amazon retail's own seller id). unknown nothing provable, with the reason stated (no_seller_token, seller_unresolved, brand_owner_unresolved, identity_not_comparable, or country_mismatch: a same-named entity in a different country proves neither sameness nor difference, so it stays unknown). seller_entity / brand_entity carry the two compared identities as receipts. Never a score.
On an independent store, sells_direct additionally covers the case where the store is the brand's own site (basis: brand_own_site, cited from the brand's resolved footprint) or publishes a legal entity that folds to the brand's register owner (basis: published_entity).
no_discoverable_chain is the value unique to independent stores, and it is an absence, not an accusation: the brand has a named owner, we read the store's own site, we know where the brand's own site is, and nothing joins the two. checked lists exactly what ran. It is never emitted over a lane that has not finished — a storefront still enriching, a footprint still building, or a brand whose own site we never resolved all answer unknown with the reason, because "we have not looked" must never read as "we looked and found nothing." A brand pulled out of the store's own domain gets unknown / no_independent_brand_claim: a store has no chain to answer to its own name.
Is the listing what it claims to be? Composed from crowd-relayed observations (extension sightings, hardened by a 2-network corroboration gate) plus our own reverse-image receipt over the listing's hero image. status is observed or the honest no_observation (coverage is demand-shaped: unseen listings have no data, and none is invented). claim carries the crowd-corroborated identity tuple (attribution, ships-from, duties-paid language, AI-scale flag); hints carries uncorroborated latest-value numerics (sales, shop age); signals lists human-checkable reasons with their evidence grade. receipt is the reverse-image result (catalog_matches = mass-market catalog twins, always with caveat: "copy_direction_unverified". Copycat sites also steal from real artisans). lean is advisory and watch is its ceiling: “worth a human's look, here are the receipts” (lean_basis), never a confident “fake” label. Never a score.
The brand's off-platform footprint: does it exist anywhere besides the listing you found it on? own_site (resolved domain with Ahrefs authority depth: domain rating, organic traffic, referring domains, or resolved: false with the near-miss candidates), wikipedia_url, knowledge_graph, social, marketplaces, storefronts (shop URL, verification receipts, and sales/rating when available), software and reputation (app-store and review-platform profiles, same verification rule), press (web mentions, each with the url and title of the page that named the brand). Filled by demand-gated async enrichment: the first sighting of a brand returns {"status": "queued"}, later calls carry the map. lean is advisory with its lean_basis stated, never a score.
ISO-2 country of the current owner. Only present when matched. An ambiguous brand never gets an owner claim.
Months since the earliest real filing among the matched marks.
Recorded sales of the mark (true ownership changes; renames and collateral liens don't count).
Name of a published operator cluster this brand belongs to. Clusters publish only when public records or calibrated matching rules clear the measured publication bar; the audit basis is returned in operator_footprint.cluster.basis.
How many marks matched, how many live, and on what basis (wordmark / pseudo_mark).
Up to 20 serial numbers with TSDR links, every claim is independently verifiable.
operator_footprint: the operator behind the brand
The current owner's whole-register filing pattern, precomputed nightly over all 14M marks. This is the field that separates a real company from a pseudo-brand operation: pseudo-brands almost all have trademarks. What gives them away is an owner with dozens of unrelated brands filed in bursts, often through a filing mill, often as an individual.
How many distinct brand names this operator holds across the whole register. The headline: a real brand files a handful for its own products; a mass operator files dozens. Counted over the operator's resolved identity, its name variants folded together (see confidence).
The owner's live and total mark counts.
The owner's filing window. 8 brands across a 4-month burst reads very differently from 10 brands across 12 years.
company individual null from the USPTO legal-entity code; an individual holding many brands is a strong mass-filing signal.
True if any of the owner's marks were filed through a high-volume filing attorney whose book is ≥50% CN/HK owners. Most meaningful for small-footprint owners; a century-old global filer can flag on one mark.
{known, size, basis}: whether this operator belongs to a published cluster, how many brands it spans, and its audit trail (record, ai, human, or mixed). Only returned when matched.
resolved_entity the owner's name variants (“Procter & Gamble Company” / “The Procter and Gamble Co.”) were folded into one operator, corroborated by a shared country, so the counts are the operator's true total. exact_name no variant was found, so the counts are keyed on the single filing string and are a floor: an operator filing under variants we couldn't corroborate is undercounted. The fold is a deterministic name+country match, separate from the published cluster inference.
How many distinct owner-name strings were folded into this resolved operator. 1 means none were found (so the counts equal the exact-name floor); higher means variants were merged.
On ambiguous brands the footprint shown is the most prolific candidate owner's; this is how many other candidates exist. 0 when matched.
Errors & limits
| Status | When |
|---|---|
401 | Missing or invalid API key. |
400 | Missing required parameters (e.g. no brand/title/url on resolve). Also an unusable merchant domain on /merchants: an IP literal, a bare hostname with no public suffix, or a malformed DNS name. |
422 | Batch over 100 items. |
429 | Rate limit exceeded (default 120 requests/min per account, shared across that account's keys; hand-issued pilot keys are limited per key). Retry after the Retry-After seconds. Throttled calls are not billed. |
Every served query is metered per key, hits and misses alike.
Glossary
Every load-bearing term in the contract, one plain-English line each. The field names stay as they are: precise terms with definitions beat friendly renames that drift.
The lookup’s honest answer: matched (one owner stands behind the name), ambiguous, or no_record. There is no fourth state and no score.
More than one unrelated owner could match this name, so we publish no owner claim rather than guess.
No USPTO trademark matches this exact name. Unregistered brands exist, but there is no registered owner standing behind the name.
Context-conditioned lookups only: the reading of the brand the verdict applies to, when the product title changes which trademark the name means.
Whether the matched registration is live or dead on the register right now. A matched brand whose marks are all dead is an owner claim about the past, and every surface says so.
The current owner of record after following the assignment chain — not necessarily the name on the original filing.
The owner’s register-wide filing stats: distinct brands, live marks, filing span, and the mill flag. The difference between a company with a trademark and an operation with a portfolio.
How many different brand names the owner holds marks for. The single most telling number about a marketplace brand’s owner.
Filed through a filing mill — an attorney who files trademarks in bulk for overseas operators. A fact we report, not a judgment.
Several registered companies that public records show are run as one operation. We only say this when USPTO filings or verified evidence prove the connection — never on a guess.
One owner holds nearly all the live trademarks under this name. The remaining filers are listed by name so nothing is hidden.
How a marketplace seller identity was connected to a trademark owner — e.g. entity_country, a distinctive-name-and-country match. Never a bare name guess; below the bar, no join is published.
The TSDR links: every claim carries the serial numbers of the USPTO records behind it, so you can verify our work in one click.
What the verdict rests on: how many marks matched, how many are live, and on what basis they matched — so you can see how much record stands behind the answer.
Our stated read of the off-platform footprint evidence — protect or watch — with lean_basis naming exactly why. A read of the facts listed beside it, never a score.
Get a key
Keys are self-serve: sign up, name a key, and it works immediately.
Data: USPTO trademark corpus (applications, registrations, assignments), refreshed nightly. Facts are published freely; operator-identity inferences ship only when the evidence clears a measured publication bar.