Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt

Use this file to discover all available pages before exploring further.

Ask a brand-agent a verification question about a facet of its identity. This is a prerequisite gate — check before you proceed, not a signal you consume after a decision is locked in. One tool with four claim types covers the verification dimensions:
claim_typeThe questionUsed at
subsidiary”Is this brand a subsidiary of yours?”Brand-relationship establishment, member-feature provisioning, governance-trust extension
parent”Is this brand your parent house?” (leaf-side mirror)Mutual-assertion confirmation at the agent layer
property”Is this site / app / property one of yours?”Inventory onboarding, creative clearance, fraud escalation
trademark”Is this trademark yours?”Creative-clearance gates, licensee-posture confirmation
The brand-agent answers using its own data — which is brand.json plus the richer states (pending_review, transferring, licensed_in, etc.) that the static file can’t express. The tool is one specific-question affordance on top of the same identity surface get_brand_identity reads. For high-volume verification (portfolio refresh, creative-clearance batches, crawler scans), use the bulk variant verify_brand_claims — same per-claim semantics, one round-trip and one rate-limit slot for the whole batch.

The trust rule — two calls, not one

A single signed owned response is NOT trust-extending. Mutual assertion remains the floor for positive trust. This is the load-bearing rule of the asymmetric trust model — assertion direction requires both sides to agree. Consumers MUST call both sides when extending relationship trust:
  • For subsidiary claims, also call the leaf’s brand-agent with claim_type: "parent" (or crawl the leaf’s brand.json for its house_domain).
  • For property claims, cross-check against the brand’s static brand.json properties[] and (for domains) DNS/TLS evidence.
  • For trademark claims, cross-check the public registry record. For licensed_in specifically, the licensor named in details.licensor_domain SHOULD reciprocate licensed_out for the same mark before the licensing relationship is trusted.
  • Only rejections (disputed / not_ours) are authoritative on a single signed response — a brand has standing to refuse association unilaterally.
Shortcuts kill the trust model. Without the reciprocation step, a malicious or mistaken house could claim subsidiaries, properties, or licensed marks it doesn’t actually have. See brand.json § Agent-augmented verification for the full normative trust table and the malicious-house walkthrough.

Schema

Capability discovery

The brand-agent advertises this task in its get_adcp_capabilities response. An agent that supports only some claim types declares this via the per-tool capability extension:
{
  "supported_protocols": ["brand"],
  "supported_tasks": [
    "get_brand_identity",
    "verify_brand_claim"
  ],
  "brand": {
    "verify_brand_claim": {
      "supported_claim_types": ["subsidiary", "parent", "trademark"]
    }
  }
}
When supported_claim_types is omitted, the agent advertises support for all four. Consumers MUST check before relying on a specific claim type; unsupported types return UNSUPPORTED_CLAIM_TYPE (see Error handling).

Minimum viable adoption

A brand-agent doesn’t have to ship all four claim types at once. Pick the slice that matches the workflow:
  • Property only — creative-clearance and inventory-onboarding consumers; the smallest useful surface.
  • Subsidiary + parent — partners doing brand-relationship establishment or governance-trust extension; ship both halves at once so mutual assertion completes at the agent layer.
  • Trademark only — creative-clearance pipelines that need licensee posture (the differentiator from registry crawls).
  • All four — full coverage; recommended for AAO-hosted agents serving many member configurations.
Advertise only the types you implement. Partners check supported_claim_types and route accordingly; unsupported types return UNSUPPORTED_CLAIM_TYPE cleanly.

Authorization tiers

The public/authorized split per claim type:
TierWhat the agent returns
Public (no linked account)claim_type, status (always). For applicable claim types: details.brand_id, details.relationship, details.matched_registration, details.countries, details.nice_classes. context_note when populated.
Authorized (via sync_accounts)Everything above, plus: details.first_observed_by_house_at, details.expected_resolution_window_days, details.use_case_authorization, details.licensor_domain (when licensed_in).
Queue position, internal ticket state, and team routing are never exposed.

Per-claim-type request and response shapes

The details field on the response varies by claim_type. Below: the request payload and the typed details fields each claim type returns.

claim_type: "subsidiary"

