Skip to main content
Deprecated. This page documents the v2 storefront API, which is being retired for external callers. Use Admit an external buyer and inspect delivery and the Buyer Account Mapping Page in V3 instead.
Buyer Account Mapping gives a seller one account for each complete AdCP AccountKey and shows the verified buyer organisation that owns it. The seller can privately see whether each inventory source has a current mapping. Operator and brand still group the list for navigation, but they do not identify an account or carry an approval on their own.

Where to find Buyer Account Mapping

In the seller navigation, choose Storefront, open Buyers under Your storefront, then select Buyer Account Mapping. This opens the full mapping Page without requiring a chat request. For one buyer relationship, open Buyers the same way, select the buyer, then open Account. That opens the same relationship’s focused account-setup case. Inventory Sources and ad-server connection settings manage the source connection and its roster health. Buyer account mapping is configured from Buyer Account Mapping or the focused Account case, not from the source connection.
The complete-key experience is staged behind a customer cutover and is off by default. Until a storefront is enrolled, the Page keeps the released relationship-based view and six-column v1 feed. On the complete-key path, the same import Task uses the versioned v2 feed format. A missing or failed cutover decision does not switch the Page to an empty exact-account view.
Open the portable Page with the storefront MCP tool:

What is canonical

An account is identified by its storefront and complete AccountKey:
  • brand domain, optional brand ID, and optional country set;
  • operator domain and optional operator-unit ID;
  • optional fixed currency and buyer-selected timezone; and
  • sandbox value.
The Page shows every field, including absent optional fields, alongside the verified buyer organisation. A CRM record, GAM advertiser, FreeWheel reference, operator, brand, user credential, or another native ID can support the account, but none replaces this identity. An omitted country qualifier means all countries. An explicit country set is preserved as part of the AccountKey, so US is not the same account as all countries. Older relationship rows whose country scope is unknown are setup-incomplete: they cannot be shown, approved, or used as complete-key accounts. The sync_accounts wire type has no country field; omit it there and use the reviewed v2 mapping flow when recording an explicit country set. This keeps two native accounts with the same literal ID separate. For example, 1234 under gam-primary and 1234 under freewheel-ctv are different source mappings even when both support the same buyer relationship.

Account authority during the complete-key cutover

For a storefront enrolled in the complete-key cutover, an opaque account ID is a reference, not a credential. Every list, discovery, creative-sync, and media-buy operation rechecks the approved account’s verified buyer organisation, advertiser scope, active seller decision, and the current human or service-token authority before contacting a source. Authorised colleagues can use the same approved account while audit records the actor that performed each action. Removing the owner, seller decision, or actor authority blocks the next operation. A pending task or deferred retry repeats those checks when it runs; it does not trust the credential that originally created the work. Another organisation cannot use the account, including by supplying its opaque ID. The older relationship-based view is never treated as a complete-key approval. After a seller is enrolled, existing relationship rows remain visible as Existing relationship rows. They have partial identity and stay read-only for identity: they are not an AccountKey, are never promoted to complete-key authority, and cannot be used as AdCP 3.2 accounts. A seller can still review a pending existing request and maintain its existing source mapping through the released relationship workflow; those actions record the original relationship and actor, not an inferred AccountKey. During a seller’s complete-key rollout, AdCP 3.0 and 3.1 sync_accounts can only read an exact credential-owned legacy row that already exists. That read returns its recorded status; it never applies or reports a new billing or payment-term request. It cannot create a request, reserve an authority, or call an upstream seller. A new, incomplete, or ambiguous legacy request receives ACCOUNT_SETUP_REQUIRED and must use the seller’s ordinary setup flow or an exact AdCP 3.2 identity. Once the seller is enrolled, list_accounts, discovery, creative sync, and media-buy operations on the public AdCP 3.0 and 3.1 Storefront MCP work with two kinds of account, chosen by the account_id itself: approved complete-key accounts, through the same checks as above, and the credential-scoped accounts a buyer credential already held, which stay usable by that exact credential only. A buyer agent sends the opaque account_id alone, as described in Address your approved account from a direct AdCP 3.0 or 3.1 agent. A credential account is never converted into a complete-key account. A storefront that is not enrolled keeps the released relationship readers. On a storefront that is not enrolled, an approved relationship account belongs to the buyer organisation. Anyone authorised in that buyer account, whether a colleague or a service token of the same buyer, can use it for discovery, creative sync, and media buys. A person’s own grant is used first. If their own grant is not active, for example because it is waiting for payment readiness, they are refused rather than given a colleague’s. The same holds for sync_accounts: a request from a colleague or service token for an account the organisation already holds returns that account as unchanged and opens no second account, unless the caller already has its own grant or request for it. Requested payment terms that differ from the account’s terms are not applied. list_accounts follows the same rule: it lists the account to a colleague or service token of the same buyer organisation, not only to the credential that set it up, unless that caller has its own request for the account, which is listed instead. A person who works in a different advertiser still sees the account their colleague set up. The account is never shared with another organisation. Once the storefront is enrolled, the complete-key account is the shared one, and older credential accounts stay with their own credential.

