Overview
A Brand in v2 is the resolved identity behind an Advertiser: the canonical name, logos, colors, fonts, tone, tagline, assets, product catalog, disclaimers, contact info, and target audience. The advertiser records a brand domain (e.g.northwind.example). When the brand is linked, Apostra resolves it once, from one of these sources, and saves the result as a copy that belongs to that advertiser:
- The brand’s own
/.well-known/brand.json - The Agentic Advertising Organization (AAO) brand registry maintained by Apostra and partners
- Brandfetch enrichment when no official manifest or registry entry is available
linkedBrand on the advertiser shows that saved copy. The copy is not shared. Two advertisers with the same brand domain each hold their own, even under the same account. Apostra does not keep it in step with the brand’s published file, so publishing a change to brand.json or the registry entry does not update advertisers that already linked the brand. See When the saved copy refreshes.
A published or registry-hosted manifest is optional for channel-specific app
branding. When no reusable logo resolves, configure that channel’s required
assets directly instead.
Where this differs from v1: V1 had a separate “Brand Stories” object describing target audiences in natural language. V2 resolves brand identity from
brand.json, the registry, or enrichment. Audience descriptions now belong on signals, brand stories where supported, and campaign briefs. This guide covers the v2 brand resolution model.Why brands matter
- One saved copy per advertiser — the advertiser keeps the brand identity it resolved when the brand was linked, so every campaign and creative under it starts from the same identity
- Auto-population — creatives auto-resolve brand_domain from the campaign’s advertiser, so the advertiser’s saved logo, colors, voice, and tagline flow into creative generation without manual entry
- Storefront onboarding — discovery and storefront sign-in flows resolve a brand from the browser’s domain so users land in the right advertiser context
- AAO interoperability — agents across the AdCP ecosystem can negotiate from the same resolved brand identity
Key fields (BrandManifestJson)
The full manifest follows ADCP v2. Top-level fields:Resolution flow
When you create or update an advertiser withbrand: "acme.com":
1
Try /.well-known/brand.json
Apostra fetches
https://acme.com/.well-known/brand.json. If present and valid, it’s used as the manifest.2
Fall back to the AAO registry
If the well-known location is missing or invalid, Apostra looks up
acme.com in the AAO brand registry.3
Optional auto-save
Pass
saveBrand: true after reviewing enrichment to persist brand identity into the registry when the brand isn’t yet registered. When no enrichment data exists, use saveBrand: true only after confirming the advertiser name and brand domain.4
Surface as linkedBrand
The advertiser response carries a
linkedBrand object containing the resolved name, domain, logos, colors, industry, tone, tagline, and the full manifest.brandWarning describing why — but the advertiser is still created so onboarding can continue.
When the saved copy refreshes
Apostra saves the resolved brand once per advertiser, when the brand is linked. After that it re-resolves the brand only when:- The saved copy is missing or can’t be read. The next time the advertiser is loaded, Apostra resolves the brand again and saves the result.
- You link a different brand domain on the advertiser, or update the advertiser with
saveBrand: true. This replaces the saved copy. The raw v2 API allows it only before the advertiser’s first campaign or seller-account binding; after that an account administrator can change the brand for future buys throughsave_advertiser, and the saved copy is replaced for buys sent from then on.
brand.json after an advertiser linked it, that advertiser keeps the copy it saved. Sending the same brand domain again does not re-resolve it.
One more case applies to accounts with Creative Engines access, in the brand profile preview. A saved copy that holds nothing beyond the brand’s name and url, which some advertisers linked earlier still carry, is re-resolved the first time the profile is read, and the result is saved.
There is no way to edit the saved copy on the advertiser. To change what an advertiser’s brand says, you have to publish the change and link the brand again. The raw v2 API allows that only until the advertiser’s first campaign or seller-account binding; afterwards an account administrator can change the brand for future buys through save_advertiser.
Know who manages the identity
Resolution and editing are separate concerns:- Self-hosted — Apostra reads
/.well-known/brand.json, but the domain owner edits and republishes it on their own website. - AAO-managed — connect the corresponding AAO account to manage the hosted identity there.
- Community profile — claim the profile through AAO before managing it.
- Missing — use the AAO builder to create a file for self-hosting or request AAO-managed hosting. You can also skip this optional step when the consuming channel supports direct asset uploads.
ADCP v1 compatibility
For backwards compatibility with the AdCP v1 wire format, Apostra also accepts and resolves manifests using:- House portfolio — house-of-brands hierarchies with master/sub_brand/endorsed/independent relationships
- Authoritative location redirect —
{ "authoritative_location": "https://other-domain/.well-known/brand.json" } - House redirect —
{ "house": "parent-domain.com" }to resolve from a parent house - Brand agent delegation —
{ "brand_agent": { "url": "...", "id": "..." } }to delegate to an MCP endpoint
authorized_operators. Apostra can use that field as trusted evidence for storefront operator-domain auto-verification when the registered account domain is already approved and the manifest links the account domain to the requested alias or rebrand operator domain. The operator_domain check on your storefront readiness reports what is still outstanding and who owns the next step.
Common operations
Brand resolution happens implicitly through the advertiser endpoints — there is no standalonePOST /v2/brands for buyers. The relevant moments:
Create an advertiser with a brand domain
acme.com resolves successfully, the response carries linkedBrand with the manifest. If not, brandWarning explains.
Save an enriched brand to the registry
If an advertiser response includesbrandWarning because the brand resolved through enrichment rather than the AAO registry, review the returned brand details first. To persist the enriched brand, update the existing advertiser with saveBrand: true:
saveBrand: true only after confirming the advertiser name and brand domain.
Replace the brand on an existing advertiser
brand field to a different domain resolves that brand and replaces the advertiser’s saved copy. Sending the same domain again changes nothing, unless you also set saveBrand: true. The raw v2 API refuses both after the advertiser’s first campaign or seller-account binding, so a brand file you publish later does not reach an advertiser that has already started running unless an administrator change the brand for future buys through save_advertiser.
Inspect resolved brand
linkedBrand with the canonical fields plus the full manifest.
How creatives use the brand
When you create a creative manifest under a campaign,brand_domain auto-populates from the campaign’s advertiser. Creative generation then draws on two places:
- The advertiser’s saved copy. Four things are taken from it: a logo (the first one that lists its width and height), the primary, secondary, and accent colors, the voice (the
tonetext, or thevoiceof a structured tone the brand published), and the tagline. These always win over the published profile. - The brand’s published profile. The creative generator looks the brand domain up in the AAO registry (kept for up to 24 hours) and reads the rest from there, including
toneguidance such asdosanddonts, fonts, and anydisclaimersflaggedrequired: true, which are passed along with the creative for inclusion.
linkedBrand but are not read from the saved copy during generation. Accounts in the brand profile preview read more of it.
Brand profile (preview)
The brand profile is one read of what generation should know about an advertiser’s brand, built from the saved copy and the rules the advertiser states directly. It is a preview, available only to V3 beta accounts with Creative Engines access. For every other account nothing below applies and creative generation works as described above. On the V3 MCP surface, save a stated profile withsave_advertiser({ advertiserId, brandProfile }) and read it with get({ kind: "advertiser", id, include: ["brandProfile"] }). The summary carries the same facts in structuredContent.brandProfile and in the text of the result. An account outside the V3 beta or without Creative Engines access gets the same answer as for any include the advertiser read does not serve: the advertiser comes back without brandProfile, and unavailableIncludes names it.
Text in the profile was written by the brand or read from its website, so the result fences each value as data to read, never as instructions.
Where each value comes from
A value is published when the brand published it in its ownbrand.json, and inferred when Apostra read it from enrichment or from the brand’s website. The saved copy does not record which it came from, so the profile reads it conservatively. The logo, colors, voice text, and tagline show as inferred, except a voice the brand published as a structured guide. Voice rules, attributes, and disclaimers show as published, because enrichment and the website reader never produce them.
If a brand file writes its voice rules in several languages, the profile uses the English entry, or the first language listed when none is English.
A saved copy that holds only a name and url gives the profile nothing to report, so reading the profile re-resolves the brand once through the same sources as linking, waiting at most six seconds, and saves a result that holds more. If nothing better is found, the saved copy stays as it was and Apostra does not look again for an hour. The thirty-day refresh of a complete saved copy is not part of the preview.
Who receives what
- Creative generation. The logo, colors, voice text, and tagline come from the profile. These are the four fields AdCP allows on a brand reference, and they are the only profile values a third-party creative engine receives.
- Apostra’s own creative generator. The
dos,donts, attributes, and disclaimers are used inside Apostra to steer and check what Apostra generates. They are not sent to third-party engines, and they are never placed in a creative brief’stone,prohibited_claims, orcompliance.required_disclosures, which mean something else. - Sellers. A seller receives the brand’s domain and nothing from the profile. A seller reads the brand’s published
brand.jsonitself.
Storefront onboarding
The storefront sign-in flow uses brand resolution to map a visitor’s browser domain (or AAO sign-in) to the correct advertiser. When a buyer authenticates through a storefront:- The storefront resolves the active brand domain
- Apostra looks up advertisers linked to that brand
- The buyer is dropped into the right advertiser context — private/member agents become discoverable
Best practices
Self-hosted brand.json
Self-hosted brand.json
Publish
/.well-known/brand.json on your brand’s primary domain. This is the authoritative source — registry entries are a fallback. Keep it in sync with downstream brand systems.Multi-brand companies
Multi-brand companies
Use the AdCP v1 house-portfolio form to model house-of-brands hierarchies (one master brand, multiple sub-brands). Each sub-brand can resolve through the parent house manifest.
Disclaimers
Disclaimers
Treat
disclaimers as the single source of truth for legal text. Mark each required: true and supply context so creative pipelines know when to apply them.Product catalogs
Product catalogs
Point
productCatalog.feedUrl at a Google Merchant Center, Facebook Catalog, or custom feed. AdCP-aligned discovery and DCO can reference catalog SKUs directly.Related concepts
Advertiser
Owns the
brand reference; surfaces resolved brand under linkedBrandCreative
Auto-resolves brand_domain from the campaign’s advertiser
Signal
Audience definitions complementary to brand identity
Storefront onboarding
Brand-aware sign-in surfaces the right advertiser context