House-side: a consumer detects converse.com claiming house_domain: nikeinc.com. Asks Nike’s agent:
{
  "claim_type": "subsidiary",
  "claim": {
    "subsidiary_domain": "converse.com",
    "subsidiary_brand_id": "converse",
    "observed_at": "2026-05-14T10:00:00Z"
  }
}
{
  "claim_type": "subsidiary",
  "status": "owned",
  "details": { "brand_id": "converse" }
}
The brand can also reject — rejection direction is authoritative on a single signed response, no reciprocation required:
{
  "claim_type": "subsidiary",
  "status": "not_ours",
  "context_note": "We have no record of this brand; the leaf's claim is in error."
}
Applicable statuses: owned, pending_review, transferring, disputed, not_ours, archived, unknown. (licensed_in / licensed_out don’t apply — subsidiaries aren’t licensed; brands and trademarks are.) archived means the brand once held this subsidiary (e.g., a divested business unit) but no longer does — distinct from not_ours (never owned). Request claim fields:
FieldRequiredNotes
subsidiary_domainYesDomain of the leaf brand whose house_domain claim is being verified.
subsidiary_brand_idNoStable brand identifier the leaf uses for itself. Recommended; helps the agent disambiguate when multiple brands share a domain.
observed_atNoISO 8601 timestamp — when the caller observed the leaf’s claim. Helps the agent age claims and prioritize fresh ones in its internal queue.
Response details fields:
FieldTierReturned whenNotes
brand_idPublicstatus ∈ The house’s brand_id for this subsidiary.
first_observed_by_house_atAuthorizedanyWhen the house first became aware of the claim.
expected_resolution_window_daysAuthorizedREQUIRED when status is pending_review; otherwise Authorized when presentThe aging window. Enforcement is agent-side: the agent MUST transition the claim to a terminal status or unknown once the window elapses. When a pending_review response is older than its declared window, consumers SHOULD treat it as unknown and fall back to crawl.

claim_type: "parent" (leaf-side mirror)

Leaf-side: a consumer wants the leaf’s authoritative answer about its parent. Asks Converse’s agent:
{
  "claim_type": "parent",
  "claim": {
    "parent_domain": "nikeinc.com",
    "claimant_says": "Nike's brand_refs[] lists converse.com"
  }
}
{
  "claim_type": "parent",
  "status": "owned",
  "details": { "house_domain": "nikeinc.com" }
}
The leaf can also actively reject:
{
  "claim_type": "parent",
  "status": "disputed",
  "context_note": "We are not a Nike subsidiary; their claim is in error."
}
Applicable statuses: same as subsidiary (mirror). Request claim fields:
FieldRequiredNotes
parent_domainYesDomain of the house being claimed as this brand’s parent.
claimant_saysNoFree-text context about what the claimant published (e.g., “Nike’s brand_refs[] lists converse.com”). Helps the agent disambiguate competing claims.
observed_atNoISO 8601 timestamp — when the caller observed the parent claim.
Response details fields:
FieldTierReturned whenNotes
house_domainPublicstatus ∈ The brand’s declared parent house. NOT returned for pending_review — the leaf hasn’t yet accepted the parent claim.
first_observed_by_leaf_atAuthorizedanyWhen the leaf first became aware of a third-party claim about its parentage.
When both verify_brand_claim with claim_type: "subsidiary" (on the house) AND with claim_type: "parent" (on the leaf) return owned for the same relationship, mutual assertion is established at the agent layer — no static-file crawl required. This is the cleanest path for trust extension.

claim_type: "property"

The request asks about one property; the response describes the brand’s relationship with that property, including all regions where the relationship applies (which may exceed the one named in the query).
{
  "claim_type": "property",
  "claim": {
    "property": {
      "type": "website",
      "identifier": "nike.cn",
      "region": "CN"
    },
    "use_case": "advertising"
  }
}
{
  "claim_type": "property",
  "status": "owned",
  "details": {
    "relationship": "owned",
    "brand_id": "nike",
    "regions": ["CN"],
    "use_case_authorization": { "advertising": true }
  },
  "context_note": "Regional site for China market"
}
A property that spans multiple regions (e.g., a global e-commerce surface) returns all of them:
{
  "claim_type": "property",
  "claim": { "property": { "type": "website", "identifier": "nike.com" } }
}

{
  "claim_type": "property",
  "status": "owned",
  "details": {
    "relationship": "owned",
    "brand_id": "nike",
    "regions": ["US", "CA", "GB", "FR", "DE", "JP", "AU"]
  }
}
The brand can also reject — rejection direction is authoritative on a single signed response:
{
  "claim_type": "property",
  "claim": { "property": { "type": "website", "identifier": "fake-nike-store.com" } }
}

{
  "claim_type": "property",
  "status": "not_ours",
  "context_note": "Unaffiliated third-party site; we do not authorize use of our marks on it."
}
Applicable statuses: owned, transferring, disputed, not_ours, archived, unknown. (pending_review is uncommon for properties; use transferring for in-flight ownership changes.) archived means the brand once operated this property (e.g., a sold-off domain) but no longer does. Request claim fields:
FieldRequiredNotes
property.typeYeswebsite, mobile_app, ctv_app, desktop_app, dooh, podcast, radio, streaming_audio.
property.identifierYesDomain for websites/podcasts, bundle id for apps, etc.
property.storeWhen type is an appapple, google, amazon, roku, fire_tv, samsung, lg, vizio, other.
property.regionNoSingle ISO 3166-1 alpha-2 code (or "global") — the region the caller cares about. The response’s details.regions carries the full applicable set.
use_caseNoFree-text use case (e.g., "advertising"). The agent MAY scope its answer accordingly.
Response details fields:
FieldTierReturned whenNotes
relationshipPublicstatus ∈ owned / direct / delegated / ad_network — mirrors brand.json’s properties[].relationship.
brand_idPublicstatus ∈ The brand within the house that owns this property.
regionsPublicstatus ∈ ISO 3166-1 alpha-2 codes, or ["global"] sentinel for no regional restriction. May include regions beyond the one the request named.
use_case_authorizationAuthorizedanyPer-use-case permission map. Registered keys: advertising, endorsement, retail_listing, editorial, commercial_advertising, merchandise_resale. Agents MAY add extensions.