How account requests resolve

Each sync_accounts request has one resolution authority. A storefront that builds or mixes inventory resolves the request through its own intake policy. A pure pass-through storefront always delegates it to its one sales agent, which does buyer review. To take the request, the agent must list both sync_accounts and list_accounts in its tools and must not require operator authentication. If the agent cannot, or the storefront has more than one active agent, which is not a valid pass-through setup, the request fails with CONFIGURATION_ERROR, a terminal error the buyer should not retry; the seller has to fix the setup. Automatic account requests for that storefront wait until it is fixed. Apostra does not run local intake and then forward the same request, or broadcast it to several possible account authorities. On a pass-through storefront, each returned account’s action describes the buyer’s account on this storefront, not the sales agent’s own account. The first request for an account the buyer organisation does not yet hold returns created, even when the agent already had an account for that brand and operator. A dry run returns created with status pending_approval for such an account without calling the agent; only a request that is not a dry run records the account, so list_accounts shows it only after that request.

When your sales agent manages accounts

On a storefront whose sales agent manages buyer accounts, the agent reviews buyers and the Buyers view is read-only. Each buyer shows the agent’s decision: accepted by the agent, rejected by the agent, or waiting on the agent. The agent receives the payment terms the buyer requested and must accept them or reject the account. A new account the agent offers on other terms is treated as a refusal and waits for the buyer. An existing account the agent keeps on other terms stays usable, but it shows a warning naming both terms. An accepted account reports the terms the agent confirms in payment_terms; each time Apostra re-reads the agent’s accounts, those terms are updated to what the agent reports. You can see each buyer, its status, its account sync and its billing readiness, but you cannot approve, decline or map a buyer account (including through a mapping import), ask the buyer for information, or assert or revoke billing readiness, and the API refuses those requests with ACCESS_DENIED. The one exception is a request that was already waiting on you before the agent took over: you can still accept or decline it, so it does not stay stuck.

Buyer API requests

