> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up operator and brand identity in chat

> Inspect commercial identity, confirm changes, and follow proof and review status through a text-only v3 MCP client.

An account administrator can set the commercial operator domain and scope,
inspect an advertiser's linked brand, and follow supported verification work
through v3. The responses include the details in text; an MCP App or Settings
page is not required for these steps.

Commercial identity, public branding and domain proof are separate. Saving a
domain or finding a public `brand.json` does not grant account access, prove
domain ownership or authorise an agent to act for that brand. Organisation
names, login domains, users and roles are outside this setup flow.

## Select the confirmed identity contract

For this workflow, send `identityContract: "confirmed-v1"` on every operator
identity save or advertiser brand correction. Keep it on the preview,
confirmation and retry calls. Replacing an existing identity in this contract
requires a preview and the person's explicit confirmation; omitting the token
returns `CONFLICT` without saving.

This contract coexists with earlier v3 saves on the same tools. Calls using
only the earlier fields retain their existing behaviour, including one-call
Buyer operator and advertiser brand updates and the Seller's
`confirmOperatorDomainProfileReset` check. They do not acquire a new preview
requirement. New setup integrations should select `confirmed-v1` explicitly.
Supplying `preview` (including `false`), `confirmationToken`, or an advertiser
update's `publicBrand` also opts into the confirmed contract. An unsupported
`identityContract` value is rejected; it does not fall back to an earlier save.

## Find the account and its current identity

Call `tools/list`, then `get_status`. Use `switch_account` with an account ID
returned by `get_status` if you need a different account, and read status
again. A principal with several accounts must select the Buyer or Seller
Account it intends to configure. An Organisation-only account provides
orientation and support asks; it does not expose a separate identity editor.

| Active account   | Read                                                   | What to inspect                                                                      |
| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| Buyer            | `get_status`                                           | `operatorIdentity`: domain, source, scope, unit, lock, domain proof and AAO evidence |
| Seller           | `get({ "kind": "seller", "include": ["identity"] })`   | Operator domain, verification, saved branding and the current human review           |
| Buyer advertiser | `get({ "kind": "advertiser", "id": "ADVERTISER_ID" })` | `brandIdentity`: BrandRef, saved name, logo, manifest URL and provenance             |

For a Buyer, `operatorDomainSource: "legacy_customer_domain"` identifies a
fallback from the account record. It is not a confirmation of commercial scope.
`domainProof` reports the separately recorded verification and its source.
`organization` and `aao` describe the evidence used by readiness; inspect them
alongside `scopeStatus` and `locked`.

For an advertiser, `source: "saved_brand_link"` means a saved branding snapshot.
It does not assert that a published document is available now. A Seller's
`identity.source: "storefront_config"` likewise describes saved configuration.
`manifestUrl: null` means that this read cannot identify a published URL.

## Confirm the Buyer's operator

Use `save_buyer_operator` as an account administrator:

```json theme={null}
{
  "identityContract": "confirmed-v1",
  "operatorDomain": "agency.example",
  "operatorScope": "whole_operator"
}
```

For one office, team, region or seat, use `operatorScope: "specific_unit"` and
a stable `operatorUnitId`. Do not invent a unit called `default`.

Before replacing an existing domain or confirmed scope, send the proposed
values with `preview: true`. This explicitly requests `action: "preview"`
without saving. Show the person the before and after values and any loss of
domain proof. After they confirm, repeat the same request without `preview`
and with the returned `preview.confirmationToken`.

In `confirmed-v1`, an unconfirmed replacement that does not request a preview
returns `isError: true` with `code: "CONFLICT"` and saves nothing. A successful
preview is returned only when you explicitly request one. A caller that
attempts an unconfirmed replacement in this contract receives an error rather
than a successful-looking result that preserves the old identity.

The confirmation belongs to that account, current identity and requested
change. A stale or different confirmation fails with `CONFLICT`; read and
preview again. An identical retry with no new proof returns `unchanged`,
preserves confirmation timestamps and domain proof, and does not create a
second identity audit event.
A successful write returns a resource receipt and its audit ID.

Read `get_status` again to check the persisted domain, scope and proof. The
first advertiser binding locks the operator identity. A locked correction
requires support, rather than a different domain spelling or another account.

## Resolve and link public branding

In a Buyer Account, call `save_advertiser` with only:

```json theme={null}
{ "resolveBrand": "brand.example" }
```

In a Seller Account, the same lookup is available through `save_seller` with
only `resolveBrand`. Both lookups are read-only. They require a published
`brand.json` or an AAO-hosted brand identity and do not fall back to inferred
branding. Inspect `resolved`, `identity.brandRef`, `identity.source`, name,
logo and `manifestUrl`. An unavailable registry returns an error; a missing
brand returns `resolved: false` and may supply a builder link.

To create a Buyer advertiser that requires public branding, call
`save_advertiser`:

