Two directions
Separately, any AdCP buyer (Semicola or not) can call a storefront Semicola hosts. That’s always a
single-seller conversation.
The cross-seller pattern
AdCP addresses one agent at a time. Semicola fans the same task out across your connected sellers and keeps each seller call a normal, one-to-one AdCP call.
A seller never sees a multi-seller request. Each seller’s answer is validated on its own before it’s
combined, and only the seller can change its pricing, allocations or terms: refining a proposal goes
back to the seller that made it.
What a hosted storefront answers
Every storefront Semicola hosts is an AdCP sales agent at/seller/<storefront>/mcp. It answers
get_adcp_capabilities, get_products, list_creative_formats, create_media_buy,
update_media_buy, get_media_buys, get_media_buy_delivery, sync_creatives, list_creatives,
provide_performance_feedback, sync_event_sources, log_event and sync_audiences.
A hosted storefront declares conversion tracking and audience targeting (hashed email and phone;
the audience-sync specialism), so buyers can share measurement data with it. It keeps what it
receives per storefront, buyer account and brand:
sync_event_sourcesregisters a buyer’s source and answers with the storefront’s own id for it (seller_id). It honorsdelete_missingand discovery-only calls.log_eventneeds anevent_id, a type the source accepts and a valid time (more than an hour ahead is refused). It drops a repeatedevent_idfor the same type and source and keeps each other event’s type, time, value and currency, never user identifiers. It takes the storefront’s id for the source, or the buyer’s id when that names one source; otherwise it answersREFERENCE_NOT_FOUND.sync_audiencescounts members by the buyer’sexternal_id. Hashed identifiers are checked for shape and not kept. With no identity graph to match against, every audience staysprocessingand no match count is ever reported.
Versions
AdCP negotiates at release precision (MAJOR.MINOR, like 3.1); patches aren’t negotiated.
The rule: a seller downshifts a pin to the highest release it supports at or below the pin within
the same major, and serves the request.
VERSION_UNSUPPORTED is only for a different major.
Semicola’s AdCP client pins 3.1 and sends
adcp_major_version alongside adcp_version for older
sellers. When Semicola probes a seller, it records the seller’s advertised major versions and its
supported_versions. Hosted storefronts advertise supported_versions: ["3.0", "3.1"] in
get_adcp_capabilities and serve a 3.0 pin by downshifting.
Request shape is checked separately
Negotiating a release and validating a request’s shape are separate. A 3.2 client can’t send the account-identity fields AdCP 3.2 introduced (operator_unit, currency, timezone,
brand.countries) to a storefront that serves only 3.0 and 3.1 and expect them to be dropped:
dropping them could merge two distinct advertiser accounts. So a hosted storefront refuses such a
sync_accounts call with VERSION_UNSUPPORTED before writing anything. field names the first
unsupported value, and details carries:
get_adcp_capabilities advertises 3.2.
If a seller returns VERSION_UNSUPPORTED for a same-major request, that’s a stale seller build; the
seller has to upgrade its AdCP server.
Not available yet
- Signals discovery across sellers (
get_signals); see Signals. - A cross-seller
get_productspage with seller-qualified ids, progressive polling and screening (accept/reject/refine) for external buyers. - Account setup with sellers over AdCP. The buy side doesn’t call
list_accountsorsync_accounts, and a hosted storefront answers them with the caller’s own account without creating or approving one. - Performance feedback (
provide_performance_feedback) from the buy side: we don’t send it. A hosted storefront stores what buyers send (one row peridempotency_key), but nothing reads it yet. - Hosted storefronts answering
get_signals.