The buyer API (POST /api/v2/buyer/storefront-accounts/sync and the sync_buyer_storefront_accounts tool) resolves through the same authority as a buyer calling your AdCP endpoint and as an account Apostra opens automatically, so all three reach the same decision for the same account. When complete AccountKey mapping is enabled for the buyer, the buyer sync_accounts API and MCP tool create a request for the verified buyer organisation, not for the credential that sent it. The request must have a selected advertiser and an authenticated human or service token. Apostra checks that actor and the buyer’s current eligible lifecycle again while it records the request. Colleagues and permitted service tokens can therefore request the same exact AccountKey and receive the same seller decision, while each request retains its own audit actor. list_accounts uses that same mode, so a pending or accepted request, and an account blocked on billing readiness as payment_required, is visible to each authorised actor. Until that cutover is enabled, the released relationship-based request and list behaviour remains in place. For a buyer with no lifecycle record yet, a non-dry-run account request can create the first record when the buyer has exactly one verified, non-sandbox organisation owner and the caller is currently authorised for that buyer. A child account’s owner is its parent organisation’s verified WorkOS organisation, so a child needs no members of its own. Accounts in the same organisation hierarchy can share one verified owner, each with its own seller accounts. This does not require an existing seller connection. The request checks that authority again before it records a seller-account intake, so a changed owner, revoked lifecycle, or removed caller permission stops the request without a seller decision. Creating that first record is separate from the seller-account request: the record can remain when the later request does not complete. An existing disabled, revoked, or replaced lifecycle is not reset by a request. If a buyer has no verified owner, more than one verified owner, or an owner claimed by a different organisation hierarchy, sync_accounts returns ACCOUNT_SETUP_REQUIRED. For a child account, a missing owner means its parent organisation has no verified WorkOS organisation yet. Confirm the buyer’s verified organisation and use an authorised administrator or write-capable service token before retrying. list_accounts and dry runs do not create lifecycle records. The wire request supplies the identity fields it supports. Omitted optional fields remain absent; an omitted country qualifier means all countries and is never guessed from another account. If the seller cannot establish the complete identity or the actor is no longer authorised, no account permission is created. The normal seller account-setup action remains the way to supply or confirm missing identity and source information. An agent that does not list both sync_accounts and list_accounts, or that declares require_operator_auth, is not a supported source. Apostra always calls the agent with the seller’s connected credential and never passes a buyer’s own credentials through, so the agent must accept that credential for every buyer and take buyer account requests itself. Such an agent fails the matching check in its Agent page’s required capability declarations: Takes buyer account requests or Accepts the connected credential for every buyer. On a pass-through storefront there is no local-review fallback: until the agent is fixed, new buyer account requests through that storefront fail, and the seller cannot approve them instead. A request that was already waiting on the seller before stays with the seller, as described in When your sales agent manages accounts. Once the agent lists sync_accounts and list_accounts and does not require operator authentication, account requests go to it. Before an external mutation, the storefront persists a non-authorizing authority reservation. Existing grants or seller-owned intakes keep retries on their original local read-back path even if storefront topology changes. Delegated decisions are stored locally as an observed-state mirror so buyers can read pending, accepted, and rejected status consistently. The mirror is not a second approval: upstream-owned pending requests never appear in the local seller review queue, and one accepted upstream decision creates at most one local account authorization. When an external sync_accounts call is asynchronous, the storefront returns a buyer-pollable task and immediately refreshes that authority with list_accounts. One unambiguous exact account row from the refresh settles the task. Several native accounts with the same operator, brand, and sandbox remain mapping candidates and do not decide buyer access. External authorities that accept asynchronous work must explicitly advertise a reconcilable account roster. The storefront verifies that capability before forwarding the request, and a missing or unknown upstream account status never creates access. If the configured authority is missing, unavailable, or ambiguous, the request fails before creating access or changing a source mapping. A future account-level CRM/MCP resolver follows the same rule: it returns exact mapping evidence into the canonical relationship and source-mapping records; it does not create a parallel CRM-owned mapping. Existing manual mappings and mappings owned by a different feed remain protected from overwrite.

Brand IDs on buyer requests

A buyer may name a brand inside a house of brands by sending a brand_id with the brand domain on get_products, create_media_buy, or sync_accounts. Before the storefront passes that request on, Apostra checks that the brand’s /.well-known/brand.json (or a registry entry the brand owner verified) lists that brand_id. Requests that pass, or that cannot be checked, go through unchanged:
  • Listed: the brand publishes the brand_id.
  • Account already held: the buyer already holds a seller account on this storefront under that brand domain and brand_id, so existing accounts keep working.
  • Registry unavailable: the brand registry can’t be reached.
Otherwise the storefront returns a VALIDATION_ERROR naming the field and the brand’s brand.json, and the buyer should send a listed brand_id, or omit it for a single-brand domain. Apostra keeps each brand’s record for up to a day, so before rejecting it reads the record again if its copy is more than an hour old. A brand_id the brand publishes can therefore still be rejected for up to an hour after Apostra last read the brand’s record; after that, it is accepted. Apostra is turning this rejection on storefront by storefront. Until it is on for a storefront, an unlisted brand_id is recorded and the request goes through.