```json theme={null}
{
  "name": "Example brand",
  "brand": "brand.example",
  "publicBrand": true,
  "idempotencyKey": "example-brand-setup-1"
}
```

This create operation does not accept `identityContract`; use that field only
when correcting the brand of an existing advertiser.

Keep the key and creation fields unchanged when retrying. A key reused for a
different request is rejected. The creation receipt includes its audit event
ID. Existing calls that omit `publicBrand` retain the normal brand-resolution
behaviour, which may include inferred branding.

To correct an advertiser's brand, supply `identityContract: "confirmed-v1"`,
`advertiserId`, `brand`, `preview: true`, and optionally `publicBrand: true`.
An account administrator must review the returned preview and repeat the
request without `preview` and
with its top-level `confirmationToken` after the person confirms. An
unconfirmed replacement in this contract without `preview: true` returns
`CONFLICT` and saves nothing. A saved replacement returns
`advertiser.identityChangeReceipt` with its audit ID and brand-link IDs. Read
the advertiser again to verify `brandIdentity`.
The first campaign or seller-account binding locks advertiser identity.
If `brandIdentity` is null, the saved link cannot be inspected safely. Request
support with `save_ask` to repair that legacy record before replacing it.

An identical brand-only retry does not rewrite the link. With `publicBrand:
true`, it also checks that public identity is currently available and returns
that lookup separately from the saved snapshot. It does not refresh the saved
name, logo or document contents.

<Note>
  v3 can resolve public branding and link an advertiser to a resolved brand.
  It cannot create, edit or publish `brand.json`, choose who owns an AAO-hosted
  document, or refresh a saved snapshot in place. Use the domain publisher or
  the returned external builder for document changes. These responses report
  `editingSupported: false`. A public lookup is never domain proof.
</Note>

## Confirm the Seller's operator and follow proof

Use `save_seller` as an account administrator:

```json theme={null}
{
  "identityContract": "confirmed-v1",
  "operatorDomain": "seller.example"
}
```

For a replacement, include `preview: true` before any fields change. Review
the previous domain, proof and profile values, then repeat without `preview`
and with its top-level `confirmationToken` after the person confirms. An
unconfirmed replacement in this contract without `preview: true` returns
`CONFLICT` and saves nothing. Fields curated for the previous domain, including
description, channels, membership status and website, may be
cleared. Description and channels can be supplied in the same request to
replace those values; the other legacy profile fields are not writable in v3.
An intervening identity or profile change requires a fresh preview. The older
`confirmOperatorDomainProfileReset` flag alone does not replace a confirmation
token in `confirmed-v1`; its earlier behaviour remains available to existing
callers as described above.

The save returns a receipt with its audit ID and, when present, the domain
review ID. Saving the domain uses the existing verification service and human
review queue. An already approved domain may verify immediately; otherwise the
current review is visible through:

```json theme={null}
{ "kind": "seller", "include": ["identity"] }
```

Inspect `operatorDomainVerified` and `identity.domainProof.review`. The review
contains its ID, domain, status, request time, revision, decision time and ETA
when assigned. Poll this same read after the human responds. `PENDING` is not
proof; `REJECTED` requires a correction or support follow-up. Verification is
complete when the persisted domain matches the intended domain and
`operatorDomainVerified` is true. A repeated identical save does not duplicate
the review. Saving a Seller domain does not copy the public lookup's logo or
other document fields into Seller configuration.

A domain-only save for the already saved domain returns `unchanged`; members
can make that request without administrator write permission or a proof-review
read. Actual domain changes require an administrator. Proof reads are
cancellable and have a bounded wait. If a transient read failure returns
`SERVICE_UNAVAILABLE`, retry `get`.

## Request a person when proof or correction needs help

Show the person the proposed support request before filing `save_ask`:

```json theme={null}
{
  "type": "support",
  "title": "Verify our commercial operator domain",
  "detail": "Our saved operator is agency.example. We need help completing domain proof. Please provide the verification steps."
}
```

Keep the returned `askId`. In a Buyer or Seller Account, poll it with
`get({ "kind": "ask", "id": "ASK_ID" })`, follow the human's instructions,
then re-read identity. A filed or resolved ask does not itself verify a domain.
Do not paste passwords, OAuth tokens or other secrets into chat.

If support approves a Buyer domain, repeat `save_buyer_operator` with the saved
domain and scope to record that approval, then check `get_status` again. The
save checks approved evidence separately; repeating domain text without that
evidence cannot verify it.

Buyer AAO OAuth verification currently has no portable v3 initiation or
callback flow. v3 can inspect its evidence and request human help, but cannot
complete that OAuth proof in a text-only host. A Seller review with no current
record, a rejected review, or a locked identity correction can use the same
support path. [Shared workflows](/v2/setup/v3/shared-workflows) covers ask
states and follow-up.