claim_type: "trademark"

{
  "claim_type": "trademark",
  "claim": {
    "mark": "AIR JORDAN",
    "registry": "USPTO",
    "number": "1234567"
  }
}
{
  "claim_type": "trademark",
  "status": "owned",
  "details": {
    "matched_registration": {
      "registry": "USPTO",
      "number": "1234567",
      "mark": "AIR JORDAN",
      "registration_status": "active"
    },
    "countries": ["US"],
    "nice_classes": [25, 41]
  }
}
{
  "claim_type": "trademark",
  "status": "licensed_in",
  "details": {
    "matched_registration": { "registry": "EUIPO", "number": "EU98765", "mark": "CONVERSE", "registration_status": "active" },
    "licensor_domain": "converseholdings-eu.com",
    "countries": ["FR", "DE", "IT", "ES"],
    "nice_classes": [25]
  }
}
licensed_in reciprocation. Consumers SHOULD treat licensed_in as unverified until the named licensor_domain’s brand-agent reciprocates licensed_out for the same mark (same mutual-assertion shape as ownership, just across the licensing edge). Without reciprocation, the brand could unilaterally claim a licensed relationship that doesn’t exist. The brand can also reject — rejection direction is authoritative on a single signed response:
{
  "claim_type": "trademark",
  "claim": { "mark": "AIR JORDAN", "registry": "EUIPO" }
}

{
  "claim_type": "trademark",
  "status": "disputed",
  "context_note": "EU mark in this jurisdiction held by separate entity; we contest their registration and do not authorize use as ours."
}
Applicable statuses: owned, licensed_in, licensed_out, transferring, disputed, not_ours, archived, unknown. (pending_review is uncommon — trademark registrations are public-record events with definitive ownership at any given time.) archived means the brand once held this mark (expired, cancelled, transferred to another party) but no longer does. details fields:
FieldTierNotes
matched_registrationPublicThe registration the agent matched the query to. Returned when status is owned, licensed_in, licensed_out, or transferring.
licensor_domainPublicDomain of the licensor when status is licensed_in.
countriesPublicISO 3166-1 alpha-2 codes the response covers.
nice_classesPublicNice Classification class numbers. Disambiguates cross-industry marks.
use_case_authorizationAuthorizedPer-use-case permission for this mark — the differentiator from registry crawls.

Trust model

The agent’s response is signed under the brand’s adcp_use: "response-signing" JWK. The trust model is direction-asymmetric:
  • Rejection direction (agent says disputed / not_ours) is authoritative. A brand can refuse association unilaterally; no mutual reciprocation required.
  • Assertion direction (agent says owned / pending_review / transferring / licensed_*) is informative but NOT trust-extending on its own. The reciprocating side must still confirm before trust extends.
When both the house-side and leaf-side agents speak (via claim_type: "subsidiary" and claim_type: "parent" respectively), mutual assertion is established at the agent layer. When only one side has an agent, fall back to crawl-based mutual-assertion inference per brand.json § Mutual-assertion trust model. See brand.json § Agent-augmented verification for the full trust table and the malicious-house walkthrough.

Caching

Per-status:
  • owned / not_ours / disputed — stable. 24-72h.
  • pending_review — volatile. Max-age ≤1h.
  • transferring — volatile until transition. Max-age ≤4h.
  • licensed_in / licensed_out — moderately volatile. 24h.
  • use_case_authorization — most volatile. Re-check per session.
  • unknown — short cache (≤1h).
Agents SHOULD set Cache-Control: max-age=N. Consumers MAY override downward but SHOULD NOT exceed agent-supplied max-age.

Error handling

Error codeCause
AUTH_INVALIDCaller’s signed envelope did not verify.
RATE_LIMITEDAgent has rate-limited the caller per {caller_identity, claim_type, claim-target}. Agents SHOULD return Retry-After and prefer returning cached prior answer.
UNSUPPORTED_CLAIM_TYPEThe agent does not implement the requested claim_type. Check supported_claim_types via get_adcp_capabilities.
INVALID_INPUTRequired claim fields are missing or malformed (e.g., subsidiary_domain not a valid hostname).
AMBIGUOUS_MATCHFor claim_type: "trademark" — multiple registrations match. Narrow with registry, number, or countries.
{
  "errors": [
    {
      "code": "UNSUPPORTED_CLAIM_TYPE",
      "message": "claim_type 'property' is not supported by this agent. Supported: subsidiary, parent, trademark."
    }
  ]
}