The account key a third-party sales agent receives

When an account has no mapping to a third-party sales agent’s own account, Apostra sends the agent the account’s AccountKey, limited to the fields the agent’s AdCP version can read. Apostra calls third-party agents on AdCP 3.1, which carries the brand domain, brand ID, operator and sandbox. The brand’s country set, operator unit, currency and timezone belong to an AdCP 3.2 key and are not sent. Accounts whose keys differ only in those fields therefore use the same agent account, while accounts with different brand IDs use different ones. Apostra uses the account ID the agent returns from sync_accounts for that key, or sends the key on every call when the agent issues no account IDs.

Your own sales agents on a storefront that combines sources

When your storefront combines several inventory sources and one of them is an external sales agent you connected, such as your ad server’s AdCP agent, that agent is your own infrastructure, not a seller to your buyers. Apostra calls it with the credential you gave when you added the source, and you decide which of its accounts each buyer uses:
  • An agent that lists its accounts. Its account listing is that source’s roster in Source coverage. Map each buyer’s account to one of the listed accounts; buys, creative syncs and reports then send that account’s ID.
  • An agent that cannot list its accounts. When you approve a buyer, Apostra asks the agent once for that buyer’s account, naming the buyer’s brand and agency, with billing: agent: the agent invoices you under your own contract with its operator, never the buyer. Apostra records the answer. An account the agent accepts is used for that buyer from then on; a refusal is kept for a person to take up with the agent and is not retried. Buyer activity never asks the agent again. Until the agent has an account for the buyer, a product search reaches it without an account, so it answers as it would anyone, and a buy or creative upload that uses that source is refused as not yet linked.
A storefront whose only source is one external agent is different: that agent is the seller and decides buyer accounts itself (see When your sales agent manages accounts).

Page views

  • Accounts shows each complete AccountKey, its verified buyer owner, and the seller’s decision for that exact account and owner. API rows expose the exact sellerAccountId separately from the optional legacy relationshipId; the latter is navigation-only and is never source-account or approval identity.
  • Existing relationship rows show pre-cutover relationships alongside complete accounts. They retain the released relationship review and source-mapping controls, but never display or create a complete AccountKey. In the complete-key API response, items and its pagination remain exact AccountKey rows; retained rows are additive legacyItems. API clients can page the released relationship workflow explicitly with identityKind=legacy_relationship.
  • Source coverage expands the exact seller account across active inventory sources. Coverage is Mapped, Not required, Not set up, Needs account selection, or Stale. Source names and native IDs remain seller-private. For a third-party sales agent with no mapping, discovery, media buys and creative sync use the account the agent returned from sync_accounts for the buyer’s brand and operator, or send the brand and operator when the agent issues no account IDs. The agent’s account listing suggests mapping candidates here; it never decides which account a call uses.
  • Sources shows the last account-listing attempt, last complete snapshot, observed/missing counts, and whether Apostra or an upstream sales agent owns the account lifecycle. Sellers can refresh a supported source without discarding the last complete snapshot when the new listing fails or is incomplete.
The Page is paginated and searchable. It does not expose private source topology or source-native account IDs to buyers. The buyer total is storefront-wide: it counts distinct verified buyer organisations represented by currently eligible exact accounts and does not change with search, relationship filters, or pagination. A rejected seller decision does not erase the verified owner, so the account remains in that ownership total. Revoked or stale buyer lifecycle records are excluded from both the total and coverage summary.

Account setup in Buyers

To see buyers, open Buyers under Your storefront in Storefront. Each buyer reached through an AdCP account relationship appears in its picker; advertisers you operate stay in Managed campaigns. A buyer whose setup case is waiting on you shows Awaiting you and counts toward the picker’s attention badge. There is no separate inbound-requests inbox; a pending buyer is a picker entry like any other. Selecting a buyer scopes its jobs to that exact seller relationship: Media buys with you (its approval work and active buys), Creatives synced to you, Delivery on your inventory (available once the buyer is admitted), and Account, which opens the same account-setup case drawer available from Buyer Account Mapping. Where Sessions is available, Sessions opens the timeline filtered to that buyer. None of these jobs shows the buyer’s own campaigns, and a relationship that has not resolved yet offers no jobs. Seller storefronts retrieve this projection from GET /api/v2/organization/advertisers/account-setup.
  • Needs setup — waiting on you means the case is blocked on the seller; you provide or confirm the required setup details.
  • Waiting on buyer means a live request for information is with the buyer; the buyer needs to respond.
  • Awaiting billing means the relationship has a grant requiring payment and billing readiness is not established; it clears when a valid ready-to-invoice assertion for that billing entity reactivates the grant.
These are neutral setup statuses, not storefront-health errors. Buyers with a closed or inapplicable case do not show a setup status. Advertisers you operate (House and Self-serve) do not carry a buyer account-setup status, because there is no relationship or setup case behind them.

Money view

Buyer Account Mapping does not derive proposal or spend rollups by joining an exact account back to the older operator-and-brand relationship. Those values remain unavailable until they can be attributed through an exact account route. Use Sessions and Reporting for current commercial activity.

When an account listing does not complete

Only a complete reading of a source’s account roster replaces the last complete snapshot. An attempt that stops short records a diagnostic and leaves the previous snapshot in place, so a partial read never archives accounts that still exist. The diagnostic names whose limit stopped the attempt, because the remedy is different in each case:
  • INCOMPLETE_LISTING — the source itself answered with a partial roster, or reported an error while reading it. Check the ad server or sales agent: a permission that no longer covers the whole roster is the usual cause.
  • ROSTER_DRAIN_TIMED_OUT — Apostra ran out of its own time budget before finishing the roster read. Scheduled attempts get a longer budget than a refresh you trigger by hand, so this often clears on its own within the next polling cycle.
  • ACCOUNT_LISTING_FAILED — the roster read itself failed. Inspect the inventory source connection and its credentials.
Apostra follows pagination to the source’s terminal page and does not impose an account-count ceiling. Large complete rosters are published in database batches. A source that has never once produced a complete snapshot has no accounts to map, so no buyer relationship can reach Mapped coverage on it — and for a provider that requires an explicit account, that leaves the source unable to execute. Apostra alerts on that state rather than retrying silently.

Select from the full source roster

When a source needs an account, page or search its complete observed roster in the Page (the list_seller_account_source_roster operation), then map one authenticated native account to the exact seller account. The Page does not treat an operator, brand, or sandbox match as approval or as evidence that a source account belongs to a different complete AccountKey. A dedicated native account stays owned by that complete AccountKey after its current mapping is archived, so it cannot later be rebound to another key. Use Interchange default mappings remain intentionally shareable.

Review pending buyer access

When a buyer requests access to a relationship that requires seller approval, the request stays pending until a storefront administrator decides it. List the pending requests with list_seller_account_grant_reviews in storefront MCP; in V3, get of the account_relationship shows each pending request in admission.actions. Each row includes the current version needed to prevent a decision against stale review state, the snapshotted policy result, CRM-match status, and the canonical intakeId. The released grantId field remains as a deprecated alias for compatibility; a pending review is not an authorization grant. For a retained existing-relationship review during the complete-key rollout, the Page sends that row’s relationshipId with the decision. This keeps the decision tied to the recorded relationship even if an independent complete-key intake has the same opaque intake ID; it does not turn the relationship into an AccountKey or request the buyer’s approval again. Seller relationship rows expose each pending request’s resolution authority, requested billing path, billingReady, and truthful allowedActions. Direct operator or advertiser billing cannot be accepted until its billing entity is resolved; link_existing remains available to supply that verified entity. Use decide_seller_account_grant_review with decision: "accept" to accept using the billing path already resolved for the request. The released approve_interchange value remains a compatibility alias for agent billing. link_existing is the legacy direct-billing acceptance path: it requires an operator or advertiser billing entity, but it does not create a CRM link or inventory-source mapping. Rejections require a reason. A buyer’s request can name the payment terms it wants, such as net_60. The review shows them, and accepting the request accepts those terms: the account then reports them in payment_terms. There is no counter-offer. If the terms don’t work for you, reject the request and say why. A request for net_60 or shorter terms (or prepay) is approved automatically, and a request that names no terms counts as net_60. Longer terms wait for your review. You can’t change this limit yet; see New buyer accounts. While a request is pending, the buyer can send different terms, which replace the earlier ones. Once you have decided, the decision and its terms stand; a later request for different terms is refused on that account and changes nothing. When a buyer must choose payment terms before an agent-billed account can open, that is a buyer setup step rather than a seller failure. Discovery continues without opening the account only when the seller explicitly declares that an account is not required: that seller receives a public discovery request. A seller that requires an account, or does not declare whether it requires one, serves its warmed public catalogue when available. Otherwise the buyer sees the payment_terms Buyer Setup step. Choosing terms makes the held account-provisioning work for the billing organization and its current direct children eligible to retry immediately; no seller action is needed. The activation worker also performs an hourly, best-effort recheck for a buyer reparented after that save. A processing backlog can delay that convergence. Acceptance creates buyer access. Native account creation and source mapping are separate operations, and existing mappings keep their state unless an administrator explicitly changes them. After access is approved, decide coverage separately for every source the account may use. On the Page, a person can choose the source account for a source, which records a Mapped decision. A seller’s agent records either decision through V3 with save_seller and its sourceDecision field; see Decide which account serves each source. It can map a source-native account the source lists for the buyer, or confirm Not required when that source’s contract is intentionally unscoped. Use expectedVersion: 0 for the first decision and the currently displayed coverage version for a replacement. A stale version is rejected instead of silently changing the source used for products or buys. For example, a modular source that does not consume a native advertiser account is made eligible explicitly—not inferred from its execution type:
On an embedded sales agent source, Not required still sends an account, because AdCP requires one on every media buy and creative sync. Apostra sends the buyer’s brand and operator. If the sales agent already has an account for that buyer, it books there; otherwise it books the buy under your advertiser routing rules or, when none match, your default advertiser. This is the only decision available on an embedded sales agent whose ad server cannot hold a buyer’s account, such as AdsWizz or SpringServe. The sales agent creates a new account as billed through Apostra, so a buyer you bill directly, or a buyer identified by a complete AccountKey, cannot buy on that source, and a product request that names that buyer’s account by its account_id does not include the source’s products. If you have neither routing rules nor a default advertiser, buys on that source fail until you set one. If a wholesale product request (buying_mode: "wholesale") names an account by its account_id, none of your wholesale sources can be used under it, and the request is not relayed live to your sales agents, the buyer receives an empty product list with a message saying that no products are available to that account, not an error to retry.

Use Apostra default

For an ad-server-backed source, the account picker can offer Use Apostra default instead of mapping a dedicated account: it maps the relationship to your shared default advertiser on that connected ad server, rather than creating or choosing an advertiser for this buyer alone. This option is offered only when every active grant on the relationship settles through agent (consolidated) billing and the source’s configured default advertiser currently reads back healthy. Direct-billed (operator or advertiser) relationships never see it — a direct-billed buyer needs its own advertiser so invoicing and reporting resolve to that buyer, not the shared default. Read get_interchange_default_eligibility before offering the choice; an ineligible response carries a machine-readable reason and never a raw boolean. Choosing it records the mapping through the same decision endpoint as a dedicated account, with bindingMode: "shared_default" and no sourceExternalAccountId — Apostra resolves the native account server-side, so this option never exposes the shared advertiser’s native ID. Apostra keeps the mapping healthy going forward. If the ad server’s configured default advertiser later changes, or the ad server stops reporting it, the mapping is marked stale and execution pauses on it until it is either reconciled against the new default or you choose a dedicated account instead — it never silently keeps executing against the old default or falls back to one automatically. A dedicated mapping is unaffected by a default-advertiser change elsewhere on the source.

Mappings on an Apostra-managed sales agent for Google Ad Manager

A sales agent that Apostra runs for your Google Ad Manager network books every buy on one of its own accounts, not on an advertiser ID. When a buyer’s buy or creative sync reaches that source, Apostra first creates or updates the sales agent’s account for that buyer, keyed by brand domain, operator and sandbox flag, and maps it to the advertiser your mapping names: your default advertiser or the dedicated one you chose. The advertiser must already exist; nothing is created in Google Ad Manager. If the sales agent was holding an account for that buyer as pending provision, the mapping activates it. Product discovery on that source carries no account. This applies to agent-billed accounts. For an operator- or advertiser-billed account, or an account identified by a complete AccountKey, a product request that names the account by its account_id does not include the source’s products, and buys and creative syncs on that source are refused with source_account_not_bound without calling the source. A sales agent for a FreeWheel network receives the mapped FreeWheel advertiser ID as the account. A buy or creative sync that names the buyer only by brand domain and operator, with no account_id, uses the account the buyer has approved for that brand and operator, the same way a request that carries the account_id does. The calling user’s own approval comes first. Without one, the buyer company’s oldest active approval applies to any member of that company, while the seller does not use complete AccountKey mapping. Another company’s approval is never used. That account is then handled as above, so the buy or sync runs on the sales agent account mapped to your advertiser, and the buy’s route records that account for later updates, delivery reads and creative syncs. If the buyer company has no active approval for that brand and operator, or the approved account cannot serve this source (it is not agent-billed, the source has no healthy mapping, or the sales agent will not map it), nothing changes: the request uses the account recorded when the buyer ran sync_accounts, and is otherwise refused with MANAGED_ACCOUNT_LINKAGE_REQUIRED. A sales agent that cannot be reached is a temporary failure, and the request can be retried.

CSV exports and imports

The Page can download:
  • an empty source_account_bindings.csv template for the active mapping mode;
  • current healthy source mappings; and
  • active native accounts with their source namespace, generation, status, and listing version.
In complete AccountKey mode, the versioned mapping columns are:
Every v2 row explicitly declares binding_mode (dedicated or shared_default). Exports protect formula-leading opaque identifiers with a reversible escape; importing the v2 export restores the exact identifier. shared_default rows may be shared by multiple complete AccountKeys and never claim dedicated ownership. A row cannot silently change a matching dedicated mapping into a shared default (or the reverse); use the explicit source-account transition. A prepared v1 revision for an existing relationship remains reviewable and committable after enrolment using its original relationship authority. New feeds in complete-key mode use v2. A legacy relationship-level shared default is never converted or exported as an exact AccountKey; keep managing it through the existing relationship flow. Select Import feed from the Page to open the portable import Task. The Task:
  1. lets an administrator choose the inventory sources covered by the file;
  2. uploads the bytes directly to private, short-lived storage;
  3. validates the exact schema, hashes, row count, relationships, source accounts, and current mapping authority;
  4. shows creates, updates, archives, unchanged rows, and quarantined rows; and
  5. applies the reviewed set in one atomic, version-checked commit.
Sandbox relationships use the same reviewed mapping flow as live relationships. If a storefront has both a sandbox and live relationship with the same operator and brand domains, the Task quarantines that row instead of guessing which one to map. Each successful commit records the administrator, revision, and impact in the seller’s activity audit. Audit delivery is durable and does not make the mapping transaction depend on a second service being available at commit time. Snapshot imports treat the selected sources as complete. A missing row can archive only a mapping that an earlier revision of the same feed created; manual mappings and mappings owned by another feed are never removed. Any quarantined snapshot row blocks the commit. Delta imports require the last committed revision ID and may apply only accepted rows after the administrator reviews the quarantine impact.
This release imports only source_account_bindings.csv. It does not create CRM records, canonical operator-and-brand relationships, grants, or native accounts. Exported native-account choices must already come from an authenticated inventory source. Files are limited to 10 MB and 10,000 data rows.
The MCP Task launcher is:
The upload, preview, and commit capabilities are app-only; they do not appear in the model’s tool catalog.

CRM and commercial policy

A CRM is optional evidence and workflow acceleration. Runtime product discovery, execution, and reporting use the inventory-source mapping for the relevant leg. Credit limits, billing approvals, and permissions remain in their owning typed commercial contracts; the account-mapping export does not copy or interpret arbitrary CRM fields. Native mapping support is runtime-specific. Third-party agent-backed sources and managed Google Ad Manager or FreeWheel sources consume explicit native-account mappings. Sellers can refresh those sources’ authenticated advertiser choices before exporting or importing mappings. Third-party list_accounts results retain the upstream operator, brand, status, and freshness needed for diagnosis, but Apostra does not offer upstream approval or creation actions. A partial, failed, duplicate, or non-advancing refresh keeps the previous complete choices active and never archives an omitted advertiser. Automatic polling includes managed sources and external agents that explicitly advertise list_accounts. Account-capable modular sources can be refreshed on demand; capability-aware periodic modular scheduling remains a follow-on so unsupported compositions are not retried forever. Modular sources can also consume mappings when their active modules declare one shared account namespace across products, media buys, delivery, and account resources. CitrusAd is the first supported composition and maps a supplier team. The Page labels an incomplete composition as unsupported; it may participate only through an explicit, contract-valid Not required decision where account scope is not needed.

Asking the buyer for more information

Some intakes need something from the buyer before you can decide them — a completed W-9, a signed contract, an answer to a credit question. Rather than guessing or rejecting outright, request it: the buyer’s account stays pending_approval, now carrying a message and a link into your own process (a form, a DocuSign envelope, a portal). The buyer’s agent presents the message as untrusted text and offers the link to an authorized human — it never treats the message as instructions, and it never opens the link automatically. Opening the link is not completion. You confirm explicitly once the material actually arrives, and only then does the case return to your queue ready for a decision. If you no longer need what you asked for, withdraw the request instead of declining the whole case — the case stays open and returns to your queue, the same way an expired request re-blocks on you. Ask for the information, confirm that it arrived, or withdraw the request with save_seller({ informationRequest }): action: "request" takes the pending intake’s intakeId and a setup object (message, an optional url, and an expires_at in the future, within 365 days) and returns the launch link for the buyer; action: "confirm" and action: "withdraw" take the requestId that get of the account_relationship shows in the intake’s case.

Billing readiness for direct-billed accounts

Accepting or linking a buyer decides admission — whether they get in. For operator or advertiser billing, that is a separate question from whether you can actually invoice them: your finance system (CRM, ERP, a staff member, or an external workflow) has to explicitly confirm the buyer is billable before their account can place direct-billed media buys. Merely creating a CRM account or a native advertiser is never itself that confirmation. Agent billing (Apostra settlement) never needs this — Apostra handles collection, not you. An operator/advertiser-billed account you’ve accepted or linked but not yet confirmed billable stays pending_approval — no account is created until readiness exists. Your decision is remembered; asserting readiness completes it immediately, activating the account without you having to decide again. Revoking readiness on an account that is already active fails closed: it moves the account to payment_required, immediately blocking new direct-billed activity without touching buys already placed, and it never silently falls back to agent/Apostra billing on your behalf. The review queue’s billingGate field on each pending request shows whether this gate applies and where it stands: not_required (agent billing), pending (never asserted), ready (an active assertion exists), or revoked (one existed and was withdrawn). When the gate is ready or revoked, billingGate.assertionId names the assertion, so you can revoke it even without keeping the original assert response. Assert or revoke billing readiness with save_seller({ readyToInvoice }): action: "assert" takes the relationshipId, the billing party, the billing_entity (repeat the gate’s entity exactly), and the authority the confirmation comes from; action: "revoke" takes the assertionId and a reason. get of the account_relationship lists the active assertions as billingReadiness.